ЦСС правила која ће вам олакшати живот

Након година писања и одржавања неколико веома великих веб пројеката и бројних мањих, развио сам неке хеуристике за писање одрживог ЦСС-а. За именовање сам користио БЕМ, СМАЦСС и ЦСС модуле, мада овај чланак није сам о именовању. (Обично користим комбинацију атомских класа и БЕМ-исх именовања.) ​​Овај чланак говори о својствима и вредностима које користим или избегавам.

Конфигурација Ми СтилеЛинт: //гитхуб.цом/НицкГард/цсс-утилс/блоб/мастер/стилелинт.цонфиг.јсон

Боје

Мој љубимац кућног љубимца је прекомерно богатство боја у веб пројекту. Велики, дуговечни пројекат на којем сам радио пре неколико година, имао је преко 300 јединствених боја пријављених у 40-ак ЦСС датотека. Трећина њих су биле нијансе сиве. Боје марке поновљене су са малим разликама у нијанси. Многе од ових боја разликовале су се буквално неприметне вредности, попут #3426D1и #3426D2. Решење за ово је употреба атомских класа боја или променљивих (у СЦСС или ЦСС) за прихваћене боје бренда.

Ограничавање броја прихваћених боја има додатну предност што поједностављује осигуравање да боје позадине и првог плана испуњавају смернице ВЦАГ2.0 Цонтраст Цолор.

Друга пракса склона грешкама је коришћење боја алфа-канала, обично декларисањем боје помоћу rgba()или hsla()функција. Овако створена боја са вредностом алфа канала било чега осим што 1је полупрозирна. Опажена боја се сада мења у зависности од онога што је у позадини . Обично је жељена боја како ова изгледа на белој позадини, па уместо ње можете да користите хексадецималну вредност. Неке функције претпроцесора, попут САСС-ових lighten(), генерисаће полупрозирну боју, зато се придржавајте чврсто кодираних вредности или променљивих.

Типографија

Све особине које утичу или су погођене фонт треба прогласити једном заједно. Одмах након проглашења било @font-faceправила, ја бих да додам атомске наставе за фонт који мењају font-size(преко rem) и укључују line-height, letter-spacingи word-spacingда су одговарајуће за ту комбинацију фонта и величине. Након тога, ниједно font-*или text-*(са изузетком text-overflow) својство не би требало да се користи у било ком скупу правила.

Декларирање ових својстава једном у комбинацији са фонтом лица осигурава да копија на локацији увек изгледа исправно. Прилагођавањем line-heightуместо paddingили marginће створити грешке када се текст премота. Прилагођавање font-weightодвојено од декларације фонта ризикује да створи погрешно подебљани фонт. Промена font-styleфонта који га не подржава ствара погрешно косо.

И на крају, избегавајте постављање величина фонта на било шта осим remјединица. Коришћење emузрокује проблеме при угнежђивању елемената јер emје скаларни вишекратник струјеfont-size . Коришћење px(или било које друго „фиксно“ мерење) ризикује стварање копије коју је тешко прочитати и коју корисник не може прилагодити. Дозволите кориснику (или корисниковом прегледачу) да постави font-sizeоно што је за њега исправно тако што не декларише знак font-sizeа bodyили htmlсамо користи rem.

Размак

На локацији са садржајем прво, размак треба да допуни копију. Било какво статично мерење, на пример padding: 4px, изгледа погрешно на некој величини фонта. Динамично мерење, које одговара величини фонта padding: .5em, изгледа баш на свакој величини фонта.

Користите emза својства размака.

Грид

ЦСС Грид је веома добро подржан (натраг на ИЕ10!) И омогућава распоређивање садржаја у две димензије без доданих елемената контејнера као што су Боотстрап rowили colгрид елементи. Дизајнери често раде у решеткама од 12 колона, а ЦСС оквири обично следе њихов пример, али мреже, као и сви размаци, треба да допуњују копију, а не да је ограничавају. Мреже треба писати ад хоц, а не у унапред одређеном формату без контекста. Не надимајте свој ЦСС „мрежним оквиром“.

Поравнање текста

