Статьи

Мой текущий CSS и Sass Styleguide

Никогда не легко найти способ написать последовательный, ориентированный на будущее и надежный CSS. Мне потребовались месяцы, если не годы, чтобы придумать чистый способ написать мой. На самом деле, мой процесс все еще развивается, и я ожидаю, что он изменится еще больше.

Тем временем я накопил достаточно знаний, чтобы написать статью о том, что я чувствую по поводу написания CSS. Я не утверждаю, что эти предложения для всех, и они, конечно, не идеальны. Но я подумал, что было бы неплохо поместить их в статью, чтобы поделиться ими с сообществом.

Соглашения об именах

Соглашения об именах являются командным решением. Если, как и я, вы работаете со своим CSS самостоятельно, вы можете сходить с ума и использовать то, что вам подходит. Лично я придерживаюсь методологии Николя Галлахера, которая находится под влиянием хорошо известной системы БЭМ Яндекса .

BEM расшифровывается как Block Element Modifier , умный и понятный способ назвать ваши CSS-классы. Да, я сказал, классы , а не идентификаторы . Я не использую идентификаторы в своем CSS, и вы не должны. Любые. Идентификаторы излишни и могут привести к проблемам специфичности Конечно, идентификаторы все еще очень полезны для хуков JavaScript и якорей HTML.

Смысл синтаксиса БЭМ заключается в предоставлении контекста непосредственно в селектор, чтобы сделать его легко понятным любому новичку в проекте.

Вот очень простой пример БЭМ:

.block { } .block--modifier { } .block__element { } .block__element--modifier { } 

Да, двойные черточки, двойные подчеркивания. Мы увидим почему через мгновение.

Итак, что случилось с БЭМ? Это выглядит долго и некрасиво. Ну да, это так! Но тот факт, что это долго и некрасиво, на самом деле делает его эффективным.

Основная идея проста: когда вы создаете компонент, вы даете ему имя. Дочерний элемент компонента будет назван так: .{{ name of component }}__{{ name of child-element }} . Когда элемент немного изменен, он будет назван .{{ name of component }}--{{ name of modifier }} . Конечно, дочерний элемент также может быть изменен.

Так что же с двойными тире и подчеркиванием? Ну, они позволяют использовать .my-component имена, такие как .my-component . Тогда вы можете прочитать .my-component--disabled без проблем. То же самое касается двойных подчеркиваний. Не беспокойтесь, вы привыкнете к этому очень быстро.

Поскольку нет ничего лучше, чем хороший старый пример, вот модуль пошагового мастера, который я написал на работе, используя систему имен BEM (которую вы можете найти в CodePen ):

 .steps { } .steps__item { } .steps__item--first { } .steps__item--last { } .steps__item--active { } .steps__item--done { } .steps__link { } 

Как видите, мы имеем дело с 3 различными элементами:

  • .steps который является оберткой модуля
  • .steps__item который является основным элементом модуля, так как он имеет как минимум 4 измененных состояния
  • .steps__link , еще один элемент в модуле

Это может показаться многословным, но я могу заверить вас, что с этим действительно приятно иметь дело, как только вы к этому привыкнете. Это очень наглядно и менее подвержено ошибкам и путанице.

Именование переменных

Были целые дебаты по поводу именования переменных Sass , особенно с участием цветов. Должны ли мы называть наши переменные как цвета, на которые они ссылаются, или мы должны называть их в соответствии с их назначением в проекте? В основном, с кем бы вы предпочли иметь дело?

 $blue: #4183c4; // Or $primary-color: #4183c4; 

Это действительно вопрос мнения. Я иду с обоими.

 $blue: #4183c4; $primary-color: $blue; 

Таким образом, у меня может быть куча классных переменных, таких как $blue-like-the-sky , $red-like-blood и $sexy-pink которые имеют больше смысла, чем шестнадцатеричные цвета и значимые переменные по всему проекту, чтобы определить, какой цвет предполагается использовать где (первичный здесь, вторичный там и так далее).

Примечание. Дефисы ( - ) и подчеркивания ( _ ) в Sass обрабатываются одинаково, поэтому $blue-like-the-sky и $blue_like_the_sky и ту же переменную.

Именование точек останова

Если вы еще не называете свои медиа-запросы, вам действительно следует это сделать. Это имеет огромное значение, когда приходится обновлять точку останова или читать какой-то код, который сильно зависит от разрешения экрана. Назвать точки останова так же просто, как использовать этот простой миксин:

 @mixin breakpoint($name) { @if $name == "small" { @media (max-width: 767px) { @content; } } @else if $name == "medium" { @media (max-width: 1024px) { @content; } } @else if $name == "large" { @media (min-width: 1025px) { @content; } } } 

