Организация таблиц стилей CSS стала критически важной для эффективного оформления больших веб-сайтов, но таблицы стилей в наших проектах становились все больше, сложнее и сложнее в обслуживании по мере их развития. Вот тут и приходит Sass, чтобы все упростить.
Для тех, кто еще не изучил Sass, это расширение CSS. Он предоставляет нам функции, которых нет в нативном CSS, такие как выражения, переменные, вложение, mixins (имя Sass для функций), наследование и многое другое.
В этой статье я собираюсь дать обзор наследования в Sass с использованием @extend
. Я расскажу о преимуществах этой функции и своем опыте ее использования в своих собственных проектах. Важно отметить, что @extend
может быть использован не по назначению, Хьюго Жираудель здесь, в SitePoint, даже написал статью о том, почему вы должны избегать Sass @extend . Так что помните, что @extend
может быть предметом спора.
В следующих примерах я буду использовать синтаксис SCSS. Это синтаксис, который содержит все функции и структуру CSS с дополнительными функциями Sass.
Что такое @extend
?
@extend
— это функция Sass, которая позволяет классам обмениваться набором свойств друг с другом. Для селекторов, которые @extend
класса в Sass, их селектор будет включен прямо рядом с классом, который он расширяет, что приводит к разделению запятыми.
Его синтаксис выглядит так:
@extend .class-name;
использование
Использование @extend
выглядит так:
.foo { color: black; border: 1px solid black; } .bar { @extend .foo; background-color: red; }
Это скомпилировано в:
.foo, .bar { color: black; border: 1px solid black; } .bar { background-color: red; }
В приведенном выше примере я определил .foo
и .bar
которые имеют следующие функции:
-
.bar
наследуется от.foo
, содержащего все свойства родительского класса.foo
. -
.bar
расширяет.foo
, добавляя свойствоbackground-color
.
Зная основы, теперь мы рассмотрим некоторые варианты использования @extend
.
Использование @extend
Вариант использования 1: дублирование
При сборке CSS сложно избежать дублирования свойств между классами. Это может сделать ваши таблицы стилей более сложными. Например:
.breakfast { color: #333; border: 1px solid #bbb; box-shadow: 1px 1px 0 #ddd; margin: 0 0 10px; padding: 15px; } .lunch { background-color: yellow; color: #333; border: 1px solid #bbb; box-shadow: 1px 1px 0 #ddd; margin: 0 0 10px; padding: 15px; } .dinner { background-color: orange; color: #333; border: 1px solid #bbb; box-shadow: 1px 1px 0 #ddd; margin: 0 0 10px; padding: 15px; }
Как видно из приведенного выше примера, .breakfast
, .lunch
и .dinner
содержат свойства color
, border
, box-shadow
, margin
и padding
с одинаковыми значениями. Эти свойства дублируются, что делает наш код грязным, поэтому давайте перепишем его с помощью @extend
:
.meal-box { color: #333; border: 1px solid #bbb; box-shadow: 1px 1px 0 #ddd; margin: 0 0 10px; padding: 15px; } .breakfast { @extend .meal-box; } .lunch { @extend .meal-box; background-color: yellow; } .dinner { @extend .meal-box; background-color: orange; }
В переписанном CSS выше мы видим, что использование Sass помогает нашей разметке стать чище, чем только CSS.
Случай 2: перемещение нескольких классов из HTML
При разработке страницы часто бывают случаи, когда один класс должен иметь все стили другого класса. Мы часто обрабатываем этот случай, используя несколько имен классов в HTML.
Наш CSS будет выглядеть так:
.candy { background-color: black; border: 1px solid red; box-shadow: 1px 1px 0 #ddd; padding: 15px; } .strawberry-candy { background-color: #ff6666; color: white; }
Наш HTML для этого CSS:
<div class="candy strawberry-candy"> This is the strawberry candy! </div>
В приведенном выше примере у нас есть два класса в нашем <div>
. Представьте, как это было бы грязно, если бы у нас было несколько классов:
<div class="candy strawberry-candy sugar-free-candy free-candy"> This is just an example </div>
Код HTML выше может стать довольно сложным. Некоторые веб-разработчики предпочитают это таким образом, однако я предпочитаю наследование в моих стилях Sass:
.candy { background-color: black; border: 1px solid red; box-shadow: 1px 1px 0 #ddd; padding: 15px; } .strawberry-candy { @extend .candy; background-color: #ff6666; color: white; }
С нашим HTML теперь выглядит так:
<div class="strawberry-candy"> This is the very sweet candy! </div>
На этот раз нам нужен только один класс. Все стили, определенные для класса .candy
, также применяются к классу .strawberry-candy
, теперь наш HTML-код становится чище.
Случай 3: расширение сложных селекторов
Селекторы классов не единственные вещи, которые могут быть расширены. Мы также можем расширить сложные селекторы в один элемент, такой как a:hover
, .parentClass.childClass
и так далее. Например:
.example { color: black; } .example:hover { color: red; } .hover-link { @extend .example:hover; }
Это скомпилировано в:
.example { color: black; } .example:hover, .hover-link { color: red; }
Который мы можем затем использовать в нашем HTML, как это:
<p>This is an example sentence with <a class="example">a sample link</a> that should have a typical hover style.</p> <p>This is another sentence, this time with <a class="hover-link">an eternally hovered link</a>.</p>
Преимущества @extend
Просматривая приведенные выше примеры, мы видим несколько преимуществ наследования через @extend
. Это включает:
Более чистые классы HTML
Как вы можете видеть во втором примере, использование такого количества классов в одном элементе может затруднить определение первопричины, если вы столкнетесь с проблемами. Структура HTML-тегов также выглядит не очень красиво и чисто.
С моей точки зрения, при создании хорошего продукта мы учитываем не только точку зрения конечного пользователя, но и качество нашей стратегии развития. Таким образом, @extend
помогает нам более @extend
структурировать наши классы внутри каждого элемента HTML.
Сокращение дублирования CSS
В веб-разработке у нас всегда есть некоторое дублирование в наших стилях CSS. Следовательно, повторное использование написанного исходного кода CSS может быть крайне необходимо. @extend
может помочь нам повторно использовать наш CSS, когда это уместно и чище.
Экономия времени и усилий
Обладая двумя вышеупомянутыми преимуществами, разработчики могут сэкономить время и усилия при разработке.
Разработчики могут повторно использовать CSS для различных элементов, сокращая усилия, необходимые для поиска основной причины проблем CSS, и делая их структуру CSS красивой и чистой.
Однако использование @extend
не обходится без опасностей. Вышеперечисленные преимущества применяются только тогда, когда @extend
используется осторожно — его можно использовать @extend
часто, вызывая противоположный эффект.
Опасности @extend
Я применил @extend
в своих собственных проектах, и мне нужно быть осторожным при использовании @extend
. Ты должен быть осторожен.
@extend
может резко увеличить размер вашего CSS-файла и повлиять на производительность вашего CSS, если его использовать без осторожности. Я @extend
боль в такой ситуации и потратил много времени на рефакторинг использования @extend
. Вот пример того, как я изначально использовал @extend
неправильно:
Пример:
.base-css { color: red; font-size: 15px; font-weight: bold; } .btn { @extend .base-css; padding: 5px; } .warning-message { @extend .base-css; background-color: red; } .footer { @extend .base-css; color: #fff; } .content { @extend .base-css; margin: 10px; }
компилируется в:
.base-css, .btn, .warning-message, .footer, .content { color: red; font-size: 15px; font-weight: bold; } .btn { padding: 5px; } .warning-message { background-color: red; } .footer { color: #fff; } .content { margin: 10px; }
В этом примере .base-css
— это класс, на котором основано много унаследованных классов. Если вы посмотрите на пример, вы увидите, что унаследованные классы не связаны друг с другом. У меня есть .btn
для моих кнопок и .footer
для моего .footer
колонтитула. Если у меня есть 100 классов, унаследованных от .base-css
, селекторы, имеющие характеристики .base-css
, увеличатся. Это значительно и излишне усложняет наш конечный результат CSS. Кроме того, это затрудняет проверку свойств каждого селектора.
После @extend
Sass я понял, что мы должны использовать @extend
только @extend
когда унаследованный класс напрямую связан с объектом, от которого мы наследуем. Это должно быть изменение объекта или стиля, а не общее правило для многих не связанных между собой элементов. Для наследования, как мой пример выше, мы должны полагаться на существующие возможности CSS для каскадирования наших стилей в дочерние элементы.
.btn { color: #fff; font-size: 15px; font-weight: bold; } .btn-success { @extend .btn; background-color: green; } .btn-warning { @extend .btn; background-color: orange; } .btn-info { @extend .btn; background-color: blue; } .btn-error { @extend .btn; background-color: red; }
компилируется в:
.btn, .btn-success, .btn-warning, .btn-info, .btn-error { color: #fff; font-size: 15px; font-weight: bold: } .btn-success { background-color: green; } .btn-warning { background-color: orange; } .btn-info { background-color: blue; } .btn-error { background-color: red; }
Мы видим, что приведенный выше пример является гораздо более правильным и разумным. Мы сократили область применения, применив @extend
только к классам, которые должны наследоваться друг от друга, поскольку являются разновидностью типа объекта. Например, все вышеперечисленные стили относятся к различным типам кнопок.
Вывод
Sass — это ценное расширение, которое может улучшить наш CSS, чтобы сделать его более чистым, хорошо структурированным, организованным и простым в разработке и обслуживании. Если вы раньше не пробовали Sass, я настоятельно рекомендую это сделать. Когда вы освоитесь с основами Sass, мы рекомендуем прочитать статью SitePoint Уго Жирауделя « Что никто не сказал вам о @extend
Sass . У нас также есть полное справочное руководство по Sass на Sass Reference в SitePoint с множеством примеров для изучения.
Спасибо Стиву и Иезекиилю в комментариях за обнаружение ошибки в первой версии этого поста, с тех пор он был обновлен.