CSS
Правильное каскадирование, анимации, книги для верстальщиков, разбор сложных моментов и полезных приёмов.

Кроссбраузерная вёрстка
Что такое кроссбраузерная вёрстка, — спрашивают Илья, Сергей и Эдуард, — какие есть браузеры и нужен ли пиксель-пёрфект?
Если собрать охапку современных браузеров, то разложить её можно по-разному: по устройствам, по платформам, по типу работы, да хоть по цвету иконок. Самое полезное для разработчика — уметь разложить их по движкам. Именно движок, то есть самое ядро браузера, определяет как он работает с вашей вёрсткой.
При всём разнообразии браузеров, независимых движков довольно мало, а новые появляются очень редко. Так что вместо десятков браузеров вам нужно поддерживать не больше пяти независимых движков. А ещё бывает, что браузеры с одним названием используют разные движки на разных платформах! В общем, всё очень сложно и интересно.
Самый популярный в мире браузерный движок — это Blink. Его использует Chrome и браузеры на его основе: Opera, Samsung Internet, Яндекс.Браузер и другие. Для работы с JavaScript, эти браузеры используют движок V8 — тот же, что и в Node.js. Один из главных разработчиков открытого движка Blink — Google, но в разработке активно участвует не меньше десятка компаний.
WebKit, другой популярный движок, очень похож на Blink. А вообще, наоборот — это Blink похож на WebKit. Это как? В 2013 году Blink форкнули из WebKit. По сути, скопировали. Google собрала вещи и сказала Apple, основному разработчику WebKit, что ей не нравятся её методы работы и теперь всё будет по-другому. Что поделать, опенсорс. И действительно, стало по-другому: основа у WebKit и Blink общая (префиксы webkit, например), но возможности уже довольно разные. На новом WebKit сейчас работают мобильные и десктопные браузеры Safari, на старом — встроенный браузер на Android до версии KitKat.
На движке Gecko работает браузер Firefox, когда-то очень популярный, а сегодня сохраняющий небольшую долю и важную роль в развитии веба и технологий. Префиксы у Gecko свои: moz — Mozilla, но для лучшей совместимости Firefox специально поддерживает некоторые свойства WebKit. Полноценный Firefox на Gecko работает на десктопных платформах и на Android. Параллельно с Gecko, Mozilla разрабатывает экспериментальный движок Servo и меняет некоторые части Gecko прямо на ходу. Например, в следующем Firefox 57 движок CSS заменят на новый.
Браузер Edge работает на всех современных платформах Microsoft, включая мобильные и Xbox. В его основе движок EdgeHTML — недавно как раз вышла его 16-я версия. EdgeHTML тоже форкнули от движка Trident или MSHTML, на котором работал браузер Internet Explorer. Удивительно похоже на историю Blink и WebKit: оба движка сохраняют общие префиксы (ms и опять немного webkit для совместимости), но сильно отличаются по возможностям. EdgeHTML отбросил всякое старьё и смело развивается: пара крупных релизов в год и даже система голосования за фичи. Trident и IE закрыли в 2015 году.
Кроме движков, полезно ещё знать особенности платформ. Например, на мобильной платформе iOS куча браузеров, помимо встроенного Safari: Chrome, Firefox, Opera, Яндекс, UC и даже Edge недавно выпустили. Но все эти браузеры — просто оболочки над встроенным в систему движком WebKit. Правила этой платформы запрещают использовать другие браузерные движки. А вот на Android большинство браузеров поставляются со своими движками: Firefox, Opera, Samsung, но некоторые используют встроенный Chromium.
Ну вроде всё? А нет! Есть ещё отдельная группа необычных браузеров: они живут не на устройствах пользователей, а глубоко на серверах. На устройствах стоит только лёгкая оболочка, которая запрашивает адрес и получает с сервера набор скриншотов и ссылок, слепленных в сайт. Это прокси-браузеры и они безумно сжимают трафик, но по пути теряют: фирменные шрифты, фоновые картинки, градиенты, скруглённые уголки, тени и вроде того. Opera Mini — один из самых популярных прокси-браузеров. На сервере у него крутится устаревший движок Presto, а ставят его чаще всего на простые телефоны. Но есть и другие, подробнее вам расскажет Тим Кадлек.
Некоторые браузеры работают только на одной платформе: Edge и IE есть только на Windows, Safari только на macOS и iOS. Были когда-то попытки интервенций, но ничего не вышло. Это конечно усложняет тестирование. К счастью, есть сервисы вроде BrowserStack, которые дают вам доступ ко всем существующим браузерам, а Microsoft выкладывает компактные образы Windows для тестирования Edge и IE в виртуальных машинах.
Ладно! Про браузеры мы теперь знаем. А что делать, если тот же браузер, тот же движок — а результат на разных платформах разный? А ничего не поделаешь! На деле браузеры могут сильно отличаться в зависимости от платформы или устройства. Самая большая разница между десктопными и мобильными браузерами — в последних очень много оптимизаций и просто магии. Но можно поймать и разное поведение на десктопных Windows и macOS.
Думаю, вы уже поняли, к чему я клоню. Кроссбраузерность — это такой радужный единорог, за которым все гоняются, но никто не может поймать. Цель у погони, безусловно, благородная: чтобы сайты выглядели и работали одинаково хорошо на всех браузерах и всех платформах. И если размеры отступов, шрифта, высоту строки, цвета мы ещё можем более-менее гарантировать, то сглаживание текста, размытие теней, рендеринг графики и внешний вид системных контролов лучше даже не пытаться привести к общему виду.
Так что если для вас пиксель-пёрфект — это попасть в сетку и в горизонтальные размеры блоков, то у вас ещё есть шансы. Но если вы подкручиваете сглаживание текста, количество строк в абзаце или вертикальные размеры блоков с содержимым, строго по макету, вы тратите время впустую. Идеально кроссбраузерный сайт будет выглядеть одинаково чужеродно на всех платформах — ведь у каждой свои особенности, привычные пользователям.
И ещё про тестирование. Как бы хорошо ни имитировал устройства и браузеры эмулятор Chrome DevTools — это только намёк на то, как они будут выглядеть в реальности. Важно проверить результат на настоящих платформах и устройствах, как минимум: на Windows, Android, macOS и iOS. Настоящие пальцы на настоящем устройстве, настоящие браузеры в естественной среде обитания расскажут вам много нового о том, как именно будут пользоваться вашими интерфейсами. Это гораздо важнее того, насколько они похожи на макет.
Подпишитесь на новости браузеров в Твиттере, поставьте себе Chrome Canary, Firefox Nightly, Safari Technology Preview. Включайте флаги, пробуйте, будьте в курсе и главное — хватит гоняться за пикселями, займитесь хорошими интерфейсами. Сайты не должны выглядеть одинаково во всех браузерах.
- 3 ноября 2017

