Native <input type="file"> wrapped in framework
chrome and paired with a styled ::file-selector-button.
The vendor pseudo lives in its own rule block — listing it alongside
the base selector causes browsers that don't recognise the pseudo to
drop the whole selector list.
Live
File input with styled vendor button
<input type="file" />
@use '@adnap/krysalicss' with ( $feature-list: ('base-reset', 'base-global', 'element-file'));
Standard file pickers (single file or, with the multiple attribute, several at once).
For drag-and-drop upload surfaces, build a custom dropzone with a hidden file input — the framework doesn't ship one.
For image-only or video-only pickers, set accept on the input so the OS picker filters at source.
Variables
Variable
Default
Notes
$selector
'input[type="file"]'
Attribute selector.
$padding-y
$size-extra-small (0.5rem)
Vertical padding on the outer chrome.
$padding-x
$size-small (0.75rem)
Horizontal padding on the outer chrome. Also drives the margin-inline-end on the vendor button.
$border-radius
$global-border-radius (5px)
Outer corner radius.
$border-width
$global-border-width (1px)
Outer stroke. Mixed at $border-mix against currentColor.
$focus-outline-width
$global-focus-outline-width (2px)
Focus-visible ring width.
$focus-outline-style
$global-focus-outline-style (solid)
Focus ring style.
$focus-outline-offset
$global-focus-outline-offset (2px)
Gap between border and ring.
$disabled-opacity
$global-disabled-opacity (0.6)
Applied via plain rule (no shared mixin) so the cursor swap is colocated.
$border-mix
$global-border-mix (50%)
Border tint vs. currentColor.
$button-padding-y
$size-extra-small / 2 (0.25rem)
Vertical padding inside the vendor button.
$button-padding-x
$size-small (0.75rem)
Horizontal padding inside the vendor button.
$button-border-radius
$global-border-radius (5px)
Vendor button corner radius.
Override example
app.scss
@use '@adnap/krysalicss/element/file' with ( $padding-y: 0.5rem, $button-padding-x: 1rem, $button-border-radius: 999px,);
Tokens consumed
Token
Used for
--kc-input-bg / --kc-input-fg
Outer wrapper surface and text colour. Optional: falls back to transparent + currentColor.
--kc-default-bg / --kc-default-fg
Vendor-button surface and text colour. Uses the neutral combination so the button reads as secondary chrome, not a primary CTA.
--kc-fg
Focused border colour and focus-ring fallback.
--kc-focus-ring
Painted on :focus-visible. Falls back to --kc-fg then currentColor.
Accessibility
Anchored on native <input type="file">: keyboard activation (Enter / Space opens the OS picker), screen-reader file-name announcement, and all native validation flow through unchanged.
Always pair with a <label> (visible or aria-labelledby).
The vendor button is part of the native control's shadow DOM — it inherits the input's focus behaviour and AT semantics. Don't try to focus it separately.
Focus ring uses --kc-focus-ring with a fallback chain into --kc-fg / currentColor.
The chrome relies on borders for the control boundary, mixed at 50% against currentColor — clears WCAG 1.4.11 (3:1) on shipped themes. Consumers reducing $border-mix must re-verify.
See also
Text input — pairs with file inputs in upload forms (file name + caption row).