---
# System prepended metadata

title: Как писать CSS

---


# Как писать 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, соответвующий ранним черновикам спецификации, а на выходе получать рабочий в нынешних браузерах.