Раньше я выбирал простую систему именования, такую ​​как: small , medium и large с возможностью добавления tiny или huge при необходимости. Это имеет большое преимущество, так как является очень простым для чтения и независимым от устройств, что не относится к таким phone , как phone , tablet и desktop , что больше не имеет смысла, так как у нас очень большие телефоны и планшеты и очень маленькие компьютерные экраны.

Но! Вы можете придумать что-нибудь более игривое, если хотите повеселиться, и ваша команда в порядке. Я все еще хожу с baby-bear , c3p0 и chewbacca от Криса Койера на моем собственном сайте, но почему бы не сделать что-то вроде r2d2 , c3p0 и chewbacca ? Более интересные примеры, подобные этим, можно найти в статье Криса.

Вкладки против пробелов

Это та тема, которая ведет к ядерной войне, поэтому я просто выскажу свое мнение о ситуации — не стесняйтесь думать иначе. Раньше я использовал только вкладки, но в итоге я переключился на пробелы. Два пробела .

Я не уверен, что есть много причин для этого, за исключением того, что я чувствую, что это подходит мне лучше всего. У него есть свои плюсы и минусы. Среди профессионалов это избегает линий, начинающихся в середине экрана из-за дополнительной вложенности.

Кроме того, основные редакторы не очень хорошо обрабатывают вкладки. Подумайте, например, об элементах textarea . Они позволяют вставлять пробелы, но не вкладки (если только вы не копируете и не вставляете откуда-либо еще, что не идеально). Пробелы поддерживаются везде. Отсюда мой выбор для первого.

Наборы правил CSS

Мне нравится, когда все чисто. Все мои наборы правил CSS написаны одинаково и соответствуют строгим (но стандартным) соглашениям. Вот пример:

 .selector, .other-selector { color: black; padding: .5em; font-size: 1.2em; } 

Ну, это не что иное, как основы, которые включают в себя:

  • Один селектор на строку
  • Один пробел перед открывающей фигурной скобкой
  • Разрыв строки после открывающей фигурной скобки
  • Последовательный отступ
  • Нет места перед двоеточием
  • Пробел после двоеточия
  • Нет места перед точкой с запятой
  • Разрыв строки после точки с запятой
  • Нет места до закрывающей фигурной скобки
  • Разрыв строки и пустая строка после закрывающей фигурной скобки

Некоторые примечания:

  • Я стараюсь избавиться от отступа 0 при работе с десятичными числами от 0 до 1 , поэтому число начинается с a . ;
  • Я стараюсь сделать цвета как можно короче, следуя этому порядку: ключевое слово> маленький шестнадцатеричный триплет> шестнадцатеричный триплет> rgb / hsl > rgba / hsla ,
  • Я избегаю магических чисел любой ценой (числа, которые не являются круглыми или не имеют смысла сами по себе),
  • Я не использую значения px (только em или rem если это позволяет поддержка браузера), за исключением случаев, когда оно равно единице ( 1px ); пиксели не масштабируются, это просто отстой.

Sass Stuff

То, что я только что пробежал — это довольно стандартные правила CSS. Теперь немного о Sass-специфичных вещах.

 .element { $scoped-variable: whatever; @extend .other-element; @include mixin($argument); property: value; &:pseudo { /* styles here */ } .nested { /* styles here */ } @include breakpoint($size) { /* styles here */ } } 

Различные элементы в наборе правил Sass располагаются в следующем порядке:

  1. Переменные области
  2. Расширения селектора с @extend
  3. Смешивать включения с @include за исключением медиа-запросов
  4. Обычное property: value пары property: value
  5. Псевдокласс / вложенность элементов с & после пустой строки
  6. Обычный вложенный селектор после пустой строки
  7. Медиа-запрос (с миксином или без)

Взяв наш пошаговый пример из предыдущего, вот как будет выглядеть реальный пример в приведенном выше порядке:

 .step__item { counter-increment: steps; /* 1 */ background: $step-background-color; float: left; padding: $step-baseline 0; position: relative; border-top: $step-border; border-bottom: $step-border; white-space: nowrap; &:after { @include size($step-arrow-size); @include absolute(top .3em left 100%); @include transform(rotate(45deg)); content: ''; z-index: 2; background: inherit; border-right: $step-border; border-top: $step-border; margin-left: -$step-arrow-size/2; } &[disabled] { cursor: not-allowed; } @media (max-width: 767px) { width: 100% !important; border-left: $step-border; border-right: $step-border; padding: $step-baseline*2 0; &:after { content: none; } } } 

Вложенность в Sass

