CSS taisyklės, kurios palengvins jūsų gyvenimą

Po daugelio metų rašymo ir palaikymo keliuose labai dideliuose ir daugelyje mažesnių interneto projektų sukūriau keletą euristinių duomenų, skirtų prižiūrimam CSS rašyti. Pavadinimams naudojau BEM, SMACSS ir CSS modulius, nors šis straipsnis nėra apie pavadinimą. (Aš linkęs naudoti atominių klasių ir BEM-ish pavadinimų derinį.) Šis straipsnis yra daugiau apie savybes ir vertes, kurias naudoju arba kurių vengiu.

Mano „StyleLint“ konfigūracija: //github.com/NickGard/css-utils/blob/master/stylelint.config.json

Spalvos

Mano augintinių peeve yra per didelis spalvų vertybių gausa interneto projekte. Dideliame, ilgai gyvavusiame projekte, prie kurio dirbau prieš kelerius metus, 40-yje CSS failų buvo deklaruota per 300 unikalių spalvų. Trečdalis jų buvo pilkos spalvos atspalviai. Prekės ženklo spalvos buvo kartojamos su nežymiais atspalvio skirtumais. Daugelis šių spalvų skyrėsi pažodžiui nepastebimomis vertybėmis, pavyzdžiui, #3426D1ir #3426D2. Išeitis yra tai, kad priimtų prekės ženklų spalvoms bus naudojamos atominės spalvų klasės arba kintamieji (SCSS arba CSS).

Ribotų priimamų spalvų skaičiaus nauda yra papildoma, nes paprasčiau užtikrinti, kad fono ir priekinio plano spalvos atitiktų WCAG2.0 spalvų kontrasto gaires.

Kita į klaidas linkusi praktika yra alfa kanalo spalvų naudojimas, paprastai deklaruojant spalvą su rgba()arba hsla()funkcijomis. Tokiu būdu sukurta spalva, kurios alfa kanalo vertė yra ne kas kita, o 1pusiau nepermatoma. Suvokiama spalva dabar keičiasi priklausomai nuo to, kas yra fone . Paprastai norima spalva yra tokia, kokia atrodo baltame fone, todėl vietoj jos galite naudoti šešiakampę reikšmę. Kai kurios išankstinio procesoriaus funkcijos, pvz., SASS lighten(), sukurs pusiau nepermatomą spalvą, todėl laikykitės griežtai koduojamų reikšmių ar kintamųjų.

Tipografija

Visos savybės, kurios turi įtakos arba jie yra paveikiami šrifto turėtų būti paskelbta vieną kartą kartu. Iškart po deklaravimo jokių @font-facetaisyklių aš norėčiau pridėti atomines klases šrifto kad pakeisti font-size(TVOU rem) ir įtraukti line-height, letter-spacingir word-spacingkad tinka tos šrifto ir dydžio derinys. Po to jokiame taisyklių rinkinyje neturėtų būti naudojama jokia nuosavybė font-*arba text-*(išskyrus text-overflow) nuosavybė.

Vieną kartą deklaravus šias savybes kartu su šriftu, užtikrinama, kad svetainės kopija visada atrodytų tinkamai. Koreguojant line-heightvietoj paddingarba marginbus sukurtos klaidos, kai tekstas apvyniojamas. Koreguojant font-weightatskirai nuo šrifto deklaracijos kyla pavojus sukurti dirbtinį paryškintą šriftą. Pakeitus font-stylešriftą, kuris jo nepalaiko, sukuriamas dirbtinis įstrižas.

Galiausiai venkite nustatyti šriftų dydžius, išskyrus remvienetus. Naudojant emkyla problemų sudedant elementus, nes emyra srovės skaliarinis kartotinis font-size. Naudojant px(ar bet kurį kitą „fiksuotą“ matavimą) kyla pavojus sukurti sunkiai įskaitomą ir vartotojui neįmanoma pritaikomą kopiją . Leidžia vartotojui (ar vartotojo naršyklė), kad nustatyti font-size, kas tinka jiems ne skelbiantis font-sizeant bodyarba htmlelementą ir tik naudojant rem.

Tarpai

Pirmoje turinio svetainėje tarpai turėtų papildyti kopiją. Bet koks statinis matavimas padding: 4pxatrodo netinkamas dėl tam tikro šrifto dydžio. Dinamiškas matavimas, atsižvelgiant į šriftų dydžius padding: .5em, atrodo tinkamas kiekvienam šrifto dydžiui.

Naudokite emtarpų savybėms.

Tinklelis

CSS tinklelis yra labai gerai palaikomas (grįžta į IE10!) Ir leidžia išdėstyti turinį dviem aspektais be papildomų sudėtinių rodinių elementų, tokių kaip „Bootstrap“ rowar coltinklelio elementai. Dizaineriai dažnai dirba 12 stulpelių tinkleliuose, o CSS sistemos dažniausiai seka pavyzdžiu, tačiau tinkleliai, kaip ir visi tarpai, turėtų papildyti kopijas, o ne varžyti. Tinkleliai turėtų būti rašomi ad hoc, o ne iš anksto nustatyta forma be konteksto. Negalima išpūsti savo CSS naudojant „tinklelio sistemą“.

Teksto lygiavimas

text-aligndažnai naudojamas norint suderinti kitus dalykus nei tekstas. Tai nėra tinkama darbo priemonė. Tokiam lygiavimui naudokite „flexbox“. Naudojant reikšmes left ir rightne visada galima dirbti su kalbomis, kurios yra iš dešinės į kairę arba vertikaliai (kai kurios naršyklės priskiria šias vertes srauto santykinei startir end, bet ne visoms). Vertės justifynaudojimas tekste gali sukelti problemų kai kuriomis kalbomis su digrafais, be to, tai gali sukelti problemų disleksija sergantiems žmonėms. Kiekvieną naudojimo atvejį text-aligngeriau išspręsti „flexbox“, todėl naudokitės tuo. Visada.