text-alignчесто се користи за поравнање ствари осим текста. Ово није прави алат за посао. За ову врсту поравнања користите флекбок. Коришћење вредности left и rightне функционише увек са језицима који су здесна налево или вертикално (неки прегледачи мапирају ове вредности у релативни проток startи end, али не све). Коришћење вредности justifyтекста може на неким језицима створити проблеме са диграфима и људима са дислексијом. Сваки случај употребе text-alignбоље је решити флексбоксом, па га уместо тога користите. Увек.

Обриси

Обриси фокусираних елемената су начин на који прегледачи изворно комуницирају који елемент прима улаз. Подразумевани обриси су обично довољно истакнути да буду корисни сваком кориснику, укључујући оне којима је потребан висок контраст. Подразумевани обрис се обично преписује (или уклања), јер се не уклапа у дизајн веб локације. Ако не замените фокусирани outlineстил неким другим истакнутим и доступним индикатором фокуса, немојте уклањати или поништити својство обриса .

Фокус и показивач

Као што је горе поменуто, пазите да мењате :focusстил јер делује као индикатор за који елемент тренутно прима улаз. Додавање стилова елементу на :hoverчесто је леп додир, али немојте користити тај псеудо-селектор да бисте приказали додатну копију, осим ако то не учините за :focus(и, наравно, ако је елемент фокусиран ). Обично је, али не увек, добра идеја користити :hoverи :focusпсеудо-селекторе за исти скуп правила. (Додавање :focusбирача стиловима лебдења дугмета може резултирати притиском на дугме које изгледа „заглављено“.)

Непрозирност

Постављање opacityелемента на њега 0заправо не скрива од алата за приступачност. Елемент и даље заузима место у току документа и читачи екрана и даље читају његову копију. Једина два случаја употребе која оправдано захтевају употребу opacityсвојства су приликом преласка елемента у приказ (брзи прелаз из 0у 1) и приликом обликовања прекривача дијалога (тако да је садржај у наставку донекле видљив). Пазите се "наслаганих" полупровидних прекривача. Ниво непрозирности је мултипликативан, па је садржај испод два прекривача, сваки са opacity: 50%, приказан као да је испод једног елемента са opacity: 25%.

Селектори

Придржавајте се коришћења селектора класе и класе. Коришћење ид-а, типа и универзалних селектора долази са главобољом. У специфичности ЦСС-а, селектори ИД-а увек ће победити било који други селектор, али idатрибути би требало да буду јединствени (по страници), тако да нису корисни за примену стилова за вишекратну употребу.

Перформансе селектора у модерним прегледачима су занемарљива брига, па упркос ономе што сте можда чули о томе да универзални селектор ( *) не ради, моја стварна брига око његове употребе је да је превише уопштен за скоро сваки случај употребе. Коришћење неког селектора попут .my-class >; * на крају ће довести до искључивања неког детета, па бисте могли додати и часове елементима које желите да обликујете и директно их циљати.

Сличан аргумент може бити без употребе типа селекторе, као div, main. Они имају тенденцију да се подударају са превише елемената и обично захтевају више детаља да би били корисни, као што је div.some-class. Овакви сложени селектори имају већу специфичност од селектора једне класе, проблем стварања грешака адресиран у наставку.

Придржавајте се селектора класе ( .class), атрибута ( [attribute]) и псеудо-класе ( :focus). Сви они имају исти ниво специфичности.

Специфичност

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.

У наставку су наведени неки додаци у датотеку за ресетовање. Не волим да укључујем .hiddenатомску класу у свој ЦСС, јер постоји боља опција која ће радити чак и ако се ЦСС не учита - hiddenатрибут. Подразумевано понашање прегледача при подешавању display: noneскривених елемената може се пребрисати, чак и случајно, па укључујем правило за његово спровођење.

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;}
Мој ресет: //гитхуб.цом/НицкГард/цсс-утилс/блоб/мастер/ресет.цсс

Још један услужни програм који често сматрам потребним је visually-hiddenкласа. Иако aria-labelчешће користим за невидљиви текст читљив на екрану, обично негде уврстим следеће правило:

/* //a11yproject.com/posts/how-to-hide-content/ */.visually-hidden { position: absolute !important; height: 1px; width: 1px; overflow: hidden; clip: rect(1px, 1px, 1px, 1px);}

БЕМисх именовање

Не могу да завршим овај чланак без бар једног коментара на конвенције именовања. Свиђа ми се БЕМ именовање јер добро чита. /> 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.