Адаптивная вёрстка
В чём разница между резиновой, адаптивной и отзывчивой вёрсткой? — спрашивают наши зрители Екатерина и Константин — как правильно их применять? Давайте разберёмся в отличиях подходов и попробуем сформулировать один общий вместо трёх.
Когда мобильного веба не было даже в самых смелых фантазиях, весь интернет был на десктопных компьютерах с небольшими экранами. Оптимизирован для разрешения 1024 на 768 и браузера Internet Explorer 5! — гордо писали тогда на сайтах. Но прошло время, экраны подросли и пришлось к этому как-то подстраиваться. Сначала это были просто резиновые таблицы: колонки по 25%, содержимое 50%, а в отдельной строке colspan=3 и распорка для минимальной ширины. Надеюсь, вы не поняли о чём я сечас говорил.
- 26 июля 2017

Нормальный сброс. Normalize
Расскажите про ресеты и нормалайзы, что лучше использовать? — просят наши зрители Андрей, Сергей и Юрий. Знаете, это как отвёртка и молоток — что лучше? Все хороши. Давайте копнём глубже — к самой сути проблемы, которую они по-разному решают.
HTML хорош тем, что вы набросали тегов и всё — они сразу выглядят. И во всех браузерах всё примерно одинаково: чёрным Таймсом по белому body, да с синими ссылками. Эх, красота! Но в том и дело, что почти: точные стили для всех элементов хоть и рекомендованы сегодня в HTML5, но в каждом браузере свои.
В HTML 4 было всего 78 строк стилей по умолчанию, вроде head { display: none } или text-decoration: underline для ссылок. В WebKit, Chrome и Firefox сегодня около 1000 строк стилей, в которые смело можно снаряжать археологическую экспедицию. Но мы не будем, у нас и так дел хватает.
/* html.css */
HTML 4: 78;
Chrome: 1123;
Firefox: 907;
Разработчикам долго не мешало это примерное соответствие стилей, к тому же браузеры старались их изредка улучшать и унифицировать. Проблема была в другом: все эти отступы, рамки, подчёркивания всегда не по дизайну и приходится их снова и снова отменять для каждого элемента. Но потом кто-то придумал ластик, первый сброс стилей.
Звёздочка выбирает все элементы, а дальше начинается: margin: 0, padding: 0, border: 0, Джофри, Серсея, Фрей и все остальные свойства, которые мешают вам жить. Способ довольно варварский: не только потому, что выбирает элементы, которым ничего не нужно сбрасывать, но и потому, что некоторые стили лучше не трогать, иначе всё развалится — например, элементы форм.
* {
margin: 0;
padding: 0;
border: 0;
joffrey: kill;
cersei: kill;
frey: kill;
}
/* ORLY? */
div , span {
margin: 0;
padding: 0;
border: 0;
}
Следующей попыткой сделать из HTML стерильный набор кубиков, стал CSS Reset из Yahoo UI, который сбрасывал стили только там, где это было нужно. Ещё большую популярность получил Reset CSS Эрика Мейера, сделанный по мотивам Yahoo UI. Эти ресеты не только сбрасывали отступы, но и приводили к единому значению размер и семейство шрифта, выравнивание для текста и другие свойства.
Между ресетами Yahoo и Мейера были различия: Эрик, например, разумно не трогал элементы форм. Было много других решений, но все они решали единую задачу — сделать из сложных стилей по умолчанию простой констуктор, чтобы вы сразу могли писать свои стили, не сбрасывая встроенные.
Эти ресеты никогда не были чистыми сбросами браузерных стилей: нет-нет, да назначались цвета, выравнивание, начиналась борьба за кроссбраузерность. В итоге все проекты несли печать предпочтений конкретных авторов. Самым нейтральным из ресетов до сих пор остаётся Reset CSS Мейера, но даже он убрал вредный: focus { outline: 0 } — и правильно сделал.
/* YUI Reset */
html {
color: #000;
background: #FFF;
}
select {
*font-size:100%;
}
/* Не забыть
вернуть обводку */
:focus {
outline: 0;
}
/* Забыл */
Многих ресеты раздражали: для внутренних блоков с содержимым приходилось восстанавливать стили не только для списков, но и базовых текстовых элементов вроде strong, em, code и других. У Yahoo даже был CSS Base, который назначал правильные базовые стили. После ресета, который отменял неправильные. Почему бы и нет.
Николас Галлахер и Джонатан Нил зашли с другой стороны: вместо того, чтобы сбрасывать примерно одинаковые браузерные умолчания, они подробно изучили все различия и проблемы — и сделали Normalize.css. Он делает везде одинаково и решает много проблем по пути.
С Normalize вам снова приходится убирать отступы со списков. Многих это провоцирует использовать элементы попроще, но будьте внимательны — это чревато диватозом. Зато Normalize берёт на себя сложности оформления элементов форм, поведение мобильных браузеров и много мелких багов.
Видите? Совсем другую задачу решает проект. Я на днях видел сайт, на котором после Normalize.css подключают Reset CSS, чтобы оставить нормализацию, но при этом получить нейтральный конструктор. Это конечно глупости, которые приводят к распуханию глобальных стилей. Уж лучше собрать свой гибрид — кода там всего ничего.
@import "normalize.css";
@import "reset.css";
@import "yui-reset.css";
@import "yui-base.css";
@import "h5bp.css";
Благо Normalize. css дотошно документирован: у каждого свойства стоит объяснение зачем оно нужно. В сомнительных местах, которые не нормализуют, а назначают более подходящие (по мнению авторов) умолчания — стоят пометки. Это помогает не просто слепо копировать его из проекта в проект, а использовать только нужные части.
Представьте, что вы в рамках проекта делаете модуль, который потом будет использоваться на другом сайте. У вас есть Normalize, а у них? Или наоборот: на ваш проект приходит сторонний модуль — а там нет Normalize и всё подогнано под браузерные баги, ну или особенности. Или даже есть Normalize, но другой версии. Так себе модульность получается.
А вот если бы вы сразу пошли в Normalize и скопировали нужные кусочки для каждой сложной ситуации — модуль бы вышел хороший, независимый. Normalize — это ещё и самая полная энциклопедия кроссбраузерных сложностей Да, это провоцирует лёгкое дублирование, но дарит гибкость — притом, что сжатие повторяющихся фрагментов — это хлеб с маслом для gzip.
Reset CSS не обновлялся с 2011 года, хотя до сих пор отлично работает. Но его эпоха уже прошла — на смену спешит новое свойство all со значением unset. Оно сбрасывает браузерные умолчания, где это нужно — почитайте на MDN. Normalize. css сейчас в моде и хорошо решает проблемы кроссбраузерности, но попробуйте использовать его как справочник. Ну так Reset или Normalize? Танцуйте от задачи.
/* Welcome to the */
.future {
all: initial;
all: inherit;
all: unset;
}
- 26 июля 2017

