# Как писать CSS Чтобы сделать хороший CSS, нужно выполнить несколько условий. ## Модульность Мы хотим писать стили в разных файлах, а браузер должен скачивать только один, склеенный. В JS это называется “бандл” (bundle), в CSS тоже. Любой CSS-препроцессор умеет это делать, о них ниже. ## Обфускация, оптимизация, сжатие Чтобы уменьшить размер файла, который будет качать браузер. Чтобы из такого: ```css h1::before { margin: 10px 20px 10px 20px; color: red; font-weight: 400; background-position: bottom right; quotes: '«' "»"; background: linear-gradient(to bottom, #ffe500 0%, #ffe500 50%, #121 50%, #121 100%); min-width: initial; } @charset "utf-8"; ``` Получилось такое: ` @charset "utf-8";h1:before{margin:10px 20px;color:red;font-weight:400;background-position:100% 100%;quotes:"«" "»";background:linear-gradient(180deg,#ffe500,#ffe500 50%,#121 0,#121);min-width:0} ` С этим лучше всего справляется [CSSNano](https://cssnano.co/). Вот бенчмарки: [goalsmashers.github.io/css-minification-benchmark](https://goalsmashers.github.io/css-minification-benchmark/). ## Autoprefixer должен расставить вендорные префиксы А не ты. Некоторые свойства до сих пор нужно повторять через префиксы типа `-webkit-backdrop-filter` Вот [статья про них по состоянию на 2021 год](https://css-tricks.com/is-vendor-prefixing-dead/). ## Тебе должно быть удобно Если любишь синтаксический сахар — не стоит себе в нём отказывать. Если любишь писать сложный, громоздкий код, управлять каждой мелочью, выносить всё в переменные и функции — инструментарий должен это позволять сделать. Если ты решаешь какую-то специфичкскую и сложную задачу — инструментарий должен тебе в этом помогать. # На чём писать Сами по себе языки, на которых можно писать стили, называются препроцессорами, потому что они буквально преобразуют один текст в другой. Например, вот такой код: ```sass .link background-color: hsl(217, 91%, 60%) &:hover background-color: hsl(217, 91%, 80%) ``` С помощью Sass превращается вот в такой: ```css .link { background-color: hsl(217, 91%, 60%); } .link:hover { background-color: hsl(217, 91%, 80%); } ``` Спешу напомнить, как всё называется: ```css селектор { свойство: значение; } ``` ## Препроцессоры: Sass, Less, Stylus У разных CSS-препроцессоров немного разный синтаксис, но всё склоняется к довольно простым возможностям. Сейчас есть три основных препроцессора, вот они слева направо: #### Sass Самый известный, имеет два синтаксиса: `.scss` в стиле CSS и “сахарный” `.sass` на табах. Можно импортировать между ними. #### Less У него довольно интересная идеология в стиле “сделаем очень похоже на CSS”, из-за этого там не очень с циклами и вообще синтаксис довольно странный. Но зато он работает прямо в браузере. #### Stylus Самый панковый препроцессор. Можно писать в стиле CSS, можно в стиле `.sass` на табах, можно даже двоеточие не писать между свойством и значением. Можно даже скопировать откуда-нибудь сломанный CSS и он его схавает. ### 1. Склеивать несколько файлов стилей в один `@import components/style` — Sass `@import 'components/style'` — SCSS `@import 'components/style.less'` — Less `@require 'components/style'` — Stylus Там, где ты это напишешь, в CSS будет содержимое упомянутого файла. ### 2. Статические переменные Когда все эти инструменты создавались, в CSS ещё не было возможности написать `color: var(--my-color)`, чтобы установить цвет, записанный как `--my-color: lightblue`. Поэтому препроцессоры сделали это сами: `$my-color: lightblue` — Sass / SCSS `@my-color: lightblue` — Less `my-color = lightblue` — Stylus ### 3. Переиспользуемый код: миксины и примеси Иногда код хочется использовать несколько раз в разных местах, немного поменяв его в паре мест. В препроцессорах есть функции и миксины (“mixin”, некоторые называют это “примесь”). #### Миксины Нужны для того, чтобы переиспользовать одно или несколько свойств сразу. Sass: ```sass =setColor($color, $bg) color: $color background-color: $bg .card +setColor(darkgray, lightblue) ``` SCSS: ```sсss @mixin setColor($color, $bg) { color: $color; background-color: $bg; } .card { @include setColor(darkgray, lightblue) } ``` Less: ```less .setColor(@color, @bg) { color: @color; background-color: @bg; } .card { .setColor(darkgray, lightblue) } ``` Stylus: ```styl setColor(color, bg) color color background-color bg .card setColor(darkgray, lightblue) ``` Все примеры кода выведут один и тот же CSS: ```css .card { color: darkgray; background-color: lightblue; } ``` ### Функции Нужны, когда надо переиспользовать только значение свойства. Sass: ```sass @function gradient($from, $to) @return linear-gradient(to bottom, $from 10%, $to 90%) .red-to-white background-image: gradient(red, white) .green-to-black background-image: gradient(green, black) ``` SCSS: ```scss @function gradient($from, $to) { @return linear-gradient(to bottom, $from 10%, $to 90%); } .red-to-white { background-image: gradient(red, white); } .green-to-black { background-image: gradient(green, black); } ``` Less: ```scss .gradient(@from, @to) { @result linear-gradient(to bottom, @from 10%, @to 90%); } .red-to-white { background-image: .gradient(red, white)[@result]; } .green-to-black { background-image: .gradient(green, black)[@result]; } ``` Stylus: ```styl gradient(from, to) linear-gradient(to bottom, from 10%, to 90%) .red-to-white background-image gradient(red, white) .green-to-black background-image gradient(green, black) ``` Все примеры выше выведут одинаковый CSS: ```css .red-to-white { background-image: linear-gradient(to bottom, red 10%, white 90%); } .green-to-black { background-image: linear-gradient(to bottom, green 10%, black 90%) } ``` ## Пост-процессоры: PostCSS и иже с ним А есть ещё понятие “пост-процессоры”. Оно родилось, чтобы отличать их от препроцессоров, но довольно быстро PostCSS оброс такими инструментами, что разница сильно размылась: появились переменные, примеси, функции, циклы и так далее. Вообще, самое первое, зачем нужны пост-процессоры — это Autoprefixer. Он расставляет за вас вендорные префиксы, о которых говорилось ранее. Но есть и другие весьма интересные инструменты, например: - [`postcss-momentum-scrolling`](https://github.com/solversgroup/postcss-momentum-scrolling) исправляет проблему, когда на iOS ломается плавная прокрутка на элементах с `overflow: scroll` / `auto`. - [`postcss-image-set-polyfill`](https://github.com/SuperOl3g/postcss-image-set-polyfill) позволяет использовать `image-set` - [`postcss-easing-gradients`](https://github.com/larsenwork/postcss-easing-gradients) делает градиенты мягче и симпатичнее Но есть и крупные инструменты на PostCSS, с помощью которых можно вообще отказаться от Sass / Less / Stylus в пользу, например, [CSSNext](https://cssnext.github.io/) — это набор PostCSS-плагинов, собранный для того, чтобы составить конкуренцию менее гибким препроцессорам, и писать CSS, соответвующий ранним черновикам спецификации, а на выходе получать рабочий в нынешних браузерах.