designsystemet
designsystemet copied to clipboard
Font based sizing / scaling and less useContext?
TL;DR: Her er et kjørende eksempel: https://codepen.io/eirikbacker/pen/RwXNpXo
Har tenkt en stund på dette med size
. I de fleste tilfeller, vil vi at når man setter size
, på en komponent, så påvirker det også bestanddelene inni.
F.eks; Pagination size="sm"
gjør at Pagination.Button
også skal ha size="sm"
, Dropdown size="sm"
gjør at Dropdown.Item
skal ha size="sm"
og så videre.
- I dag kreves React/Javascript som kjørere i nettleseren (ikke på server) for å få til dette, via
useContext
APIet som sendersize
nedover. Jeg tenker det er både kjipt fordi det ikke lar seg oversette til oss som jobber uten React, og det er kjipt fordi det gjør applikasjonene tyngre da det krever med rendering i nettleser. - Videre øker mengden kode generelt slik vi har implementert i dag
- Det hindrer konsumenter fra å lage ordentlig fluid scaling dersom de ønsker å implementere det
- I dag er er ikke mulig å skalere komponentene baser på skjermstørrelse med CSS; man må faktisk bytte på HTMLen Så, hva kan vi gjøre isteden?
La oss ta et eksempel med Pagination:
- CSS er skikkelig god på å arve en stil fra forelder og nedover til barna.
- Enste utfordringen er da at det må være samme stil, så f.eks setter jeg
padding: 5px
på Pagination, så er det lett å arvepadding: 5px
påPagination.Button
. - Men, vi vil jo ikke ha
padding: 5px
påPagination
, vi vil hapadding: 0
påPagination
, men fortstatt hapadding: 5px
påPagination.Button
- hvordan får vi til det? - Jo, det er én ting vi vil at skal arves nedover:
font-size
- Det betyr, at hvis padding kan basere seg på
font-size
, så får vi til noen nydeligepadding
-skalaer - også påPagination.Button
- som blir større og mindre, nårfont-size
justeres. - Det vil også bety, at når gap skal øke på selve
Pagination
, så trenger vi ikke å defineregap
mange ganger, fordigap
også kan basere seg påfont-size
.
Dette vil være relevant for gap/padding/margin/width/height
- alt som handler om størrelse, kan være skala-basert på font-size
I stede for å skrive slik som i dag:
.ds-button {
--dsc-button-font-size: var(--ds-font-size-5);
--dsc-button-gap: var(--ds-spacing-2);
--dsc-button-padding-block: var(--ds-spacing-2);
--dsc-button-padding-inline: var(--ds-spacing-4);
font-size: var(--dsc-button-font-size);
gap: var(--dsc-button-gap);
padding: var(--dsc-button-padding-block) var(--dsc-button-padding-inline);
&[data-size='sm'] {
--dsc-button-font-size: var(--ds-font-size-4);
--dsc-button-gap: var(--ds-sizing-1);
--dsc-button-padding-block: var(--ds-spacing-2);
--dsc-button-padding-inline: var(--ds-spacing-3);
}
&[data-size='lg'] {
--dsc-button-font-size: var(--ds-font-size-6);
--dsc-button-gap: var(--ds-sizing-3);
--dsc-button-padding-block: var(--ds-spacing-3);
--dsc-button-padding-inline: var(--ds-spacing-5);
}
}
Kunne vi ha skrevet dette:
.ds-button {
--dsc-button-font-size: var(--ds-font-size-5);
font-size: var(--dsc-button-font-size);
gap: var(--ds-sizing-scale-2);
padding: var(--ds-sizing-scale-2) var(--ds-sizing-scale-4);
&[data-size='sm'] { --dsc-button-font-size: var(--ds-font-size-4); }
&[data-size='lg'] { --dsc-button-font-size: var(--ds-font-size-6); }
}
Og isteden for å skrive slik når (man ikke bruker React):
<nav class="ds-pagination" data-size="sm"> <-- data-size må gjentas
<ol>
<li><button type="button" data-size="sm">1</button></li> <-- data-size må gjentas
<li><button type="button" data-size="sm">2</button></li> <-- data-size må gjentas
<li><button type="button" data-size="sm">3</button></li> <-- data-size må gjentas
<li><button type="button" data-size="sm">4</button></li> <-- data-size må gjentas
<li><button type="button" data-size="sm">5</button></li> <-- data-size må gjentas
<li><button type="button" data-size="sm">6</button></li> <-- data-size må gjentas
</ol>
</nav>
Vil man kunne skrive dette:
<nav class="ds-pagination" data-size="sm"> <-- data-size er satt én gang wee
<ol>
<li><button type="button">1</button></li>
<li><button type="button">2</button></li>
<li><button type="button">3</button></li>
<li><button type="button">4</button></li>
<li><button type="button">5</button></li>
<li><button type="button">6</button></li>
</ol>
</nav>
Systemet baserer seg på at man lager en (eller flere) skala, basert på font-size:
:root {
--ds-sizing-scale: .875rem;
/* 👆 14px at 1rem, must be smaller than smallest font-size to have effect (because 14px font size - 14px scale = 0) */
--ds-sizing-scale-1: calc(1em - var(--ds-sizing-scale) * 1);
/* 👆 4px at sm, 8px at md, 12px at lg */
--ds-sizing-scale-2: calc(2em - var(--ds-sizing-scale) * 2);
/* 👆 6px at sm, 12px at md, 18px at lg */
--ds-sizing-scale-3: calc(3em - var(--ds-sizing-scale) * 3);
/* 👆 8px at sm, 16px at md, 24px at lg */
--ds-sizing-scale-4: calc(4em - var(--ds-sizing-scale) * 4);
}
Da går det også an å gjøre:
/* For å endre størrelse til mobil med ren CSS: */
@media(max-width: 80em) {
.ds-button { --dsc-button-font-size: var(--ds-font-size-4) }
}
...så dette tror jeg vil være mulig å gjenskape i Figma også?
Ser at det vil kreve en liten opprydding; er ikke alltid vi skalerer gap f.eks konsekvent, men det tror jeg er fint å rydde i uansett. Vil gjerne høre hva dere tenker og gjerne sparre med @Thunear og @Febakke litt på om det designmessig gir mening også.
Vil også løst #1781 Vil også påvirke #1583