Кому нужны флексы
Кому нужны флексы, если на них не делают сайты? — спрашивает наш зритель Алексей. Ну, как не делают, Алексей: 12% сайтов уже используют флексы. А нужны они вам, чтобы было удобнее верстать. Давайте разберёмся.
Флексы, или Flexible Box Layout, с нами аж с 2006 года. Это получается одиннадцать лет! Их тогда внедрили в Mozilla для построения интерфейсов Firefox. Представьте себе, что вы настраиваете панель браузера: кнопочки разбегаются по краям, отталкиваются и ровно встают по горизонтали. Самый настоящий флексбокс. В 2009 году Mozilla предложила добавить эту систему в CSS.
С тех пор много чего случилось: тот самый первый флекс появился в Safari и других браузерах на WebKit. Вторая версия появилась в IE 10 в 2012 году. Флексы в текущем виде, с переносами flex-wrap, стали широко поддерживаться в 2014 году с выходом Firefox 28. Сейчас почти 98% браузеров по миру поддерживают флексбокс хоть какой-то версии. Даже Opera Mini на последнем вздохе движка Presto научилась флексам.
Зачем они вообще нужны? Это первая система раскладки в CSS, которая не хак. Таблицы, флоаты и инлайн-блоки придумали совсем для другого. Представьте три простых примера. Колонки одинаковой резиновой высоты: одна растёт по содержимому, другие идут за ней, что бы ни было. Или горизонтальный блок, внутри элементы распределены равномерно, сколько бы их ни было. Или блок произвольных размеров внутри родителя — ровно по центру.
Знаю, знаю — всё это можно имитировать десятком способов. CSS очень гибкий и кроме флоатов, инлайн-блоков и табличных свойств, можно применять хитрое позиционирование. Сам много лет это имитировал и набил руку на хаках и трюках. Но по-настоящему просто и явно это делает только флекс.
.center {
position: absolute;
top: 50%; left: 50%;
transform:
translate(
-50%, -50%
);
}
Что это вообще такое? Флекс — это такой контекст форматирования: вы задаёте родителю display: flex и его дети начинают подозрительно хорошо себя вести. Ещё есть старинный контекст display: table, когда блоки прикидываются внутренностями таблицы, и совсем новый — грид, ещё круче флекса. Гриды и флексы имеют кое-что общее и очень ценное.
Мало раскидать резиновые блоки, это можно сделать хоть на флоатах. Нужно ещё сказать, где они начинаются по главной оси, как делят пустое место внутри родителя и как выравниваются поперёк оси — во флексах ведь можно менять её направление. Этими вопросами занимается отдельная спецификация Box Alignment.
.flex {
display: flex;
justify-content:
space-between;
align-items:
stretch;
flex-direction:
column;
}
Флексы и гриды включают Box Alignment для своих детей и это то, чего нам всем очень не хватало. Когда-нибудь свойства justify-content, align-self, justify-items и другие заработают в других контекстах. Ведь до сих пор самый популярный вопрос по вёрстке — это как выровнять блок по вертикали. Проще всего это сделать на флексах.
Ладно, флексы классные, дайте две. Но почему тогда главные студии страны выпускают сайты для главных компаний страны, где всё по-прежнему на флоатах? А для надёжности иногда даже на таблицах. Варианта здесь два: либо им нужна поддержка IE 9, либо там работают упёртые староверы. У них всё и так работает на флоатах, зачем что-то менять?
Оставим консервативных верстальщиков в покое и разберёмся с браузерной поддержкой. Если вам нужны старые Android 4.3, iOS 6 или Firefox 27, то флексы у вас будут только в одной строке, без переносов: flex-wrap там ещё не работает. Сделать удобный список карточек одинаковой высоты, которые переносятся друг за другом по строкам, не получится.
В старых WebKit и в очень старом Firefox 21 поддерживается версия флексбокса 2009 года с немного другим синтаксисом, за префиксами -webkit и -moz. В IE 10 и 11 синтаксис уже ближе к современному и с поддержкой переносов, но за префиксом -ms. Если вы пишете современный флекс, а потом расставляете префиксы с помощью Автопрефиксера, то он вам добавит старых свойств, чтобы всё работало как нужно. Но никакой магии: переносы не заработают и баги никуда не денутся.
.flex {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
Про баги отдельно: в старых реализациях с префиксами в Firefox, Safari и IE багов хватает. Но все они более-менее описаны в коллекции Flexbugs Филипа Уолтона. Прежде всего, вам нужно определиться с браузерами, которые вы поддерживаете и может быть вместо старых флексов с префиксами просто отдать им флоаты?
Да, это самое приятное: вы можете сделать простую вёрстку на флоатах или в контексте table, а потом объявить display: flex и сделать ещё лучше для браузеров которые умеют флексы. Сайты не должны выглядеть одинаково во всех браузерах, что бы там ни требовали заказчики. Тем более в старых, где главная задача — сохранить доступное содержимое.
Флоаты придумали чтобы текст обтекал картинку и нашей вёрстке давно пора перестать куда-то плыть. Мы тоже переводим программу интенсивов HTML Академии на флексы — и вам рекомендуем. Уже можно.
- 21 июня 2017

Кастомные свойства
Зачем нужны кастомные свойства и как они работают? — спрашивает наш зритель Андрей. Они пришли, чтобы навсегда изменить CSS. Давайте разберёмся.
В языках программирования есть переменные: вы что-нибудь один раз объявляете, присваиваете значение, а потом снова и снова используете. Если значение переменной меняется, то меняется везде. Похоже на местоимения в языке: из предложения или абзаца всегда понятно, кто «мы» или что за «оно», мы их как будто объявили раньше и наверняка переопределим потом.
Но это языки программирования, а что со стилями? Вообще, декларативная природа CSS не подразумевает никаких переменных и соавтор CSS Берт Бос очень против, почитайте. Но жизнь внесла свои коррективы в изначальную идею, и переменные в стилях появились — слишком уж удобно было. Но сначала в препроцессорах.
Как вообще работают препроцессоры? Вы пишете на каком-то языке, который внешне напоминает CSS, а иногда вообще не напоминает.
@mixin sass
@if &
&:hover
color: tomato
@else
a
color: plum
Потом это компилируется в настоящие стили. Переменные там — это такая сложная автозамена переменных на их значения. Sass, Less, Stylus, PostCSS-плагины — все они работают только так. Эти переменные существуют только в разработке, в браузере их уже нет.
.scss {
$variable: value;
color: $variable;
}
Если сравнить такое поведение с JavaScript, то становится очень обидно за CSS. В JS переменные живут прямо в браузере, их можно создавать и менять на лету. Тем не менее такие переменные и другие элементы программирования в CSS-препроцессорах получили огромную популярность. Уже почти не бывает больших проектов без препроцессоров.
К счастью, нашлись люди, недовольные такими куцыми переменными. После ряда черновиков и вариаций синтаксиса, Таб Аткинс написал спецификацию полноценных CSS-переменных, точнее, кастомных свойств. Эти переменные поддерживаются уже в 70% браузеров по миру и сильно меняют принцип написания стилей.
Кастомные кто? Объясняю. Помните, я говорил, что CSS не очень-то готов к переменным? Чтобы сохранить синтаксическую совместимость со старыми браузерами и не противоречить модели языка, было решено сделать не просто переменные с долларом в начале, а механизм создания собственных свойств для нужд разработчика. Ещё их переводят как «пользовательские» свойства, но с этим возникает путаница: кто здесь пользователь, а кто здесь разработчик? Сразу скажу, синтаксис у них немножко странный, но вы поймёте почему.
Например, у нас сейчас есть свойство box-shadow, чтобы отбрасывать тень. А раньше его не было, оно появилось первым в браузере Safari в 2008 году. Но появилось не просто так, а как -webkit-box-shadow, с префиксом, начинающимся с дефиса. То есть разработчики движка WebKit придумали своё свойство. Только потом, когда оно стало частью стандарта и появилось в других браузерах, префикс убрали.
.shady {
-webkit-box-shadow:
0 0 0 4px tomato;
box-shadow:
0 0 0 4px tomato;
}
Теперь вы тоже можете создавать собственные свойства, только не нужно указывать между дефисами название движка: дефис, дефис, название свойства. Давайте создадим свойство --box-shadow-color и зададим ему значение tomato. Чтобы использовать это значение в коде, нужно передать его в функцию var().
.shady {
--box-shadow-color:
tomato;
box-shadow:
0 0 0 5px
var(--box-shadow-color);
}
Мы сейчас объявили новое свойство, которое потом можно повторно использовать снова и снова. А ещё свойства box-shadow-color никогда не было в природе и чтобы менять тени, например, по наведению, приходилось переписывать box-shadow целиком. А теперь по ховеру можно просто поменять значение переменной. Круто?
.shady {
--box-shadow-color:
tomato;
}
.shady:hover {
--box-shadow-color:
plum;
}
Если вы используете кастомное свойство, которое почему-то не было объявлено, то можно указать его значение по умолчанию, которое будет использовано в таком случае. Ваш компонент тогда можно будет настроить, но без настройки он не сломается.
.shady {
font-size:
var(
--font-size,
12px
);
}
Из-за того, что это кастомные свойства, а не просто доллары с автозаменой, они ведут себя как обычные свойства: наследуются вглубь для всех детей элемента и не видны между элементами-соседями. Чтобы переменную точно было видно во всём документе, её нужно задать самому корневому элементу html, но лучше даже :root, на случай если это корневой элемент svg.
:root {
--font-size: 12px;
--theme-color:
tomato;
}
Самое крутое, что переменные можно переопределять внутри медиавыражений. Например, если окно больше каких-то размеров, теперь не нужно копировать весь блок и менять его под новую ширину, достаточно поменять нужные кастомные свойства.
@media (min-width: 320px) {
.shady {
--font-size: 48px;
}
}
Кастомные свойства можно использовать даже внутри функции calc(), которая посчитает результат выражения внутри. Уже не очень похоже на привычный CSS, правда? Стоит ли говорить, что все препроцессоры уже умерли от зависти, глядя на такое.
.shady {
font-size:
calc(
var(--font-size)
* 2
);
}
Ещё кастомные свойства становятся идеальным транспортом для данных между скриптами и стилями. Например, вы можете динамически считать координаты мыши в JS и пробрасывать их в кастомные свойства через setProperty в нужный элемент.
element
.style
.setProperty(
'--pointer-left',
event.clientX
);
Дальше в стилях уже можно решить: использовать их в top и left или transform: translate(). И наоборот: значение свойства можно получить в JS с помощью getPropertyValue.
И это я только кастомные свойства лапкой потрогал, дальше ещё куча интересного, что кардинально меняет работу со стилями. Читайте и смотрите дальше сами: статьи, видео и слайды в описании.
Кастомные свойства — это не border-radius, который либо делает красиво, либо нет. Бросаться всё переделывать на них пока рано, вёрстка может сильно поломаться в браузерах, которые их не поддерживают. Но уже пришло время пробовать и уметь.
- 31 мая 2017

Зачем нужен БЭМ
Следуете ли вы БЭМу, и насколько он востребован вне Яндекса? — спрашивает наша ученица Евгения. Следуем, Евгения, и БЭМ вполне применим не только в Яндексе. Давайте разберёмся.
БЭМ расшифровывается как: блок, элемент, модификатор. Это такой набор абстракций, на который можно разбить интерфейс и разрабатывать всё в одних и тех же терминах. Как говорит сайт bem. info, БЭМ предлагает единые правила написания кода, помогает его масштабировать и повторно использовать, а также увеличивает производительность и упрощает командную работу.
Круто, да? Но зачем вам масштабируемость и командная работа, если вы один верстальщик на проекте, который не претендует на популярность Яндекса? Чтобы ответить на этот вопрос, нужно отмотать историю лет на 10 назад, когда это подход только начали формулировать.
В основу того, что мы сейчас называем БЭМом, легла идея независимых блоков, которую Виталий Харисов сформулировал и презентовал в 2007 году на первой российской конференции по фронтенду. Это было настолько давно, что тогда даже слова «фронтенд» ещё не было, тогда это называлось клиент-сайд.
Идея была в том, чтобы ограничить возможности CSS для более предсказуемых результатов. Использовать минимум глобальных стилей и каждый отдельный элемент страницы делать блоком со своим уникальным классом и стилями, которые полностью его описывают. Селекторы по элементам и ID, хрупкие связки вложенности — всё это заменялось на простые селекторы по классам. Каждый класс в стилях — это блок. Благодаря этому блоки можно легко менять местами, вкладывать друг в друга и не бояться конфликтов или влияния.
#menu ul > li {
color: old;
}
.menu-item {
color: bem;
}
Потом появились абсолютно независимые блоки (АНБ), где у элементов внутри есть свой префикс с именем родителя, а состояния блоков снова дублируют класс, но уже с постфиксом. Подход обрёл черты современного БЭМа, одна из которых — многословность классов.
.block
.block_mod
.block__element
.block__element_mod
Эта многословность гарантирует уникальность элементов и модификаторов в рамках одного проекта. За уникальностью имён блоков вы следите сами, но это довольно просто, если каждый блок описан в отдельном файле. Глядя на такой класс в HTML или CSS, можно легко сказать, что это, и к чему оно относится.
Изначально АНБ, а потом и БЭМ, решали задачу важную для вёрстки любых масштабов: предсказуемое поведение и создание надёжного конструктора. Вы же хотите, чтобы ваша вёрстка была предсказуемой? Вот и Яндекс тоже. Ещё это называется «модульность» — о ней хорошо написал Филип Уолтон в «Архитектуре CSS», ссылка на перевод в описании.
Через пару лет в Яндексе окончательно сформулировали нотацию БЭМ. Любой интерфейс предлагалось разделять на блоки. Неотделимые части блоков — элементы. У тех и других есть модификаторы.
<ul class="menu">
<li class="
menu__item">
</li>
<li class="
menu__item
menu__item_current">
</li>
</ul>
Например, блок поиска по сайту. Он может быть в шапке и в подвале — значит это блок. В нём есть обязательные части: поле поиска и кнопка «найти» — это его элементы. Если поле нужно растянуть на всю ширину, но только в шапке, то блоку или элементу, который отвечает за это растягивание, даётся модификатор.
Для полной независимости блоков мало назвать классы правильно или изолировать стили, нужно собрать всё, что к нему относится. В проекте по БЭМу нет общего script.js или папки images со всеми картинками сайта. В одной папке с каждым блоком лежит всё, что нужно для его работы. Это позволяет удобно добавлять, удалять и переносить блоки между проектами. Потом конечно все ресурсы блоков при сборке объединяются в зависимости от задач проекта.
Когда БЭМ вышел за пределы Яндекса, сначала его воспринимали как магию и старались воспроизводить дословно, вплоть до префиксов b- у каждого блока. Такой смешной карго-культ.
.b-block
.b-block--mod
.b-block__element
.b-block__element--mod
Некоторые неверно понимали идею и появлялись даже элементы элементов. Потом за нотацию взялись энтузиасты и появилась одна из самых популярных: блок отделяется двумя подчёркиваниями, а модификатор — двумя дефисами. Наглядно и просто — сам так пишу.
.block
.block--mod
.block__element
.block__element--mod
А зачем вообще все эти нотации — я ведь один верстальщик на проекте, помните? Помню. А ещё помню, как сам верстал до БЭМа: в каждом проекте придумывал что-нибудь такое новенькое. А потом открывал код годичной давности и удивлялся — какой идиот это написал?
Возьмём, к примеру, русский язык. Мы же пишем с прописной имена людей, названия и прочее такое? Пишем. Чтобы легко потом считывалось: это Надя или надежда на лучшее? Уж не говоря про знаки препинания и другие полезные договорённости. Вот буква ё, например смягчает... так, о чём мы? Да, БЭМ.
До БЭМа были проекты с портянками стилей, которые нельзя трогать. Они копились годами, слой за слоем, как обои в древней коммуналке. Их просто подключали первыми, а потом перезаписывали что мешало. Когда у вас есть div { font-size: 80% } — это даже уже не смешно.
/* Не смешно */
div {
font-size: 80%;
}
БЭМ продолжил развиваться в Яндексе и вырос за пределы вёрстки: появились уровни переопределения, богатый инструментарий, JS-библиотека для работы с БЭМ-классами, шаблонизаторы и целый БЭМ-стэк. БЭМу даже жест придумали, но это совсем другая история, специфичная для Яндекса.
Были и другие методологии: OOCSS Николь Салливан, SMACSS Джонатана Снука, вариации БЭМа и целые фреймворки. Даже у нас на продвинутом интенсиве HTML Академии можно было выбрать любую методологию для вёрстки учебного проекта.
Но выжил только БЭМ и его вполне можно назвать стандартом де-факто современной разработки интерефейсов. И что — это финальная ступень эволюции? Нет конечно. Как ни автоматизируй, многое в БЭМе приходится делать руками, и возможны конфликты.
Модульность и изоляцию стилей блока можно решить ещё лучше. Есть веб-компоненты, CSS-модули, куча решений CSS-в-JS и даже, прости господи, атомарный CSS. Но нет единого решения накопившихся проблем на следующие 10 лет, каким когда-то стал БЭМ. Что это будет? Посмотрим. Я ставлю на веб-компоненты.
А пока, если вы опишете интерфейс по БЭМу — код будет организован, предсказуем, расширяем и готов для повторного использования. Не только для вас, но и для других.
- 24 мая 2017

