frontend-разработчик. Фотографирую в инстаграме, готовлю и пишу тексты. Всё написанное не отражает мнения работодателя. 18+

2 заметки с тегом учебник

Подборка полезностей

Здесь список статей на тему frontend-разработки, которые помогают мне работать и, возможно, помогут вам.

Модифицировать и положить на место

Если вы пишете много кода, то однажды обнаружите, что вы постоянно делаете одно и то же. Те же самые куски переписываются, тратят время. Если работаете в команде, то работа вашего коллеги может вызвать неудобные зависимости.

Чтобы этого избежать, стоит определить общие правила и их придерживаться.

В Яндексе продвигают методологию БЭМ, но ей пользуются не только там.

Я попробовал, разобрался и мне понравилось.

По БЭМ весь ваш код делится на три части: блок элемент и модификатор.

Приведу аналогию:

  • у вас есть полка. Полку можно поставить в любое место и она всегда останется полкой.
  • у вас есть книга. Книга останется книгой и на полке и у вас в руках. Это тоже блок.
  • если вы поставите книгу на полку, то книга станет элементом полки с книгами.
  • а если вы поместите книгу в суперобложку, то она будет выделяться, и станет блоком с модификатором.

Больше всего вопросов вызывают следующие вещи:

  • у вас есть несколько блоков, как их расположить относительно друг друга, если описывать положение в стилях блока нельзя?
  • как сделать файловую структуру?
  • модификатор не изменяет значение родительского блока, если создать правильную файловую структуру!!!

Разберёмся по очереди.

Как поместить один блок в другой

Блок действительно не должен влиять на своё положение в пространстве.

Согласитесь, если бы ваша полка говорила: «я стою у окна» — то вы не смогли бы поставить её в другое место, и блок потерял бы главное свойство блока в методологии БЭМ: свою универсальность.

Поэтому блок управляет только внутренними элементами и своими размерами. А если вы привезли в квартиру полку, которая не помещается: надо было думать при покупке.

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

Посмотрим на код на примере полки на книге.


<div class="shelf">
     <div class="shelf__book book"></div>
</div>

Теперь книга это и блок сам по себе, и элемент родительского блока. Если посмотрите внимательно, то .book — это класс обозначающий стили блока «книга», а .shelf__book — это описание, где книга лежит на полке, как элемент «полки». Такое использование двух классов вместе называется миксами. А правила такого расположения написаны в официальной документации.

Как сделать файловую структуру

Если вы делаете проект по БЭМ и хотите получить один стиль, вы всегда можете взять кусок кода из одной страницы или с одного своего сайта и вставить в другой. Ничего не сломается.

Чтобы вы не искали код в длинном CSS-файле, frontend-разработчики, которые выбрали БЭМ, помещают каждое описание классов: блоков, элементов, модификаторов — в отдельные файлы и папки.

Выглядеть ваш сайт будет следующим образом:



src
 blocks
  shelf
   __book
    shelf__book.css
   _library
    shelf_library.css
   _kitchen
    shelf_kitchen.css
  shelf.css
  book
   _red
    book_red.css
   book.css
 pages
  index
   index.html
   index.css
   index.js

Внутри всё это дело подключается через @import url();, поэтому файл index.css выглядел бы так:


@import url(../../blocks/shelf.css);
@import url(../../blocks/book.css);

/* тут можно указать какие-то глобальные стили, но по правилам БЭМ. Например, задать шрифт странице */

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

Поэтому модификаторы элементов подключаются в корневых *.css-файлах элементов.

Создать подобную структуру, конечно, занимает время, но задачу можно легко решить при помощи терминала. Если у вас macOS или Linux, устанавливать ничего не надо: Git Bash уже установлен в системе, а если вы работаете под Windows, стоит зайти по ссылке и скачать файл.

После этого вы сможете через простое перечисление создать нужную структуру.


$ mkdir src #создали папки
$ mkdir src/blocks src/pages
$ touch src/pages/index.html src/pages/index.css src/pages/index.js #создали файлы
$ cd src/blocks #зашли в папку
$ mkdir shelf book
$ mkdir shelf/_library shelf/_kitchen shelf/__book book/_red
$ touch shelf/_library/shelf_library.css shelf/_kitchen/shelf_kitchen.css shelf/__book/shelf__book.css shelf/shelf.css book/_red/bookd_red.css book/book.css

