28 CSS Input Fields15 / 28
File Drop Zone
Drag-and-drop file input with a custom dashed boundary. Native <input type="file"> underneath, the visible filename appearing via `:has()` — accessible, keyboard-friendly, and minimal.
Published
The code
<label class="if-15">
<input type="file" name="upload" accept="image/*,.pdf" />
<span class="if-15-icon" aria-hidden="true">
<svg
viewBox="0 0 24 24"
width="22"
height="22"
fill="none"
stroke="currentColor"
stroke-width="1.6"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
<polyline points="17 8 12 3 7 8" />
<line x1="12" y1="3" x2="12" y2="15" />
</svg>
</span>
<span class="if-15-text">
<strong>Click to upload</strong> or drag & drop
<span class="if-15-types">PNG, JPG, or PDF · max 10 MB</span>
</span>
</label><label class="if-15">
<input type="file" name="upload" accept="image/*,.pdf" />
<span class="if-15-icon" aria-hidden="true">
<svg
viewBox="0 0 24 24"
width="22"
height="22"
fill="none"
stroke="currentColor"
stroke-width="1.6"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
<polyline points="17 8 12 3 7 8" />
<line x1="12" y1="3" x2="12" y2="15" />
</svg>
</span>
<span class="if-15-text">
<strong>Click to upload</strong> or drag & drop
<span class="if-15-types">PNG, JPG, or PDF · max 10 MB</span>
</span>
</label>.if-15 {
position: relative;
display: block;
width: 100%;
max-width: 320px;
cursor: pointer;
border: 1.5px dashed rgba(99, 102, 241, 0.5);
border-radius: 12px;
padding: 22px 18px;
background: rgba(99, 102, 241, 0.05);
text-align: center;
transition: border-color 0.2s, background 0.2s, transform 0.15s;
}
.if-15:hover {
border-color: #818cf8;
background: rgba(99, 102, 241, 0.1);
}
.if-15:focus-within {
border-color: #818cf8;
background: rgba(99, 102, 241, 0.12);
box-shadow: 0 0 0 3px rgba(129, 140, 248, 0.18);
}
.if-15 input[type="file"] {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
}
.if-15-icon {
display: grid;
place-items: center;
width: 40px;
height: 40px;
margin: 0 auto 8px;
border-radius: 10px;
background: rgba(99, 102, 241, 0.18);
color: #a5b4fc;
}
.if-15-text {
display: block;
font-size: 13px;
color: #c8c0ff;
}
.if-15-text strong {
color: #a5b4fc;
font-weight: 600;
}
.if-15-types {
display: block;
font-size: 11px;
color: #b8b6d4;
margin-top: 4px;
}.if-15 {
position: relative;
display: block;
width: 100%;
max-width: 320px;
cursor: pointer;
border: 1.5px dashed rgba(99, 102, 241, 0.5);
border-radius: 12px;
padding: 22px 18px;
background: rgba(99, 102, 241, 0.05);
text-align: center;
transition: border-color 0.2s, background 0.2s, transform 0.15s;
}
.if-15:hover {
border-color: #818cf8;
background: rgba(99, 102, 241, 0.1);
}
.if-15:focus-within {
border-color: #818cf8;
background: rgba(99, 102, 241, 0.12);
box-shadow: 0 0 0 3px rgba(129, 140, 248, 0.18);
}
.if-15 input[type="file"] {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
}
.if-15-icon {
display: grid;
place-items: center;
width: 40px;
height: 40px;
margin: 0 auto 8px;
border-radius: 10px;
background: rgba(99, 102, 241, 0.18);
color: #a5b4fc;
}
.if-15-text {
display: block;
font-size: 13px;
color: #c8c0ff;
}
.if-15-text strong {
color: #a5b4fc;
font-weight: 600;
}
.if-15-types {
display: block;
font-size: 11px;
color: #b8b6d4;
margin-top: 4px;
}Here's a working CSS Input Field from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: File Drop Zone
Source: https://codefronts.com/components/css-input-fields/file-drop-zone/
Drag-and-drop file input with a custom dashed boundary. Native <input type="file"> underneath, the visible filename appearing via `:has()` — accessible, keyboard-friendly, and minimal.
## HTML
```html
<label class="if-15">
<input type="file" name="upload" accept="image/*,.pdf" />
<span class="if-15-icon" aria-hidden="true">
<svg
viewBox="0 0 24 24"
width="22"
height="22"
fill="none"
stroke="currentColor"
stroke-width="1.6"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
<polyline points="17 8 12 3 7 8" />
<line x1="12" y1="3" x2="12" y2="15" />
</svg>
</span>
<span class="if-15-text">
<strong>Click to upload</strong> or drag & drop
<span class="if-15-types">PNG, JPG, or PDF · max 10 MB</span>
</span>
</label>
```
## CSS
```css
.if-15 {
position: relative;
display: block;
width: 100%;
max-width: 320px;
cursor: pointer;
border: 1.5px dashed rgba(99, 102, 241, 0.5);
border-radius: 12px;
padding: 22px 18px;
background: rgba(99, 102, 241, 0.05);
text-align: center;
transition: border-color 0.2s, background 0.2s, transform 0.15s;
}
.if-15:hover {
border-color: #818cf8;
background: rgba(99, 102, 241, 0.1);
}
.if-15:focus-within {
border-color: #818cf8;
background: rgba(99, 102, 241, 0.12);
box-shadow: 0 0 0 3px rgba(129, 140, 248, 0.18);
}
.if-15 input[type="file"] {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
}
.if-15-icon {
display: grid;
place-items: center;
width: 40px;
height: 40px;
margin: 0 auto 8px;
border-radius: 10px;
background: rgba(99, 102, 241, 0.18);
color: #a5b4fc;
}
.if-15-text {
display: block;
font-size: 13px;
color: #c8c0ff;
}
.if-15-text strong {
color: #a5b4fc;
font-weight: 600;
}
.if-15-types {
display: block;
font-size: 11px;
color: #b8b6d4;
margin-top: 4px;
}
```Here's a working CSS Input Field from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: File Drop Zone
Source: https://codefronts.com/components/css-input-fields/file-drop-zone/
Drag-and-drop file input with a custom dashed boundary. Native <input type="file"> underneath, the visible filename appearing via `:has()` — accessible, keyboard-friendly, and minimal.
## HTML
```html
<label class="if-15">
<input type="file" name="upload" accept="image/*,.pdf" />
<span class="if-15-icon" aria-hidden="true">
<svg
viewBox="0 0 24 24"
width="22"
height="22"
fill="none"
stroke="currentColor"
stroke-width="1.6"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
<polyline points="17 8 12 3 7 8" />
<line x1="12" y1="3" x2="12" y2="15" />
</svg>
</span>
<span class="if-15-text">
<strong>Click to upload</strong> or drag & drop
<span class="if-15-types">PNG, JPG, or PDF · max 10 MB</span>
</span>
</label>
```
## CSS
```css
.if-15 {
position: relative;
display: block;
width: 100%;
max-width: 320px;
cursor: pointer;
border: 1.5px dashed rgba(99, 102, 241, 0.5);
border-radius: 12px;
padding: 22px 18px;
background: rgba(99, 102, 241, 0.05);
text-align: center;
transition: border-color 0.2s, background 0.2s, transform 0.15s;
}
.if-15:hover {
border-color: #818cf8;
background: rgba(99, 102, 241, 0.1);
}
.if-15:focus-within {
border-color: #818cf8;
background: rgba(99, 102, 241, 0.12);
box-shadow: 0 0 0 3px rgba(129, 140, 248, 0.18);
}
.if-15 input[type="file"] {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
}
.if-15-icon {
display: grid;
place-items: center;
width: 40px;
height: 40px;
margin: 0 auto 8px;
border-radius: 10px;
background: rgba(99, 102, 241, 0.18);
color: #a5b4fc;
}
.if-15-text {
display: block;
font-size: 13px;
color: #c8c0ff;
}
.if-15-text strong {
color: #a5b4fc;
font-weight: 600;
}
.if-15-types {
display: block;
font-size: 11px;
color: #b8b6d4;
margin-top: 4px;
}
```How this works
The wrapper label uses a dashed border and centered icon plus text; a real file input is absolutely positioned with inset:0 and opacity:0, so it covers the entire drop zone while remaining invisible. Because the input is the top layer, native drag-and-drop, click-to-open, and keyboard focus all work without JavaScript — the browser fires the file picker or accepts the dropped file directly on the input.
Visual states are pure CSS: :hover and :focus-within tint the border and background, and accept filters the picker to images and PDF. This is a zero-KB replacement for Dropzone.js (about 43KB) and react-dropzone (about 18KB) for the common single-file upload case.
Make it yours
- Change
acceptto restrict file types — for exampleaccept=".csv,.xlsx"for spreadsheet uploads. - Add the
multipleattribute on the input to accept several files in one drop. - Tune the dashed border colour, radius, and padding to match your brand accent.
- Swap the SVG glyph or copy inside the label — the invisible input still catches every event.
Gotchas — read before shipping
- The overlay input must have
opacity:0, notdisplay:none, or drag events and the picker will stop firing. - Pure CSS cannot show the chosen filename — wire a tiny
changelistener if you need to echo it back to the user. - The 10 MB limit shown in the label is copy only; enforce it server-side and with a JS size check on
change.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 60+ | 12+ | 60+ | 60+ |
Native file input with drag-and-drop works everywhere; no library, no polyfill.