Сокращённые свойства
Зачем задавать картинку через background-image, если можно просто написать background? — спрашивает наш ученик Егор. Чтобы случайно не выстрелить себе в ногу. Давайте разберёмся.
CSS-свойство background — это сокращение целой группы свойств: background-color, image, attachment, position и других. Вместо того, чтобы писать целую батарею свойств, иногда бывает удобно просто задать background и описать всё в нём.
background-color
background-image
background-position
background-size
background-repeat
А ещё background просто короче: как вам при наборе, так и пользователю при загрузке ваших стилей с остальным сайтом. Ну, сплошные плюсы, давайте писать только сокращённые свойства! Шах и мат.
В целом, да: если вы пишете одну простую штучку, которой один раз задаёте фон, то проблем никаких. Но если вы уже начали мыслить модульно, комбинируете несколько классов на одном элементе или знаете что такое модификаторы для блоков — проблема есть.
Например, вы описали в классе first свойства фона в background, но специально не указали картинку. А потом классом second добавляете элементу картинку свойством background-image. И всё хорошо, картинка просто добавляется: first, second.
.first {
background:
red no-repeat;
}
.second {
background-image:
url(pic.png);
}
Но если наоборот: сначала background-image, а потом остальное в сокращённом свойстве background, то картинки уже не будет — она затрётся. Эх, каскад, беспощадная ты сволочь.
.second {
background-image:
url(pic.png);
}
.first {
background:
red no-repeat;
}
Подумаешь! — скажете вы, — я просто буду внимательнее и не допущу такого. Я в вас верю и наверняка всё будет хорошо. Но лучше сразу применять подходы, которые не допускают даже случайных ошибок, правильно? Все мы люди.
Если мы опишем свойства фона в обоих классах полными свойствами вместо сокращённых, то, как ни крути, классы — всё будет в порядке, они друг друга дополнят. А ещё это позволяет удобнее читать стили: порядок свойств в сокращённом свойстве background произвольный и все пишут как им нравится.
.first {
background-color: red;
background-repeat: no-repeat;
}
.second {
background-image: url(pic.png);
}
О похожем писал звезда фронтенда Гарри Робертс и прямо называл сокращённые свойства антипаттерном. Обязательно почитайте, все ссылки будут в описании к видео.
Есть много простых сокращённых свойств: font, list-style,border,padding, margin и другие. Но есть сложные или просто пока новые для вас — их проще понимать в отдельной записи.
Одно из самых моих любимых — свойство animation. Я долго не мог запомнить его синтаксис, пока однажды не решил записывать его всегда по частям: animation-name, duration, timing-function и так далее. И всё встало на свои места.
/* wat */
animation:
3s ease-in
1s 2 reverse both
paused slidein;
Та же история с сокращённым свойством flex: оно объединяет flex-grow, shrink и basis. И если вы иногда долго смотрите на какой-нибудь flex: 0 0 1 или силитесь понять эту магию, то просто запишите их отдельно и всё станет понятнее.
Запомните: сокращённые свойства удобно писать, но сложно комбинировать и понимать, поэтому пишите модульные стили или новые для вас свойства развёрнуто.
- 3 мая 2017

