Icon Inputs
.group-input-icon is a positioning wrapper that places content inside an input through two named slots: .input-slot-start on the left and .input-slot-end on the right. The input's padding adjusts automatically via CSS custom properties so the content inside the field never overlaps the slot content.
Sizing the Slots
The input's padding is not measured automatically — it is controlled by two CSS custom properties that you set on .group-input-icon. Each defaults to 2.5rem, which fits a single icon or a single small button. As soon as a slot holds more than one child, or a wider element like a labelled button, you must set the corresponding variable yourself so the input's text never runs under the slot.
| Property | Applies to | What it controls |
|---|---|---|
--input-slot-start | .input-slot-start | Left padding added to .form-input |
--input-slot-width | .input-slot-start | Width of the start slot box itself (defaults to 2.5rem if unset) |
--input-slot-end | .input-slot-end | Right padding added to .form-input |
There is no --input-slot-end-width — the end slot sizes itself to its content and is right-aligned with 0.5rem from the edge, so only the input's padding needs to be told how much room to leave.
Reference values
Use these as a starting point, then adjust to your actual button/icon sizes and label lengths.
| Slot content | Start variable | End variable |
|---|---|---|
| Single icon (16–18px) | 2.5rem (default) | 2.5rem (default) |
| Single icon-only button | 2.75rem | 2.75rem |
| Single button with text label | width of text + 1.5rem | width of text + 1.5rem |
Badge / unit label (e.g. USD) | — | width of label + 1.25rem |
Two icon-only buttons (is-small, default gap) | — | 4.5rem |
| Two buttons, one with a text label (e.g. ✕ + "Go") | — | 6rem |
| Three or more actions | — | measure and set explicitly; consider moving actions outside the input |
If a value doesn't feel exact for your button size or font, nudge it up or down in 0.25rem steps until the input text clears the slot with a small margin — there's no need to match the table exactly.
Start Icon
The start slot is ideal for context icons: search, email, user, location, and similar. Its content is pointer-events–none by default so it does not intercept clicks on the input.
<div class="group-input-icon">
<span class="input-slot-start">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="M21 21l-4.3-4.3" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<circle cx="11" cy="11" r="7" stroke="currentColor" stroke-width="2"/>
</svg>
</span>
<input class="form-input" type="search" placeholder="Search products">
</div>
Text Symbol in Start Slot
You can use plain text or symbols instead of SVG — useful for currency, unit, or at-sign patterns where a small SVG would be overkill.
<div class="group-input-icon">
<span class="input-slot-start">@</span>
<input class="form-input" type="text" placeholder="username">
</div>
End Icon Button
The end slot is commonly used for action buttons: password toggle, clear, copy, submit. Children that are button, a, [role="button"], or .is-clickable automatically receive pointer-events: auto so they are interactive.
Always provide an aria-label on icon-only buttons inside the end slot.
<div class="group-input-icon">
<input class="form-input" type="password" placeholder="Password">
<span class="input-slot-end">
<button class="button is-light-outline is-small is-icon" type="button" aria-label="Show password">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="M2 12s3.5-6 10-6s10 6 10 6s-3.5 6-10 6S2 12 2 12z" stroke="currentColor" stroke-width="2"/>
<circle cx="12" cy="12" r="3" stroke="currentColor" stroke-width="2"/>
</svg>
</button>
</span>
</div>
End Slot with Badge
Non-interactive content like a badge or unit label can also sit in the end slot.
<div class="group-input-icon">
<input class="form-input" type="number" placeholder="Amount">
<span class="input-slot-end">
<span class="badge is-light">USD</span>
</span>
</div>
Start and End Together
Both slots can be used simultaneously. Common for amount inputs, coupon fields, and search bars with a clear button.
<div class="group-input-icon">
<span class="input-slot-start">$</span>
<input class="form-input" type="number" placeholder="0.00">
<span class="input-slot-end">
<span class="badge is-light">USD</span>
</span>
</div>
Multiple Actions in End Slot
The end slot accepts multiple children. They render inline with a small gap between them. Common for search inputs with a clear and a submit button.
<div class="group-input-icon" style="--input-slot-end: 6rem">
<span class="input-slot-start">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="M21 21l-4.3-4.3" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<circle cx="11" cy="11" r="7" stroke="currentColor" stroke-width="2"/>
</svg>
</span>
<input class="form-input" type="search" placeholder="Search">
<span class="input-slot-end">
<button class="button is-light-outline is-small" type="reset" aria-label="Clear">✕</button>
<button class="button is-primary is-small" type="submit">Go</button>
</span>
</div>
Note the --input-slot-end: 6rem set inline on the wrapper above — see Sizing the Slots for why this is required whenever the end slot holds more than one action.