How to Style JetFormBuilder File Upload Fields for a Modern Look

To style a JetFormBuilder file upload field, give the Media Field block a custom class in Advanced > CSS CLASS NAME. Then target its BEM classes with CSS. .jet-form-builder-file-upload__input::file-selector-button turns the browser's plain "Choose file" button into a branded upload box, and .jet-form-builder-file-upload__file styles the image previews. On JetFormBuilder 3.6.6 or newer, check the Media Field style settings in the Style Manager first. Use CSS for anything those controls can't do.
JetFormBuilder is a solid form plugin, but its Media Field shows the browser's default file control unless you change it. Below is a scoped snippet you can paste. It builds a square upload box with a dashed border, hides the "No file chosen" text, adds hover and keyboard focus states, and keeps the field usable on mobile. We also cover the mistakes that usually break this field.
- Try the no-code style settings first
- Which selectors to target
- Step 1: Add a custom class to the Media Field
- Step 2: Choose where the CSS goes
- Step 3: Paste the CSS
- How the CSS works
- Multiple files and thumbnail sizes
- Changing the "Choose file" text
- Want real drag-and-drop?
- Common problems
- Keep the Media Field updated
Try the no-code style settings first
Custom CSS used to be the only option. That changed in recent versions:
- JetFormBuilder 3.6.0 added a new Style Manager.
- JetFormBuilder 3.6.6 added additional style settings for the Media Field in that Style Manager. It also added a notice option to the Media Field.
If you run 3.6.6 or later (the current release is 3.6.7, which needs WordPress 6.1+), select the Media Field block and review its style settings before you write any code. On older setups, the vendor's Media Field documentation describes another route. Install the free JetStyleManager plugin and use the Block Style button in the top-right corner of the editor. It offers Alignment, Border, Color, Margin, Padding and Typography controls.
On 3.6.6 and later, the Media Field's Style Manager settings cover most of this design without code. Under Media Layout, setting Upload Button Position to Left puts the previews beside the button. Upload Button has Width, Height, Padding, Typography, Border and Normal/Hover/Focus colors. File Preview sets the preview size, border and Image Fit, and File Size Message can be shown or hidden. What these settings can't do is hide the browser's "No file chosen" text, so you still need at least that part of the CSS below. If you set Upload Button Position, the Style Manager switches the wrapper to CSS grid, so don't combine it with the snippet's flex layout rules. On older versions, the JetStyleManager controls handle colors, borders, spacing and fonts, and the snippet does the rest.
Which selectors to target
Most of these class names appear in Crocoblock's own Media Field snippet; the rest come from the field's front-end markup. Markup can shift between releases, so confirm them in your browser's DevTools on your version before you rely on them.
| Selector | What it is |
|---|---|
.jet-form-builder-file-upload | The Media Field wrapper that holds the parts below |
.jet-form-builder-file-upload__fields | Column that wraps the native file input |
.jet-form-builder-file-upload__input | The native input[type=file] |
.jet-form-builder-file-upload__content | Area that holds the uploaded file previews |
.jet-form-builder-file-upload__files | The list of previews |
.jet-form-builder-file-upload__file | A single preview (thumbnail or file name) |
.jet-form-builder-file-upload__message | Text JetFormBuilder prints next to the field. Inspect it on your form to see what it holds. |
Step 1: Add a custom class to the Media Field
- Open your form in the JetFormBuilder editor.
- Select the Media Field block.
- Open the Advanced tab in the block settings.
- Type
bmc-uploadinto CSS CLASS NAME. - Click Update.
This step matters. .jet-form-builder__field-wrap is a generic wrapper that JetFormBuilder uses on many field types. A rule like .jet-form-builder__field-wrap { display: flex; } turns every field in every form into a flex row, which breaks text fields, selects and descriptions. Scoping every rule to your own class limits the styles to this one field. It also adds enough specificity to beat default styles without !important.
JetFormBuilder adds your bmc-upload class to the file input itself, not to a wrapper. To check, open the form on the front end, right-click the upload button and choose Inspect. You should see bmc-upload in the input's class list, next to jet-form-builder-file-upload__input. The snippet therefore styles the input with .jet-form-builder-file-upload__input.bmc-upload and reaches the field's wrapper with .jet-form-builder-file-upload:has(.bmc-upload). All current browsers support :has().
Want the look on every Media Field site-wide? Replace .jet-form-builder-file-upload:has(.bmc-upload) with .jet-form-builder-file-upload and .jet-form-builder-file-upload__input.bmc-upload with .jet-form-builder-file-upload__input. Never use the bare field-wrap class.
Step 2: Choose where the CSS goes
- Classic themes: Appearance > Customize > Additional CSS.
- Block themes: the Additional CSS panel in the Site Editor's Styles.
- Child theme: the child theme's
style.css. This survives theme updates. - Elementor sites: the site-wide custom CSS area, if your Elementor setup includes one.
If you use a caching or minification plugin, clear its cache after saving.
Step 3: Paste the CSS
Paste this snippet in your chosen location. Then change the four variables at the top to match your brand colors and the box size you want:
Code
/* JetFormBuilder Media Field: branded upload box
1. Media Field block > Advanced > CSS CLASS NAME: bmc-upload
(JetFormBuilder puts this class on the file input itself)
2. Paste into Additional CSS or your child theme's style.css */
/* Brand colors and box size: change these */
.jet-form-builder-file-upload:has(.bmc-upload) {
--bmc-upload-accent: #2145E6;
--bmc-upload-bg: #F6FAFF;
--bmc-upload-border: #406ACB;
--bmc-upload-size: 100px;
}
/* Layout: upload box on the left, previews on the right */
.jet-form-builder-file-upload:has(.bmc-upload) {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
gap: 10px;
}
/* Column that holds the native file input */
.jet-form-builder-file-upload:has(.bmc-upload) .jet-form-builder-file-upload__fields {
width: var(--bmc-upload-size);
flex-shrink: 0;
display: flex;
flex-direction: column;
order: 0;
}
/* Preview area takes the remaining width */
.jet-form-builder-file-upload:has(.bmc-upload) .jet-form-builder-file-upload__content {
flex-grow: 3;
min-width: 0;
order: 1;
}
/* Keep the size limit and upload errors visible, on their own line below */
.jet-form-builder-file-upload:has(.bmc-upload) .jet-form-builder-file-upload__message,
.jet-form-builder-file-upload:has(.bmc-upload) .jet-form-builder-file-upload__errors {
order: 2;
width: 100%;
}
/* Hide the browser's "No file chosen" / file name text */
.jet-form-builder-file-upload__input.bmc-upload {
width: var(--bmc-upload-size);
max-width: 100%;
color: transparent;
font-size: 0;
}
/* The visible upload box */
.jet-form-builder-file-upload__input.bmc-upload::file-selector-button {
width: var(--bmc-upload-size);
height: var(--bmc-upload-size);
margin: 0;
padding: 8px;
background: var(--bmc-upload-bg);
color: var(--bmc-upload-accent);
border: 1px dashed var(--bmc-upload-border);
border-radius: 10px;
font-size: 14px;
line-height: 1.3;
white-space: normal;
cursor: pointer;
transition: background-color 0.2s, border-color 0.2s;
}
.jet-form-builder-file-upload__input.bmc-upload:hover::file-selector-button {
background: #ffffff;
border-color: var(--bmc-upload-accent);
}
/* Visible focus ring for keyboard users */
.jet-form-builder-file-upload__input.bmc-upload:focus-visible::file-selector-button {
outline: 2px solid var(--bmc-upload-accent);
outline-offset: 2px;
}
/* Uploaded file previews (JetFormBuilder already lays them out in a wrapping row) */
.jet-form-builder-file-upload:has(.bmc-upload) .jet-form-builder-file-upload__file {
border-radius: 10px;
overflow: hidden;
}
/* Small screens: previews drop below the box */
@media (max-width: 480px) {
.jet-form-builder-file-upload:has(.bmc-upload) {
flex-direction: column;
}
}How the CSS works
- Brand variables. All colors and the box size live in four custom properties on the Media Field wrapper that contains your
bmc-uploadinput. Change#2145E6(blue) and#F6FAFF(light background) to your brand colors, and every rule follows. - Scoped flex layout.
:has(.bmc-upload)makes only the Media Field wrapper that contains your input a flex row, so other fields keep their normal layout.gaphandles the spacing between the box and the previews. - Fixed upload column.
__fieldsstays exactly one box wide and never shrinks.__contenttakes the rest of the row. - Message stays visible. A common version of this CSS uses
display: noneon__messageto remove "No file chosen". That doesn't work. The browser draws "No file chosen" inside the native file input, not in that element. Hiding__messagecan also hide information users need, such as the maximum file size text. The snippet moves it to its own line under the box instead. - Browser text hidden.
color: transparentandfont-size: 0on the input hide the "No file chosen" or file name text. The width limit stops it from overflowing the column. The button gets its ownfont-sizeback so its label stays readable. - The upload box.
::file-selector-buttonstyles the browser's button as a square with a dashed border and rounded corners. Button content is centered by default, so no extra alignment rules are needed. - Hover and focus. The box changes on hover and shows an outline when someone reaches it with the Tab key, so it isn't mouse-only.
- Previews. Thumbnails get rounded corners and wrap onto new lines when there are several.
- Mobile. Below 480px wide, the previews stack under the box.
What you should see
Reload the form, clearing any page cache first. The upload field should be a square box with a dashed border showing the browser's own label: "Choose File" in Chrome and Safari, "Browse…" in Firefox. There should be no "No file chosen" text. After you pick an image, its preview appears to the right with rounded corners. Any size or notice text appears below.
To test it fully:
- Upload one file, then several.
- Press Tab until the box has focus and check for the outline.
- Narrow the browser window to check the stacked layout.
- Repeat the checks in Chrome, Firefox and Safari.
Multiple files and thumbnail sizes
When MAXIMUM ALLOWED FILES TO UPLOAD (Field tab) is above 1, the preview list grows with each file. JetFormBuilder's own styles already wrap the previews onto new lines and show each one as a 100 × 100 px tile with object-fit: cover. To change the tile size, override it:
.jet-form-builder-file-upload:has(.bmc-upload) .jet-form-builder-file-upload__file {
width: 80px;
height: 80px;
}
.jet-form-builder-file-upload:has(.bmc-upload) .jet-form-builder-file-upload__file img {
width: 100%;
height: 100%;
object-fit: cover;
}Non-image files such as PDFs show a file name instead of a thumbnail, so test with those too. While you're in the block settings, review the related options:
- MAXIMUM SIZE IN MB (if empty, your server's maximum upload size is used) and ALLOW MIME TYPES (empty means all types).
- FILES LIMIT EXCEEDED and FILE SIZE LIMIT EXCEEDED under Validation > Advanced. Write clear messages so users know what went wrong.
Changing the "Choose file" text
CSS can't change the browser's button label. To show your own text, use the pattern from Crocoblock's snippet: hide the native input, add your own button, and have that button open the file picker. Here is a plain JavaScript version without a jQuery dependency:
document.addEventListener('DOMContentLoaded', function () {
document.querySelectorAll('.jet-form-builder-file-upload__input.bmc-upload').forEach(function (input) {
var button = document.createElement('button');
button.type = 'button';
button.className = 'bmc-upload-button';
button.textContent = 'Upload photos';
input.style.display = 'none';
input.insertAdjacentElement('afterend', button);
button.addEventListener('click', function () {
input.click();
});
});
});Add it as a footer script with a code snippets plugin, or enqueue it from your child theme. Keep these points in mind:
- Once the input is hidden, the
::file-selector-buttonrules no longer show. Move those styles to.jet-form-builder-file-upload__fields .bmc-upload-button. - Forms that load later, such as in a popup, need the script to run after they appear.
- If the field is required, submit the form empty and confirm the error message still shows.
For a fuller walkthrough, see our JetForm Builder media upload button customization tip.
Want real drag-and-drop?
The dashed border only makes the field look like a drop zone. The core Media Field is a button that opens the file picker. For real drag-and-drop, use the separate Drag & Drop File Upload Add-on. It has its own ALLOWED MIME TYPES and CSS CLASS NAME settings. Our guide to JetFormBuilder drag and drop file upload covers it. If you also want upload progress, see the redesigned Media Field with progress bar and compression.
Common problems
- The CSS doesn't apply. Clear page, CSS and CDN caches, and turn off CSS minification while you test. Then check in DevTools whether
bmc-uploadis on the element the snippet expects (see Step 1). If Style Manager output wins, raise specificity with your class instead of adding!important. - Every form field changed layout. An unscoped
.jet-form-builder__field-wrap { display: flex; }rule is still active somewhere. Remove it. - The max file size message disappeared. Look for a leftover
.jet-form-builder-file-upload__message { display: none; }rule and delete it. - It works in one browser but not another.
::file-selector-buttonis supported in current Chrome, Firefox and Safari. Very old browsers only knew the prefixed::-webkit-file-upload-button. Update the browser you test with before you debug further. - The Media Field sits inside a Repeater. Check in DevTools that the custom class and the BEM classes still wrap the field there. Adjust the selector if the structure differs.
- The button still says "Choose File". That's expected with CSS alone. Use the JavaScript pattern above.
Keep the Media Field updated
Styling is cosmetic. Updates are not. Several Media Field security fixes shipped recently, per the JetFormBuilder changelog:
- 3.6.3 made USER ACCESS a required setting.
- 3.6.5.2 escaped Media Field previews to prevent XSS.
- 3.6.6 fixed unauthenticated deletion of Media Library attachments.
- 3.6.6.1 fixed a Media Field access check.
Run the latest version. Set USER ACCESS to the narrowest option that works, and pick "Any user (incl. Guest)" only if anonymous visitors truly need to upload. Uploaded files are stored in wp-content/uploads/jet-form-builder.
With a custom class, the scoped snippet and the browser text hidden, your Media Field becomes a clean upload box that matches your branding without touching other fields. If you'd rather have someone build or extend it for you, post a request on BoostMyCroco.
Frequently Asked Questions
Can I change the "Choose file" text in JetFormBuilder with CSS?
Why doesn't hiding .jet-form-builder-file-upload__message remove "No file chosen"?
Does a dashed border make the JetFormBuilder Media Field drag-and-drop?
Can I style the JetFormBuilder Media Field without code?
Why did all my JetFormBuilder fields change layout after adding upload CSS?
Sources
- Media Field Overview 一 JetFormBuilder (jetformbuilder.com)
- JetFormbuilder media field text after upload · GitHub (gist.github.com)
- Drag & Drop File Upload Add-on — JetFormBuilder (jetformbuilder.com)
- JetFormBuilder — Dynamic Blocks Form Builder (wordpress.org)
- JetEngine: Forms: Add functionality to style the File Upload button in the Form Builder · Issue #3261 · Crocoblock/suggestions · GitHub (github.com)
- How to style the default media field for JetFormBuilder - Quora (quora.com)
- JetFormBuilder media field, enhanced choose file - Gist - GitHub (gist.github.com)