Kontūrai

Sufokusuotų elementų metmenys yra tai, kaip naršyklės natūraliai bendrauja, kuris elementas gauna įvestį. Numatytieji kontūrai paprastai yra pakankamai ryškūs, kad būtų naudingi kiekvienam vartotojui, įskaitant tuos, kuriems reikia didelio kontrasto. Numatytasis kontūras paprastai perrašomas (arba pašalinamas), nes jis neatitinka svetainės dizaino. Nebent jūs pakeičiant išryškintą outlinestilių su kitu matomoje ir prieinamoje fokusavimo indikatorius, negalima išimti ar panaikinti kontūro turtą .

Sufokusuoti ir užvesti pelės žymeklį

Kaip minėta pirmiau, saugokitės pakeisti :focusstilių, nes jis veikia kaip indikatorius, kuriam elementui šiuo metu gaunama įvestis. Stilių pridėjimas prie elemento :hoverdažnai yra malonus prisilietimas, tačiau nenaudokite to pseudo selektoriaus, kad būtų rodoma papildoma kopija, nebent tai darote :focus(ir, žinoma, jei elementas fokusuojamas ). Paprastai, bet ne visada, yra gera idėja tam pačiam taisyklių rinkiniui naudoti :hoverir :focuspseudo selektorius. (Pridėjus :focusmygtuko žymeklio stilių, esantį žymeklį, paspaustas mygtukas gali būti „įstrigęs“.)

Neskaidrumas

opacityElemento nustatymas iš 0tikrųjų jo nepaslepia nuo pritaikymo neįgaliesiems įrankių. Elementas vis dar užima vietą dokumento sraute, o jo kopiją vis dar skaito ekrano skaitytuvai. Vieninteliai du naudojimo atvejai, dėl kurių pagrįstai reikalaujama naudoti opacitynuosavybę, yra perkeliant elementą į rodinį (greitai pereinant nuo 0į 1) ir kuriant dialogo perdangą (taigi žemiau esantis turinys yra šiek tiek matomas). Saugokitės „sukrautų“ pusiau nepermatomų perdangų. Neskaidrumo lygis yra dauginamasis, todėl turinys, esantis žemiau dviejų perdangų, su kiekvienu, opacity: 50%rodomas taip, lyg jis būtų žemiau vieno elemento su opacity: 25%.

Selektoriai

Laikykitės klasių ir į klases panašių selektorių. Naudojant ID, tipo ir universalius selektorius, skauda galvą. Kalbant apie CSS, ID parinkėjai visada laimi prieš bet kurį kitą selektorių, tačiau idmanoma, kad atributai yra unikalūs (puslapyje), todėl jie nėra naudingi taikant daugkartinio naudojimo stilius.

Selektoriaus našumas šiuolaikinėse naršyklėse yra nereikšmingas rūpestis, todėl, nepaisant to, ką galbūt girdėjote apie tai, kad universalusis selektorius ( *) nėra efektyvus, iš tikrųjų nerimauju dėl jo naudojimo, kad jis yra per daug įprastas kiekvienam naudojimo atvejui. Naudojant kokį nors selektorių kaip .my-class >; * galų gale atsisakys kai kurių vaikų, todėl jūs taip pat galite pridėti klases prie elementų, kuriuos norite stilizuoti, ir nukreipti juos tiesiogiai.

Panašų argumentą galima pateikti ir nenaudojant tipo parinkiklių, pvz. div, main. Jie linkę derinti per daug elementų ir paprastai reikalauja daugiau informacijos, kad būtų naudinga, pvz div.some-class. Tokie sudėtiniai selektoriai turi didesnį specifiškumą nei vienos klasės parinkiklis, o tai yra žemiau nagrinėjama klaida generuojanti problema.

Laikykitės klasės ( .class), atributo ( [attribute]) ir pseudo klasės ( :focus) selektorių. Visi jie turi tą patį specifiškumo lygį.

Specifiškumas

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.

Toliau pateikiami keli papildymai, kuriuos darau iš naujo nustatęs failą. .hiddenNemėgstu įtraukti atominės klasės į savo CSS, nes yra geresnė parinktis, kuri veiks net ir tuo atveju, jei CSS neįkeliama - hiddenatributas. Numatytasis naršyklės elgesys, kai nustatomi display: nonepaslėpti elementai, gali būti net netyčia perrašyti, todėl įtraukiu taisyklę, kaip ją įgyvendinti.

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;}
Mano atstatymas: //github.com/NickGard/css-utils/blob/master/reset.css

Kitas įrankis, kuris man atrodo reikalingas, yra visually-hiddenklasė. Nors aria-labeldažnai naudoju nematomą tekstą, kurį galima skaityti ekrane, paprastai kažkur įtraukiu šią taisyklę:

/* //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 įvardijimas

Negaliu užbaigti šio straipsnio be bent vieno komentaro apie vardų suteikimo įpročius. Man patinka BEM įvardijimas, nes jis gerai skaitomas. /> tells me exactly what kind of button it is. My one break from the Official BEM™ methodology is that I like t o use one class on an element (with the possible exception of atomic classes). It offends my sensibilities t o see because the second class already tells me the styles extend from the base btn ruleset. This also creates two reasons for a line to change, which is a red flag.

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

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.