CSS szabályok, amelyek megkönnyítik az életedet

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.json

Szí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 1fé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-faceszabá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-spacingamelyek 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-heighthelyett, paddingvagy marginhibákat hoz létre, amikor a szöveg be van burkolva. A font-weightbetű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-stylenem 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 remegységek kivételével . A használata emproblémákat okoz az elemek beágyazásakor, mert emaz á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-sizeszámára megfelelőt, azzal, hogy nem deklarál egy font-sizea elemet bodyvagy htmlelemet, é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 ema 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 rowvagy a colrá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-aligngyakran 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 rightnem 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 justifyszö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-alignjobban 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 outlinestí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 :focusstí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 :hoverkö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 :focuspszeudo-szelektor ugyanazon szabályrendszert. (Ha hozzáadja a :focusválasztót egy gomb lebegési stílusához, akkor a megnyomott gomb „beragadhat”.)

Átlátszatlanság

Ha opacityegy 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 opacitytulajdonsá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 idattribú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 .hiddenatomosztá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 hiddenattribútum. A böngésző alapértelmezett viselkedése display: nonea 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-hiddenosztály. Bár aria-labelgyakran 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ó. /> 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.