From 1adc03592b2dd5fbb4352f8f2b21b1975140a124 Mon Sep 17 00:00:00 2001 From: Dag Frode Solberg Date: Fri, 8 May 2026 12:29:22 +0200 Subject: [PATCH 1/2] Legg til hitbox utils --- indeks-docs/docs/utility-klasser/hitbox.mdx | 142 ++++++++++++++++++++ indeks-docs/sidebars.ts | 2 +- indeks-utils/css/hitbox.css | 98 ++++++++++++++ indeks-utils/css/index.css | 1 + 4 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 indeks-docs/docs/utility-klasser/hitbox.mdx create mode 100644 indeks-utils/css/hitbox.css diff --git a/indeks-docs/docs/utility-klasser/hitbox.mdx b/indeks-docs/docs/utility-klasser/hitbox.mdx new file mode 100644 index 0000000..b04123d --- /dev/null +++ b/indeks-docs/docs/utility-klasser/hitbox.mdx @@ -0,0 +1,142 @@ +# Hitbox + +Hitbox utvider det klikkbare arealet til et element uten å påvirke layout. Nyttig for å oppfylle +WCAG 2.5.5 (44×44 px minimum touch target) på små ikonknapper, lenker og andre klikkbare elementer +der visuell størrelse er satt av designet. + +Teknikken bruker `::before`-pseudo-elementet til å utvide det interaktive arealet. Elementet selv +beholder sin visuelle størrelse og layout-påvirkning. Inspirert av [bazza.dev/craft/2026/hit-area](https://bazza.dev/craft/2026/hit-area). + +## Klasser + +`.ix-hitbox` er basisklassen og må alltid brukes. Legg til én eller flere størrelsesklasser for å +kontrollere utvidelsen i de retningene du trenger. + +### Basisklasse + +| CSS-klasse | Beskrivelse | +| ------------ | ------------------------------------------------------------------------------------ | +| `.ix-hitbox` | Setter `position: relative` og aktiverer `::before`-pseudo-elementet. Alltid påkrevd. | + +### Uniform utvidelse (alle sider) + +| CSS-klasse | Utvidelse (alle sider) | +| ----------------- | --------------------------- | +| `.ix-hitbox-2xs` | `var(--ix-spacing-2xs)` | +| `.ix-hitbox-xs` | `var(--ix-spacing-xs)` | +| `.ix-hitbox-sm` | `var(--ix-spacing-sm)` | +| `.ix-hitbox-md` | `var(--ix-spacing-md)` | +| `.ix-hitbox-lg` | `var(--ix-spacing-lg)` | +| `.ix-hitbox-xl` | `var(--ix-spacing-xl)` | +| `.ix-hitbox-2xl` | `var(--ix-spacing-2xl)` | + +### X-akse (venstre + høyre) + +| CSS-klasse | Utvidelse (venstre + høyre) | +| ------------------- | --------------------------- | +| `.ix-hitbox-x-2xs` | `var(--ix-spacing-2xs)` | +| `.ix-hitbox-x-xs` | `var(--ix-spacing-xs)` | +| `.ix-hitbox-x-sm` | `var(--ix-spacing-sm)` | +| `.ix-hitbox-x-md` | `var(--ix-spacing-md)` | +| `.ix-hitbox-x-lg` | `var(--ix-spacing-lg)` | +| `.ix-hitbox-x-xl` | `var(--ix-spacing-xl)` | +| `.ix-hitbox-x-2xl` | `var(--ix-spacing-2xl)` | + +### Y-akse (topp + bunn) + +| CSS-klasse | Utvidelse (topp + bunn) | +| ------------------- | --------------------------- | +| `.ix-hitbox-y-2xs` | `var(--ix-spacing-2xs)` | +| `.ix-hitbox-y-xs` | `var(--ix-spacing-xs)` | +| `.ix-hitbox-y-sm` | `var(--ix-spacing-sm)` | +| `.ix-hitbox-y-md` | `var(--ix-spacing-md)` | +| `.ix-hitbox-y-lg` | `var(--ix-spacing-lg)` | +| `.ix-hitbox-y-xl` | `var(--ix-spacing-xl)` | +| `.ix-hitbox-y-2xl` | `var(--ix-spacing-2xl)` | + +### Individuelle sider + +| CSS-klasse | Utvidelse | +| ------------------- | ---------- | +| `.ix-hitbox-t-2xs` | Topp: `var(--ix-spacing-2xs)` | +| `.ix-hitbox-t-xs` | Topp: `var(--ix-spacing-xs)` | +| `.ix-hitbox-t-sm` | Topp: `var(--ix-spacing-sm)` | +| `.ix-hitbox-t-md` | Topp: `var(--ix-spacing-md)` | +| `.ix-hitbox-t-lg` | Topp: `var(--ix-spacing-lg)` | +| `.ix-hitbox-t-xl` | Topp: `var(--ix-spacing-xl)` | +| `.ix-hitbox-t-2xl` | Topp: `var(--ix-spacing-2xl)` | +| `.ix-hitbox-r-2xs` | Høyre: `var(--ix-spacing-2xs)` | +| `.ix-hitbox-r-xs` | Høyre: `var(--ix-spacing-xs)` | +| `.ix-hitbox-r-sm` | Høyre: `var(--ix-spacing-sm)` | +| `.ix-hitbox-r-md` | Høyre: `var(--ix-spacing-md)` | +| `.ix-hitbox-r-lg` | Høyre: `var(--ix-spacing-lg)` | +| `.ix-hitbox-r-xl` | Høyre: `var(--ix-spacing-xl)` | +| `.ix-hitbox-r-2xl` | Høyre: `var(--ix-spacing-2xl)` | +| `.ix-hitbox-b-2xs` | Bunn: `var(--ix-spacing-2xs)` | +| `.ix-hitbox-b-xs` | Bunn: `var(--ix-spacing-xs)` | +| `.ix-hitbox-b-sm` | Bunn: `var(--ix-spacing-sm)` | +| `.ix-hitbox-b-md` | Bunn: `var(--ix-spacing-md)` | +| `.ix-hitbox-b-lg` | Bunn: `var(--ix-spacing-lg)` | +| `.ix-hitbox-b-xl` | Bunn: `var(--ix-spacing-xl)` | +| `.ix-hitbox-b-2xl` | Bunn: `var(--ix-spacing-2xl)` | +| `.ix-hitbox-l-2xs` | Venstre: `var(--ix-spacing-2xs)` | +| `.ix-hitbox-l-xs` | Venstre: `var(--ix-spacing-xs)` | +| `.ix-hitbox-l-sm` | Venstre: `var(--ix-spacing-sm)` | +| `.ix-hitbox-l-md` | Venstre: `var(--ix-spacing-md)` | +| `.ix-hitbox-l-lg` | Venstre: `var(--ix-spacing-lg)` | +| `.ix-hitbox-l-xl` | Venstre: `var(--ix-spacing-xl)` | +| `.ix-hitbox-l-2xl` | Venstre: `var(--ix-spacing-2xl)` | + +## CSS-egenskaper + +Størrelsesklassene setter interne CSS-variabler som basisklassen bruker. Du kan overstyre disse +direkte hvis du trenger en egendefinert størrelse: + +| CSS-variabel | Kontrollerer | Standard | +| --------------- | ------------- | -------- | +| `--ii-hit-t` | Topp-utvidelse | `0px` | +| `--ii-hit-r` | Høyre-utvidelse | `0px` | +| `--ii-hit-b` | Bunn-utvidelse | `0px` | +| `--ii-hit-l` | Venstre-utvidelse | `0px` | + +```css +/* Egendefinert hitbox-størrelse */ +.min-knapp { + --ii-hit-t: 12px; + --ii-hit-b: 12px; +} +``` + +## Debug + +To klasser gjør det enklere å visualisere hitbox-arealet under utvikling. Fjern dem før produksjon. + +| CSS-klasse | Beskrivelse | +| ------------------------ | ----------------------------------------------------------------------------------------------------- | +| `.ix-hitbox-debug` | Viser alltid hitbox-arealet med blå ramme og bakgrunn. Bytter til grønt ved hover. | +| `.ix-hitbox-debug-hover` | Viser bare hitbox-arealet ved hover, med grønn ramme og bakgrunn. Brukes for å bekrefte at arealet er riktig uten å forstyrre det visuelle designet. | + +Fargesignalene er de samme som i originalen fra bazza.dev: blå = «her er hitbox-arealet», grønt = «hover aktiv, treffer du innenfor?». + +### Eksempel + +```jsx live +
+ + +
+``` + +## Tilgjengelighet + +Hitbox bruker `::before`-pseudo-elementet til å utvide det klikkbare arealet. Pseudo-elementet +legges over nærliggende innhold hvis elementet ikke er plassert i en beholder med `overflow: hidden` +eller `clip-path`. Sørg for at hitbox-arealet ikke overlapper andre klikkbare elementer ved å gi +tilstrekkelig mellomrom mellom dem. + +Klassen setter automatisk `position: relative` på elementet via `.ix-hitbox`. Ikke fjern dette — +uten `position: relative` vil `::before` posisjonere seg mot nærmeste posisjonerte forfar. diff --git a/indeks-docs/sidebars.ts b/indeks-docs/sidebars.ts index 7323905..4588ce1 100644 --- a/indeks-docs/sidebars.ts +++ b/indeks-docs/sidebars.ts @@ -71,7 +71,7 @@ const sidebars: SidebarsConfig = { type: 'category', label: 'Utility-klasser', collapsed: true, - items: ['utility-klasser/oversikt', 'utility-klasser/native'], + items: ['utility-klasser/oversikt', 'utility-klasser/native', 'utility-klasser/hitbox'], }, { type: 'category', diff --git a/indeks-utils/css/hitbox.css b/indeks-utils/css/hitbox.css new file mode 100644 index 0000000..5744533 --- /dev/null +++ b/indeks-utils/css/hitbox.css @@ -0,0 +1,98 @@ +/* Inspirert av bazza.dev/craft/2026/hit-area — tilpasset Indeks med eget navn og spacing-tokens */ + +.ix-hitbox { + position: relative; + --ii-hit-t: 0px; + --ii-hit-r: 0px; + --ii-hit-b: 0px; + --ii-hit-l: 0px; +} + +.ix-hitbox::before { + content: ''; + position: absolute; + top: calc(-1 * var(--ii-hit-t)); + right: calc(-1 * var(--ii-hit-r)); + bottom: calc(-1 * var(--ii-hit-b)); + left: calc(-1 * var(--ii-hit-l)); +} + +/* Uniform */ +.ix-hitbox-2xs { --ii-hit-t: var(--ix-spacing-2xs); --ii-hit-r: var(--ix-spacing-2xs); --ii-hit-b: var(--ix-spacing-2xs); --ii-hit-l: var(--ix-spacing-2xs); } +.ix-hitbox-xs { --ii-hit-t: var(--ix-spacing-xs); --ii-hit-r: var(--ix-spacing-xs); --ii-hit-b: var(--ix-spacing-xs); --ii-hit-l: var(--ix-spacing-xs); } +.ix-hitbox-sm { --ii-hit-t: var(--ix-spacing-sm); --ii-hit-r: var(--ix-spacing-sm); --ii-hit-b: var(--ix-spacing-sm); --ii-hit-l: var(--ix-spacing-sm); } +.ix-hitbox-md { --ii-hit-t: var(--ix-spacing-md); --ii-hit-r: var(--ix-spacing-md); --ii-hit-b: var(--ix-spacing-md); --ii-hit-l: var(--ix-spacing-md); } +.ix-hitbox-lg { --ii-hit-t: var(--ix-spacing-lg); --ii-hit-r: var(--ix-spacing-lg); --ii-hit-b: var(--ix-spacing-lg); --ii-hit-l: var(--ix-spacing-lg); } +.ix-hitbox-xl { --ii-hit-t: var(--ix-spacing-xl); --ii-hit-r: var(--ix-spacing-xl); --ii-hit-b: var(--ix-spacing-xl); --ii-hit-l: var(--ix-spacing-xl); } +.ix-hitbox-2xl { --ii-hit-t: var(--ix-spacing-2xl); --ii-hit-r: var(--ix-spacing-2xl); --ii-hit-b: var(--ix-spacing-2xl); --ii-hit-l: var(--ix-spacing-2xl); } + +/* X-akse (venstre + høyre) */ +.ix-hitbox-x-2xs { --ii-hit-r: var(--ix-spacing-2xs); --ii-hit-l: var(--ix-spacing-2xs); } +.ix-hitbox-x-xs { --ii-hit-r: var(--ix-spacing-xs); --ii-hit-l: var(--ix-spacing-xs); } +.ix-hitbox-x-sm { --ii-hit-r: var(--ix-spacing-sm); --ii-hit-l: var(--ix-spacing-sm); } +.ix-hitbox-x-md { --ii-hit-r: var(--ix-spacing-md); --ii-hit-l: var(--ix-spacing-md); } +.ix-hitbox-x-lg { --ii-hit-r: var(--ix-spacing-lg); --ii-hit-l: var(--ix-spacing-lg); } +.ix-hitbox-x-xl { --ii-hit-r: var(--ix-spacing-xl); --ii-hit-l: var(--ix-spacing-xl); } +.ix-hitbox-x-2xl { --ii-hit-r: var(--ix-spacing-2xl); --ii-hit-l: var(--ix-spacing-2xl); } + +/* Y-akse (topp + bunn) */ +.ix-hitbox-y-2xs { --ii-hit-t: var(--ix-spacing-2xs); --ii-hit-b: var(--ix-spacing-2xs); } +.ix-hitbox-y-xs { --ii-hit-t: var(--ix-spacing-xs); --ii-hit-b: var(--ix-spacing-xs); } +.ix-hitbox-y-sm { --ii-hit-t: var(--ix-spacing-sm); --ii-hit-b: var(--ix-spacing-sm); } +.ix-hitbox-y-md { --ii-hit-t: var(--ix-spacing-md); --ii-hit-b: var(--ix-spacing-md); } +.ix-hitbox-y-lg { --ii-hit-t: var(--ix-spacing-lg); --ii-hit-b: var(--ix-spacing-lg); } +.ix-hitbox-y-xl { --ii-hit-t: var(--ix-spacing-xl); --ii-hit-b: var(--ix-spacing-xl); } +.ix-hitbox-y-2xl { --ii-hit-t: var(--ix-spacing-2xl); --ii-hit-b: var(--ix-spacing-2xl); } + +/* Topp */ +.ix-hitbox-t-2xs { --ii-hit-t: var(--ix-spacing-2xs); } +.ix-hitbox-t-xs { --ii-hit-t: var(--ix-spacing-xs); } +.ix-hitbox-t-sm { --ii-hit-t: var(--ix-spacing-sm); } +.ix-hitbox-t-md { --ii-hit-t: var(--ix-spacing-md); } +.ix-hitbox-t-lg { --ii-hit-t: var(--ix-spacing-lg); } +.ix-hitbox-t-xl { --ii-hit-t: var(--ix-spacing-xl); } +.ix-hitbox-t-2xl { --ii-hit-t: var(--ix-spacing-2xl); } + +/* Høyre */ +.ix-hitbox-r-2xs { --ii-hit-r: var(--ix-spacing-2xs); } +.ix-hitbox-r-xs { --ii-hit-r: var(--ix-spacing-xs); } +.ix-hitbox-r-sm { --ii-hit-r: var(--ix-spacing-sm); } +.ix-hitbox-r-md { --ii-hit-r: var(--ix-spacing-md); } +.ix-hitbox-r-lg { --ii-hit-r: var(--ix-spacing-lg); } +.ix-hitbox-r-xl { --ii-hit-r: var(--ix-spacing-xl); } +.ix-hitbox-r-2xl { --ii-hit-r: var(--ix-spacing-2xl); } + +/* Bunn */ +.ix-hitbox-b-2xs { --ii-hit-b: var(--ix-spacing-2xs); } +.ix-hitbox-b-xs { --ii-hit-b: var(--ix-spacing-xs); } +.ix-hitbox-b-sm { --ii-hit-b: var(--ix-spacing-sm); } +.ix-hitbox-b-md { --ii-hit-b: var(--ix-spacing-md); } +.ix-hitbox-b-lg { --ii-hit-b: var(--ix-spacing-lg); } +.ix-hitbox-b-xl { --ii-hit-b: var(--ix-spacing-xl); } +.ix-hitbox-b-2xl { --ii-hit-b: var(--ix-spacing-2xl); } + +/* Venstre */ +.ix-hitbox-l-2xs { --ii-hit-l: var(--ix-spacing-2xs); } +.ix-hitbox-l-xs { --ii-hit-l: var(--ix-spacing-xs); } +.ix-hitbox-l-sm { --ii-hit-l: var(--ix-spacing-sm); } +.ix-hitbox-l-md { --ii-hit-l: var(--ix-spacing-md); } +.ix-hitbox-l-lg { --ii-hit-l: var(--ix-spacing-lg); } +.ix-hitbox-l-xl { --ii-hit-l: var(--ix-spacing-xl); } +.ix-hitbox-l-2xl { --ii-hit-l: var(--ix-spacing-2xl); } + +/* Debug — viser hitbox-arealet alltid (blå) og bytter til grønt ved hover */ +.ix-hitbox-debug::before { + outline: 2px dashed rgba(0, 100, 255, 0.7); + background: rgba(0, 100, 255, 0.1); +} + +.ix-hitbox-debug:hover::before { + outline: 2px dashed rgba(0, 200, 80, 0.7); + background: rgba(0, 200, 80, 0.2); +} + +/* Debug hover — viser kun hitbox-arealet ved hover (grønt) */ +.ix-hitbox-debug-hover:hover::before { + outline: 2px dashed rgba(0, 200, 80, 0.7); + background: rgba(0, 200, 80, 0.2); +} diff --git a/indeks-utils/css/index.css b/indeks-utils/css/index.css index 24949f7..2c77733 100644 --- a/indeks-utils/css/index.css +++ b/indeks-utils/css/index.css @@ -11,5 +11,6 @@ @import './spacing.css'; @import './state-colors.css'; @import './transition.css'; +@import './hitbox.css'; @import './interaction.css'; @import './typography.css'; From 1d86a7231c8c071ff312055be1e3121ddadb7186 Mon Sep 17 00:00:00 2001 From: Dag Frode Solberg Date: Wed, 13 May 2026 08:55:02 +0200 Subject: [PATCH 2/2] Forbedre hitbox demo --- indeks-docs/docs/utility-klasser/hitbox.mdx | 64 +++++++++++++++++++++ indeks-docs/src/css/custom.css | 19 ++++++ 2 files changed, 83 insertions(+) diff --git a/indeks-docs/docs/utility-klasser/hitbox.mdx b/indeks-docs/docs/utility-klasser/hitbox.mdx index b04123d..837c09f 100644 --- a/indeks-docs/docs/utility-klasser/hitbox.mdx +++ b/indeks-docs/docs/utility-klasser/hitbox.mdx @@ -107,6 +107,70 @@ direkte hvis du trenger en egendefinert størrelse: } ``` +## Eksempler + +### Uniform utvidelse + +Legg merke til at den visuelle størrelsen er uendret — bare det klikkbare arealet vokser. + +```jsx live +
+
2xs
+
xs
+
sm
+
md
+
lg
+
+``` + +### X-akse + +Nyttig for lenker og knapper i navigasjon der du vil utvide klikkbart areal horisontalt uten å påvirke linjehøyden. + +```jsx live +
+
x-sm
+
x-md
+
x-lg
+
+``` + +### Y-akse + +Nyttig for ikoner og kompakte verktøylinjeknapper der du vil utvide treffarealet opp og ned. + +```jsx live +
+
y-sm
+
y-md
+
y-lg
+
+``` + +### Individuelle sider + +Nyttig for elementer som sitter langs en kant og bare trenger utvidelse innover — for eksempel en lukk-knapp i et hjørne. + +```jsx live +
+
t-lg
+
r-lg
+
b-lg
+
l-lg
+
+``` + +### Kombiner akseklasser + +Bruk x- og y-akseklassene sammen for asymmetrisk utvidelse. + +```jsx live +
+
x-lg y-2xs
+
x-2xs y-lg
+
+``` + ## Debug To klasser gjør det enklere å visualisere hitbox-arealet under utvikling. Fjern dem før produksjon. diff --git a/indeks-docs/src/css/custom.css b/indeks-docs/src/css/custom.css index dd28133..de3b6bc 100644 --- a/indeks-docs/src/css/custom.css +++ b/indeks-docs/src/css/custom.css @@ -67,4 +67,23 @@ /* Gjenopprett fokusring på textarea — høyere spesifisitet enn Infima sin regel */ body:not(.navigation-with-keyboard) .ix-text-area textarea:focus { outline: var(--ix-outline-default); +} + +.hb-demo { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: var(--ix-spacing-2xl); + padding: var(--ix-spacing-2xl); +} + +.hb-demo > div { + display: inline-flex; + align-items: center; + padding: 4px 12px; + background: var(--ix-color-surface-main-default); + border: 1px solid var(--ix-color-border-main-default); + border-radius: 4px; + font-size: 0.875rem; + cursor: pointer; } \ No newline at end of file