
Több év és néhány kisebb webes projekt megírása és karbantartása után kidolgoztam néhány heurisztikát a fenntartható CSS megírásához. A névadáshoz BEM, SMACSS és CSS modulokat használtam, bár ez a cikk önmagában nem a névadásról szól. (Hajlamos vagyok az atomosztályok és a BEM-ish elnevezések keverékét használni.) Ez a cikk inkább az általam használt vagy elkerült tulajdonságokról és értékekről szól.
Saját StyleLint konfiguráció: //github.com/NickGard/css-utils/blob/master/stylelint.config.jsonSzínek
A kedvtelésből tartott kedvenceim túl sok színértéket mutatnak egy webes projektben. Egy nagy, hosszú életű projekten, amelyen néhány éve dolgoztam, több mint 300 egyedi színt deklaráltak 40 CSS fájlban. Ezek harmada szürke árnyalatú volt. A márka színeit kis színárnyalatokkal megismételtük. Ezen színek közül sok különbözött szó szerint észrevehetetlen értékekkel, mint a #3426D1
és a #3426D2
. Ennek megoldása az atom színosztályok vagy változók (SCSS vagy CSS formában) használata az elfogadott márka színeihez.
Az elfogadott színek számának korlátozása azzal az előnnyel jár, hogy egyszerűvé teszi annak biztosítását, hogy a háttér és az előtér színei megfeleljenek a WCAG2.0 színkontraszt irányelveinek.
Egy másik hibára hajlamos gyakorlat az alfa-csatornás színek használata, általában a szín rgba()
vagy hsla()
funkcióval történő deklarálásával . Az így létrehozott szín alfacsatorna-értékével nem más, mint 1
félig átlátszatlan. Az érzékelt szín most attól függően változik, hogy mi van a háttérben . Általában a kívánt szín az, aminek ez a fehér háttér felett kinéz, így helyette hexa értéket is használhat. Néhány előfeldolgozó funkció, például a SASS lighten()
, félig átlátszatlan színt hoz létre, ezért ragaszkodjon a keményen kódolt értékekhez vagy változókhoz.
Tipográfia
Minden olyan tulajdonságot, amely a betűtípust érinti vagy befolyásolja, egyszerre kell deklarálni . A @font-face
szabályok deklarálása után rögtön szeretnék atomosztályokat adni a betűtípushoz, amelyek megváltoztatják a font-size
(via rem
) szót line-height
, és tartalmazzák a letter-spacing
, és word-spacing
amelyek megfelelnek a betű és méret kombinációjának. Ezt követően semmilyen font-*
vagy text-*
(a kivételével text-overflow
) tulajdonságot nem szabad használni egyetlen szabálykészletben sem.
Ezen tulajdonságok egyszeri, a font-face együttes deklarálása biztosítja, hogy a webhelyen található másolat mindig megfelelő legyen. Ha módosítja a szöveg line-height
helyett, padding
vagy margin
hibákat hoz létre, amikor a szöveg be van burkolva. A font-weight
betűkészlet-deklarációtól külön történő beállítás faux félkövér betűtípus létrehozásának kockázatával jár. A font-style
nem támogató betűkészlet megváltoztatásával faux ferde lesz.
Végül kerülje a betűméretek beállítását az rem
egységek kivételével . A használata em
problémákat okoz az elemek beágyazásakor, mert em
az áram skaláris többszöröse font-size
. A használat px
(vagy bármely más „rögzített” mérés) azt a kockázatot jelent, hogy nehezen olvasható és a felhasználó számára nem lehet alkalmazkodni képes másolatot létrehozni . Engedje meg a felhasználónak (vagy a felhasználó böngészőjének), hogy állítsa be a font-size
számára megfelelőt, azzal, hogy nem deklarál egy font-size
a elemet body
vagy html
elemet, és csak a rem
.
Távolság
A tartalom első webhelyen a szóköznek kiegészítenie kell a másolatot. Bármilyen statikus mérés, mint padding: 4px
, úgy néz ki, rossz a néhány betűméretet. A betűméretekre reagáló dinamikus mérés, például padding: .5em
, minden betűméretre néz.
Használja em
a térköz tulajdonságainak megadásához.
Rács
A CSS Grid nagyon jól támogatott (vissza az IE10-hez!), És lehetővé teszi a tartalom elrendezését két dimenzióban hozzáadott tároló elemek, például a Bootstrap row
vagy a col
rács elemek nélkül. A tervezők gyakran 12 oszlopos rácsokban dolgoznak, és a CSS keretrendszerek általában követik a példájukat, de a rácsoknak, mint minden térköznek, kiegészíteniük kell a másolatot, nem pedig korlátozniuk. A rácsokat ad hoc formában kell megírni, nem előre meghatározott formátumban, kontextus nélkül. Ne puffassza fel a CSS-t egy „rács keretrendszerrel”.
Szöveg igazítása
text-align
gyakran használják a szövegen kívüli dolgok összehangolására. Ez nem a megfelelő eszköz a munkához. Használja a flexboxot az ilyen típusú igazításhoz. Az értékek használata, left
és right
nem mindig működik jobbról balra vagy függőleges nyelvekkel (egyes böngészők ezeket az értékeket a flow-relatív start
és end
, de nem az összeshez hozzárendelik ). Az érték használata a justify
szövegen néhány nyelven problémákat okozhat a digráfokkal, és problémákat okozhat a diszlexiában szenvedők számára. Minden felhasználási esetet text-align
jobban megold a flexbox, ezért inkább ezt használja. Mindig.
Körvonalak
A fókuszált elemek körvonalai azt mutatják, hogy a böngészők natív módon kommunikálják-e, melyik elem kap bemenetet. Az alapértelmezett körvonalak általában elég szembetűnőek ahhoz, hogy minden felhasználó számára hasznosak legyenek, beleértve azokat is, akiknek nagy kontrasztra van szükségük. Az alapértelmezett vázlatot általában felülírják (vagy eltávolítják), mert nem felelnek meg a webhely kialakításának. Hacsak nem helyettesíti a fókuszált outline
stílust valamilyen más jól látható és elérhető fókuszjelzővel, ne távolítsa el vagy semmissé tegye a vázlat tulajdonságot .
Fókusz és lebegés
Mint fent említettük, vigyázzon a :focus
stílus megváltoztatására, mert ez jelzőként működik, amely elemhez éppen beérkezik az input. Stílusok hozzáadása egy elemhez a :hover
következőn gyakran jó tapintás, de ne használja ezt az álválasztót további példányok megjelenítéséhez, hacsak nem teszi meg ugyanezt :focus
(és természetesen, ha az elem fókuszálható ). Ez általában, de nem mindig, egy jó ötlet, ha mind a :hover
és :focus
pszeudo-szelektor ugyanazon szabályrendszert. (Ha hozzáadja a :focus
választót egy gomb lebegési stílusához, akkor a megnyomott gomb „beragadhat”.)
Átlátszatlanság
Ha opacity
egy elemet úgy 0
állít be, hogy valójában nem rejti el az akadálymentességi eszközök elől. Az elem továbbra is helyet foglal a dokumentum folyamatában, és annak másolatát továbbra is a képernyőolvasók olvassák. Az egyetlen két felhasználási eset, amely ésszerűen megköveteli a opacity
tulajdonság használatát, az , amikor egy elemet áttér a nézetre (gyorsan áttérés onnan 0
át 1
), és egy párbeszédpanel-stílus kialakítása (tehát az alábbi tartalom némileg látható). Óvakodjon a „halmozott” félig átlátszatlan fedvényektől. Az átlátszatlansági szint multiplikatív, ezért a két, egyenként nem fedett tartalom alatti tartalom opacity: 50%
úgy jelenik meg, mintha egyetlen elem alatt lenne opacity: 25%
.
Válogatók
Ragaszkodjon az osztály és osztályszerű választók használatához. Az id, type és univerzális választók használata fejfájással jár. A CSS-specifitásban az azonosító-választók mindig nyernek bármely más választóval szemben, de az id
attribútumoknak állítólag egyedinek kell lenniük (oldalanként), így nem használhatók újrafelhasználható stílusok alkalmazásakor.
A modern böngészőkben a választók teljesítménye elhanyagolható aggodalomra ad okot, ezért annak ellenére, hogy hallottál arról, hogy az univerzális választó ( *
) nem teljesítő, a használatával kapcsolatban az az igazi aggodalmam, hogy szinte minden felhasználási esethez túl általános. Valamilyen választót használ .my-class >
; * végül néhány gyermek kizárásához vezet, így osztályokat is felvehet a stílushoz, és közvetlenül megcélozhatja őket.
Egy hasonló érv lehet, hogy nem használ típusú szelektor, mint div
, main
. Túl sok elemhez szoktak illeszkedni, és általában további részletekre van szükségük ahhoz, hogy hasznosak legyenek, például div.some-class
. Az ilyen összetett szelektorok magasabb specifitással rendelkeznek, mint az egyetlen osztályválasztó, ami az alábbiakban egy hibaképző probléma.
Tartsa be az osztály ( .class
), az attribútum ( [attribute]
) és az ál-osztály ( :focus
) választókat. Mindegyikük azonos szintű sajátossággal rendelkezik.
Sajátosság
At the opposite end of the spectrum of selectors being too general (like using *
) are selectors being too specific. Both cases cause problems. An overly-specific selector breeds even more specific selectors or the dreaded !important
declarations. Each successive selector becomes a new hurdle to overcome when making styling changes, and following this path leads to the ever-growing fragile stylesheets we all dread working with.
CSS has a naturally increasing specificity — the order of the rulesets. This is part of the cascade in Cascading Style Sheets. With this in mind, we can write rulesets in ascending order of “importance” without increasing the selector specificity level. For example:
.btn { color: black;}.btn--primary { color: green;}.btn--primary--light { color: white;}
In this example, each single-class-selector is more specific than its predecessor, eliminating the need to declare a ruleset for .btn.btn--primary
or .btn.btn--primary--light
.
The fix is to stick to single class selectors as much as possible, written in order of increasing “importance,” and avoid using !important
declarations.
Text-transform
For sites that support languages other than English, using text-transform
will probably cause problems. There are several cases where browsers replace a character with an incorrect version for the upper- or lower-case transformations. The fix is never to use text-transform
and instead rely on an accurately capitalized copy.
Z-index
If any z-index
rule is included in a stylesheet, there will eventually be two other rules that declare z-index: 9999;
and z-index: 99999;
. Attempting to use atomic classes or variables to limit the number of acceptable z-indexes will not only fail to curb developers from using calc()
and SCSS math to modify the value for their use-case, but will miss the target entirely because of how stacking contexts work.
It has been my experience that most, if not all, uses of z-index
can be replaced by restructuring the HTML to use the natural stacking context (elements lower on the page are higher in the context) or by adding a property to the element or its parent to force a new stacking context.
Avoid z-index
at all costs.
Pseudo-elements
Using the pseudo-elements ::before
and ::after
is not only helpful, but it’s often fun! Many stylistic tricks rely on the use of these two pseudo elements and, as long as there is no copy in them (via their content
property), they are considered semantic. The issue with putting copy in these elements is that whether or not they are read by accessibility devices varies across browsers and devices. It is better to not deal with that discrepancy by avoiding placing a copy in them.
The pseudo-elements ::first-letter
and ::first-line
do not work like you probably think they should. They only target the first letter/line in a block-level element. There are also issues with the ::first-line
selector incorrectly targeting double-byte characters (such as Japanese Kana) and digraphs.
Manipulating the styles of selected text or placeholder text via ::selection
and ::placeholder
, respectively, often leads to trouble. With ::placeholder
, the concern is simple: you shouldn’t be using placeholders. This is especially true for anything of importance, such as input labels or hints. By including ::placeholder
styles, you encourage developers, designers, and authors to use them, much to the frustration of your users.
Modifying selection styles, usually color
and background-color
, leads to more subtle but insidious bugs. While the default selection colors are not consistent across browsers or devices and they do not always provide an acceptable contrast with your site’s text color, users sometimes overwrite them for accessibility reasons. Changing the colors, in this case, could either not work (because of the user’s accessibility CSS trumps yours) or it could interfere with their style sheets (if you use !important
). Using this pseudo-element to try to guarantee an accessible contrast could end up disrupting the experience for the very people you wish to help.
(Though I’ve forgotten many of the details of this bug, I ran into an issue years ago where Chrome’s auto-translated text was rendered invisible because it relied on ::selection
styling which I had modified.)
Transitions & Animations
Transitioning or animating properties other than opacity
and transform
causes the browser to repaint or reflow the page. This may not seem like a problem on a high-end developer machine, but it will cause stuttering on low-end laptops and phones. Bad animation is worse than no animation.
Prefers Reduced Motion
Writing animations that are helpful, beautiful, and safe is not a simple undertaking. With the advent of the media query prefers-reduced-motion
, we can help make our pages safer for people with vestibular disorders, and less annoying for the rest of us. While adding this media query is not a silver bullet, it helps. I’ve written the nested rule to be opt-out, meaning that all CSS animations get stopped unless the author includes the class safe-animation
on the element.
/* //github.com/mozdevs/cssremedy/issues/11#issuecomment-462867630 */@media (prefers-reduced-motion: reduce) { *:not(.safe-animation), *:not(.safe-animation)::before, *:not(.safe-animation)::after { animation-duration: 0.01s !important; animation-iteration-count: 1 !important; transition-duration: 0s !important; scroll-behavior: auto !important; }}
Reset extensions
My go-to CSS reset is a modified form of the Meyers reset. There are a few rules I remove from the reset, though. I don’t like to remove list icons from ol
and ul
elements. I find that doing so encourages developers to use those elements in non-semantic ways, like grouping items that are physically proximate but not ontologically proximate. I also remove the rule setting the line-height
on the body
to 1
. Setting attributes that affect, or are affected by, the font separately from setting the font is a bug waiting to happen.
Az alábbiakban néhány kiegészítést adok a visszaállítási fájlhoz. Nem szeretek egy .hidden
atomosztályt felvenni a CSS-be, mert van egy jobb lehetőség, amely akkor is működik, ha a CSS nem töltődik be - az hidden
attribútum. A böngésző alapértelmezett viselkedése display: none
a rejtett elemek beállításakor felülírható, akár véletlenül is, ezért a kikényszerítéshez szabályt adok.
body { /* more intuitive sizing */ box-sizing: border-box;}*, ::before, ::after { box-sizing: inherit;}i, cite, em, var, dfn, address { /* prevent faux italic */ font-style: normal;}b, h1, h2, h3, h4, h5, h6, strong, th { /* prevent faux bold */ font-weight: normal;}[hidden] { /* enforce accessible semantics */ display: none !important;}
Saját visszaállítás: //github.com/NickGard/css-utils/blob/master/reset.css
Egy másik segédprogram, amelyet gyakran szükségesnek tartok, egy visually-hidden
osztály. Bár aria-label
gyakran használok láthatatlan, képernyőn olvasható szövegeket, általában a következő szabályt veszem fel valahova:
/* //a11yproject.com/posts/how-to-hide-content/ */.visually-hidden { position: absolute !important; height: 1px; width: 1px; overflow: hidden; clip: rect(1px, 1px, 1px, 1px);}
BEMish névadás
Nem fejezhetem be ezt a cikket anélkül, hogy legalább egy megjegyzést fűznék a névadási szokásokhoz. Tetszik a BEM névadás, mert jól olvasható.
In my CSS, this looks like this:
.btn, .btn--primary { /* base button styles */}.btn--primary { /* primary button overrides */ /* has naturally higher specificity */}
In SCSS, you can achieve this same effect using
@extend
.
Conclusion
Conclusion
These have been my rules of thumb for several years now and have helped me maintain large codebases with many contributors. It’s not perfect and I’m always adjusting it (
prefers-reduced-motion
is new) but I hope that by sharing it, it will help others.