File

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')
);
Playground

Markup

markup
<input type="file" />

When to use

  • 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

VariableDefaultNotes
$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

TokenUsed for
--kc-input-bg / --kc-input-fgOuter wrapper surface and text colour. Optional: falls back to transparent + currentColor.
--kc-default-bg / --kc-default-fgVendor-button surface and text colour. Uses the neutral combination so the button reads as secondary chrome, not a primary CTA.
--kc-fgFocused border colour and focus-ring fallback.
--kc-focus-ringPainted 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).
  • Forms overview — full form-control roster.
  • Field wrapper — pairs every form control with label + help text.