Повторять команду можно переходя по стрелочке вверх. А после того, как вся структура будет собрана, останется только добавить подключения дочерних файлов и всё заработает.

Модификатор не изменяет значения родительского блока

Это происходит потому, что у модификатора не хватает «веса», а подключается он, как и положено, в начале страницы, поэтому родительский класс его переписывает. Подробнее про специфичность есть в статье.

Исправить эту вещь можно двумя способами:

Добавить «вес»

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

Если у нас все книги синие, и только одна в красной супер-обложке, то запишем код:


/* файл book_red.css*/
.book.book_red {
    color: red;
}


/* файл book.css*/
@import url(_red/book_red.css);
.book {
    color: blue;
}

То же самое будет справедливо, если вы хотите «усилить» элемент блока. Ведь элемент не может использоваться в отрыве от блока.


/* файл shelf__book.css*/
.shelf .shelf__book {
    margin-right: 10px;
}


/* файл shelf.css*/
@import url(__book/shelf__book.css);
.shelf {
    margin: 0;
}

Тут стоит быть внимательным и «усиливать» элементы только родительским блоком. С чужим блоком такой фокус не пройдет.

На самом деле, этот способ не совсем корректный и применяется только в виде исключения из правил. Правильно делать так:

Не указывайте свойства, которые могут измениться

Вернёмся к книгам. У нас есть книги одинакового размера и формы, но разного цвета. Все синие и одна красная. Правильная запись в таком случае будет выглядеть так:


/* файл book_red.css*/
.book_red {
    color: red;
}


/* файл book_blue.css*/
.book_blue {
    color: blue;
}


/* файл book.css*/
@import url(_red/book_red.css);
@import url(_blue/book_blue.css);
.book {
    width: 200px;
    height: 400px;
}


/* файл index.html*/
<div class="shelf">
    <div class="book book_blue"></div>
    <div class="book book_red"></div>
    <div class="book book_blue"></div>
</div>

Немного более загруженный *.html-файл, но всё работает так, как нужно.

1 мес   bash   css   html   БЭМ   код   учебник

Специфичность в CSS

Ваш HTML-код состоит из множества «элементов»:

  • Селекторов <header>
  • Классов .header
  • ID #header
  • Атрибутов [attr=value]
  • Псевдоэлементов ::after
  • Псевдоклассов :first-child
  • и многих других... —

каждый из них называется «селектор», и его внешний вид в вашем готовом HTML-файле определяется тем, какие стили будут даны ему в самом HTML-файле (styles у «селектора» или внутри кода <styles> на странице) или в подключенных к нему CSS-файлах.

Способ, с помощью которого браузер будет определять как выглядит «селектор» на странице называется «специфичность».

Правило первое

Код ниже имеет больший приоритет при равном «весе» всех элементов страницы

Допустим, что у вас есть такой код на странице


.first {color: red}
.second {color: green}


<p class="first">Первый абзац</p>
<p class="second">Второй абзац</p>
<p class="first second">Третий абзац</p>

Получаем следующий результат:



Первый абзац
Второй абзац
Третий абзац

Первый абзац стал красным потому, что у него один класс, браузер обратился к этому классу и получил его цвет. Второй стал зелёным по тому же принципу. Смотрим на третий абзац. Он стал зеленым, потому что браузер читает код всегда сверху вниз. Он смотрит, так, вот третий абзац с классом first — класс требует покрасить текст в красный, красим. Читаем дальше, этот же селектор имеет класс second — класс требует покрасить текст в красный, красим. Последним изменением будет применение второго класса в CSS-файле, браузер сделает изменения ещё во время загрузки, так что вы увидите уже готовый вариант.

Правило второе

Стиль каждого селектора имеет свой «вес». Чем больше «вес», тем более приоритетен стиль для селектора.

«Вес» селектора традиционно показывается в виде числа 0.0.0.0. Когда мы пишем определённые стилевые правила для наших элементов страницы, мы изменяем это число.