Вложенность должна быть одной из самых противоречивых возможностей Sass или любого другого препроцессора CSS в этом отношении. Вложенность полезна — избегать повторения одного и того же селектора снова и снова — и опасна, потому что может привести к неожиданному CSS . Используйте вложение только тогда, когда вы это имеете в виду, а не только потому, что это удобно. Если вы имеете в виду .a .b , то вы можете написать .a { .b { } } . Если .b окажется внутри .a но этого достаточно, не вкладывайте его.

Начальный мем: нам нужно идти глубже

Могу поспорить, что вы видели фильм «Начало» . Отличный фильм, верно? Ну, вы знаете, как персонажи не могут идти глубже, чем сон во сне во сне, в противном случае они оказываются в неопределенности? Ну, вложение Sass такое же: не вкладывайте глубже, чем на 3 уровня. Когда-либо. Если вам нужно, это означает, что ваша разметка или ваш CSS написаны плохо. В любом случае, вы можете оказаться в «подвешенном состоянии», и, как мы видели в фильме, там не все так просто.

«Не вкладывайте глубже, чем на 3 уровня».
Кобб

Комментарии

Когда вы работаете с Sass, у вас есть два разных способа написания комментариев: хороший старый ‘ /* */ вы все хорошо знаете, и однострочный комментарий // , который не существует в простом CSS ( хотя вы можете обойтись это ). Разница между ними заключается в том, что однострочные комментарии не будут скомпилированы в результирующей таблице стилей. Вот почему однострочные комментарии называются «прозрачными комментариями» или «невидимыми комментариями». Между тем, обычные комментарии CSS будут в скомпилированном CSS, если вы не компилируете в compressed режиме (хотя вы должны это делать).

Что касается меня, я много комментирую. CSS это язык, полный трюков, хаков и грязных маленьких секретов. Я чувствую, что мне нужно комментировать, если я хочу, чтобы кто-то (даже я) понял код спустя месяцы, даже вещи, которые кажутся очевидными на момент написания кода.

 /** * Purpose of the selector or the rule set * 1. Hardware acceleration hack (http://davidwalsh.name/translate3d) * 2. Fallback for unsupported rgba */ .selector { @include transform(translate3d(0, 0, 0)); /* 1 */ background: black; /* 2 */ background: rgba(0, 0, 0, .5); } 

Я начну с небольшого описания набора правил, а затем перечислю крошечные детали, которые заслуживают объяснения. Числа затем сопоставляются с пронумерованными комментариями в конце правил CSS (например, /* 1 */ ).

В конце я не использую однострочные комментарии, ожидайте в расширениях Compass (например, SassyJSON ). Я начал это делать, когда понял, что регулярные комментарии CSS от моего первого расширения Compass SassyLists были выгружены в вывод CSS на Sassmeister .

Квазиквалифицированные селекторы с комментариями

Я полагаю, что идея использования комментариев, чтобы избежать отборочных отборщиков, пришла от Гарри Робертса .

Квалифицированные селекторы плохи по многим причинам, описанным в посте Гарри. Наиболее важными из них являются: они излишне завышены, они нарушают каскад, и их нельзя использовать повторно.

При этом, возможность сказать «этот класс должен применяться только к этому типу элемента» может быть полезной. Допустим, в какой-то момент вы используете CSS-преобразования и создаете запасной вариант для неподдерживаемых браузеров, используя Modernizr для определения поддержки. Вот как может выглядеть ваш код:

 .no-csstransforms .selector { /* Styles here */ } 

А что если вы хотите явно указать, что класс no-csstransforms предназначен для элемента html а не где-либо еще? Выполнение html.no-csstransforms сделает ваш селектор чрезмерно квалифицированным, и это не очень хорошая идея. Вы можете использовать обычный комментарий над набором правил, чтобы сделать заметку, как мы видели в предыдущем разделе. Или вы можете попробовать квазиквалифицированные селекторы:

 /*html*/.no-csstransforms .selector { /* styles here */ } 

Вот и все: класс теперь явно предназначен для привязки к элементу html, не изменяя ваш селектор вообще и не нарушая ничего. Эта техника на первый взгляд может показаться очень странной, но к ней можно довольно быстро привыкнуть.

Последние мысли

Как уже упоминалось, вы можете не чувствовать себя комфортно, используя все эти правила. И я не ожидаю, что вы. Важно то, что вы и ваша команда можете прочитать код друг друга и легко его обновить.

Вероятно, лучшее, что вы можете сделать с этим постом, — это принять эти предложения и сделать их своими, добавив свой собственный вкус к ним, чтобы улучшить свой рабочий процесс.

Если вы разработали свои собственные методы для любой из этих областей Sass и CSS, мы будем рады услышать их в комментариях.