Свойство vertical-align
Это перевод статьи Ире Адеринокун «The vertical-align property»
Свойство vertical-align управляет вертикальным выравниванием элементов внутри своих родителей. Оно применяется к строчным элементам и к ячейкам таблиц. У него десять возможных значений:
baselinesubsupertext-toptext-bottommiddletopbottom- указание расстояния
- указание процентов
- 28 июня 2016

О normalize.css
Это перевод статьи Николаса Галахера — «About normalize.css»
Normalize.css — это небольшой CSS-файл, который обеспечивает для HTML-элементов лучшую кроссбраузерность в стилях по умолчанию. Это современная, готовая к HTML5 альтернатива традиционному reset.css.
- Normalize.css — сайт проекта
- Normalize.css — исходный код на GitHub
В настоящее время normalize.css используется в Twitter Bootstrap, HTML5 Boilerplate, GOV.UK, Rdio, CSS Tricks и во многих других фреймворках, инструментах и сайтах.
- 30 октября 2015
Принципы анимации для веба
Примечание переводчика: Представленный ниже материал содержит значительное количество технических терминов, при переводе которых могут возникнуть неточности. Если вы заметили опечатку, ошибку или неточность перевода — напишите нам, и мы оперативно всё исправим.
Кроме того, в продолжение темы сегодняшней публикации на одну неделю будет открыт продвинутый курс академии по CSS-анимациям, который обычно доступен по подписке. Его описание размещено в конце топика.
Фронтенд-дизайнеры и разработчики используют CSS для создания стилей, позиционирования элементов — в общем, для того, чтобы сайты выглядели красиво. Часто CSS применяют и для добавления движений на веб-страницы, хотя дело обычно не идёт дальше плавных переходов или анимации.
На самом деле анимация может быть мощным инструментом, который позволяет посетителям сайта и клиентам легче взаимодействовать с интерфейсом продукта и быстрее добиваться своих целей. Этого можно достичь, если следовать в своей работе некоторым основополагающим принципам.
Компания Disney занимается анимацией уже много лет и выработала такие рекомендации — ещё в 1981 была опубликована книга «Иллюзия жизни: Анимация Disney» («The Illusion of Life: Disney Animation»), в которой перечислялись 12 принципов анимации. Они описывают то, как использовать анимацию для создания у зрителей, смотрящих на экран, ощущения реального мира.
В сегодняшней статьей мы рассмотрим каждый из двенадцати этих принципов и обсудим их возможное применение при создании веб-страниц. Все исходники CSS и HTML можно скачать на Codepen.
- 13 апреля 2015