p {color: #5D4037}


<p class="first">Первый абзац</p>
<p class="second">Второй абзац</p>
<p class="first second">Третий абзац</p>

Выглядеть результат будет так:



Первый абзац
Второй абзац
Третий абзац

Все абзацы стали коричневыми потому, что мы изменили число «веса». В случае с «селектором» мы изменили самое правое число. Оно стало 0.0.0.1

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


.first {color: red}
.second {color: green}
p {color: #5D4037}


<p class="first">Первый абзац</p>
<p class="second">Второй абзац</p>
<p class="first second">Третий абзац</p>

Получаем следующий результат:



Первый абзац
Второй абзац
Третий абзац

Добавляя класс, мы меняем второе число справа в порядке 0.0.1.1. Стоит понимать, что 0.0.1.1 > 0.0.0.1, поэтому первый абзац стал красным, второй и третий зелеными (почему это произошло в третьем, посмотри первое правило).

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


a[target="_blank"] {color: black}
.first {color: blue}
.second {color: green}
a {color: red}


<a href="/" class="first">Первый абзац</a>
<a href="/" class="second" target="_blank">Второй абзац</a>
<a href="/" class="first second" target="_blank">Третий абзац</a>

Получаем следующий результат:


Первый абзацВторой абзацТретий абзац


Добавляя стиль атрибута, мы меняем третье число справа в порядке 0.1.1.1. Поэтому вторая и третья ссылка стали черными.

И наконец добавим одному из элементов ID.


#yandex {background: #ffcc00}
a[target="_blank"] {color: black}
.first {color: blue}
.second {color: green}
a {color: red}


<a href="/" class="first">Первый абзац</a>
<a href="/" class="second" target="_blank" id="yandex">Второй абзац</a>
<a href="/" class="first second" target="_blank">Третий абзац</a>


Первый абзацВторой абзацТретий абзац


Добавляя стиль для ID, мы меняем первое число слева в порядке 1.1.1.1. Поэтому вторая ссылка получила нужный цвет.

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

Не рекомендуется использовать как самый крупный «вес» для стилей «селектора» (например ID), так и самый мелкий (например P). Одинаковых ID на странице быть не может, поэтому, если вы будете задавать стили именно для него, ваш CSS-файл разрастётся, а если вы решите изменить стиль добавив класс, у вас ничего не получится, «вес» класса меньше «веса» ID. Оставьте ID элементов для вашего JS-файла.

Так же не стоит добавлять стили для «селектора» (например <p>), потому что если у селектора будет хотя бы один класс, будет использоваться именно он. Обратите внимание, именно на «специфичности» созданы такие удобные файлы как: reset.css и normalize.css. Сохраните ссылки, они вам ещё понадобятся. Файлы сделают отображение вашего кода одинаковым во всех браузерах, избавившись от их «фирменных» встроенных стилей.

Правило третье

!important; имеет максимальный приоритет


.third {color: #ffcc00!important}
#yandex {background: #ffcc00}
a[target="_blank"] {color: black}
.first {color: blue}
.second {color: green}
a {color: red}


<a href="/" class="first">Первый абзац</a>
<a href="/" class="second third" target="_blank" id="yandex">Второй абзац</a>
<a href="/" class="first second" target="_blank">Третий абзац</a>


Первый абзацВторой абзацТретий абзац


Как видим, !important; просто переписал правила установленные всем прочим кодом.

Если вы можете не использовать !important;, не используйте его!

Во-первых, такие правки сложно отследить. Если вы полюбите !important;, однажды вы столкнётесь с тем, что в другой части кода есть и другой !important;, который к тому же, имеет больший «вес» или находится ниже. Придётся переписывать код.

Во-вторых, браузеру сложнее обработать !important;: он проходит по коду сверху вниз, определит последовательность и нарисует страницу, потом определит «вес» и снова перерисует, а затем ему надо будет сопоставить все `!important;`, которые вы использовали.

Подсказка

Если !important; использовать не рекомендуется, можно просто добавить вес вашим элементам. Например, вы можете показать, что какой-то элемент для получения нужного стиля должен обязательно находиться внутри другого или один тег «модифицирует» родителя. Это «наследование».


.first .paragraph {color: grey}
.paragraph.paragraph_recolor_blue {color:blue}
.paragraph {color: red}


<div class="first">
    <p class="paragraph">Первый параграф</p>
</div>
<div class="second">
    <p class="paragraph">Второй параграф</p>
    <p class="paragraph paragraph_recolor_blue">Третий параграф</p>
</div>



Первый абзац
Второй абзац
Третий абзац

«Вес» первого параграфа 0.0.2.0, он больше, чем 0.0.1.0, поэтому у него серый цвет.

Теперь вы легко сможете понять почему тот или иной элемент имеет определённый внешний вид.

Литература

1 мес   css   код   учебник