Никогда не легко найти способ написать последовательный, ориентированный на будущее и надежный 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 располагаются в следующем порядке:
- Переменные области
- Расширения селектора с
@extend
- Смешивать включения с
@include
за исключением медиа-запросов - Обычное
property: value
парыproperty: value
- Псевдокласс / вложенность элементов с
&
после пустой строки - Обычный вложенный селектор после пустой строки
- Медиа-запрос (с миксином или без)
Взяв наш пошаговый пример из предыдущего, вот как будет выглядеть реальный пример в приведенном выше порядке:
.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, мы будем рады услышать их в комментариях.