Css на отдыхе часть 2
Существует три основных способа подключения CSS, которые мы сейчас и рассмотрим по порядку.
Как я уже говорил раньше, css призван оформлять html конструкции, то есть придавать им вид, цвет, размер, расположение, и так далее, а значит непосредственно воздействовать на html код.
Для обеспечения этого воздействия, выполняется подключение css к html документу.
В этом случае, файл style.css с таблицей стилей, подключается к html файлу в теге head, при помощи тега link
href – знакомый нам атрибут ссылок, css/stile.css – значение указывающее путь к файлу, и название файла;
type – атрибут указывающий тип подключаемого элемента, в нашем случае это text/css ;
rel – атрибут определяющий взаимосвязь, и в значении его обычно пишется stylesheet (таблицы стилей);
В этом коде обычно меняется только значение style.css (название подключаемой таблицы). Таблицы подключены.
Теперь браузер будет отображать html файл в том виде, который для него будет прописан в файле style.css .
Кстати, на будущее. К одному html файлу можно подключать сколько угодно таблиц стилей. Все они подключаются в тег head .
И, что применяется гораздо чаще, наоборот, одну таблицу можно подключить к множеству html файлов.
Это наиболее предпочтительный способ подключения таблиц стилей, так все они находятся в одном файле и поэтому легче определяются.
А так же, если придётся изменять стиль нескольких однотипных элементов, то гораздо легче будет это сделать если они собраны в одном групповом селекторе.
И хоть то, что я скажу дальше, уже больше относится к оптимизации, но это ещё больше подчеркнёт значимость вышеописанного способа.
Дело в том, что одной из задач веб-мастера является уменьшение объёма кода, при неизменном конечном результате, и отдельный файл style.css наиболее полно отвечает этому требованию.
Только представьте, чтобы написать заголовок к статье, нужно задать ему размер, цвет, шрифт и, возможно, что то ещё из стилей. И так для каждого поста.
В файле style.css можно будет задать стили один раз, но для всех заголовков постов сайта.
Теперь понимаете разницу?
Тем не менее и остальные способы подключения стилей имеют право на существование, так что давайте рассмотрим их, и ситуации, в которых они применяются.
Второй способ подключения css- глобальные стили позволяет подключать(располагать) таблицу стилей непосредственно в html файле.
Делается это при помощи тега style , и прописывается он так-же, как и в первом случае в теге head .
Как видите, таблица стилей расположена прямо в html файле. Всё это работает так-же, как и при первом способе подключения, но применяется реже, из за громоздкости, и главное, из-за невозможности воздействия стилей на несколько файлов.
Когда его применять? Я, например использую этот способ при создании дизайна в редакторе файлов.
Реализуется он при помощи атрибута style , который не стоит путать с одноимённым тегом.
Применяется он тогда, когда нужно оформить только один элемент контента.
Для примера возьмём кусочек текста, и зададим ему стили, заключив в тег span
Вот так можно сделать оформление отдельно взятого фрагмента текста. И применять этот способ лучше только для таких небольших включений.
Хотя, таким образом можно подключать любые стили, включая позиционирование, и код будет валидным, но чрезмерное применение встроенных стилей, приводит к увеличению времени загрузки страницы.
Ведь браузеру определившему их в файле style.css , и зайдя потом на страницу, придётся до определять или переопределять оформление некоторых элементов.
Неужели не осталось вопросов? Спросить
Перемена
Проблемы CSS. Часть 2
Продолжение перевода статьи «Проблемы CSS. Часть 1».
Когда использовать width / height равный 100%?
Height: 100%
Пожалуй, начнем с того, что попроще. Когда использовать height: 100%? На самом же деле, вопрос часто звучит немного по-другому: «Как мне сделать так, чтобы моя страница заняла всю высоту экрана?». Ведь правда?
Для ответа на него нужно понять, что height: 100% равен высоте родительского элемента. Это не магическое «высота всего окна». Так что, если вы захотите, чтобы ваш элемент занял все 100% от высоты окна, то установить height: 100% будет недостаточно.
Почему? А потому, что родителем вашего контейнера является элемент body, а у него свойство height установлено в auto по умолчанию; а значит — его высота равна высоте контента. Конечно, вы можете попробовать добавить height: 100% к body, но этого тоже будет недостаточно.
Почему? А все потому же, родителем элемента body является элемент html, у которого также свойство height равно auto и он также растягивается под размер контента. А вот теперь, если добавить height: 100% и к элементу html, то все заработает.
Стало понятнее? Корневой элемент html на самом деле не самый верхней уровень на странице — им является «viewport». Для простоты, будем считать, что это окно браузера. Так вот, если установить height: 100% элементу html, то это то же самое, что сказать — стань такой же высоты, как окно браузера.
Суммируем полученную информацию в небольшом кусочке кода:
Готово. Если вам интересно углубится в тему, как устроен viewport, я настоятельно рекомендую статью от PPK.
А что если у родительского элемента установлено свойство min-height, а не height?
Недавно, Роджер Йохансен (Roger Johansson) описал проблему с height: 100%, проявляющуюся, когда у родительского элемента не установлен height, но указан min-height. Я не хочу углубляться в сказанное в статье, а перейду сразу к выводам. Вам необходимо установить height: 1px для родителя, чтобы дочерний элемент смог занять всю высоту указанную в min-height.
Более подробно, с этим вопросом, вы можете ознакомится в статье Роджера Йохансена (Roger Johansson).
Width: 100%
Теперь давайте разберемся с width: 100%. Для начала, небольшое уточнение: устанавливая свойство width: 100%, мы хотим, чтобы наш элемент занял всю ширину родительского элемента. Все стандартно.
Позвольте открыть вам небольшой секрет. width, для этого свойства — не очень подходящие название. Свойство width — это не абсолютный размер элемента, а размер содержимого элемента и это огромная разница.
Если добавить padding и/или border к элементу с width: 100%, то он перестанет помещаться в родительский элемент. Потому что появились padding и border и вот почему width должен был называться content-width. А теперь, пожалуйста, посмотрите на пример демонстрирующий вышесказанное.
Допустим, ширина родителя 25em, а дочернего элемента — 100% (от ширины родителя) и он также имеет padding равный 1em (1em справа и1emслева, всумме2em по горизонтали) и border размером в 0.5em (0.5 em справа и 0.5 emслева, всумме1em по горизонтали), что в итоге нам дает 25em (100%) + 2em + 1em = 28em.
Есть 4 возможных пути решения этой проблемы. Первый и, наверное, лучший способ — избегать свойства width: 100%, тем более что в данном случае оно абсолютно бесполезно. Если дочерний элемент блочный, то он и так займет всю ширину родителя автоматически (без проблем с padding`ами и border`ами). Но если мы работаем с inline-block элементом, то нам не удастся так просто решить эту проблему.
Мы можем заменить width: 100% на статичный размер. В нашем случае 25 — (2 + 1) = 22em. Само собой — это плохое решение, потому что нам нужно вычислять ширину вручную. Пойдем другим путем!
Третий способ — использовать calc() для расчета ширины: width: calc(100% — 3em). Но оно тоже не подходит. Во-первых, нам все еще нужно вычислять размеры padding + border. Во-вторых, calc() плохо поддерживается браузерами (не работает в IE 8, Safari 5, Opera 12, родном браузере Android).
Идея номер четыре — использовать свойство box-sizing: border-box. Оно изменяет алгоритм расчета ширины и высоты элемента так, чтобы в них учитывались свойства padding и border. Отличная новость, заключается в том, что у box-sizing хорошая поддержка браузерами (IE8+, Opera 7+). А для всех остальных браузеров можно использовать polyfill.
Вывод: не используйте width: 100% без box-sizing: border-box.
Как не облажаться с z-index.
Все элементы на страницы позиционируются в трех плоскостях: кроме вертикальной и горизонтальной оси, существует дополнительная ось Z (глубина). Поначалу все выглядит очень просто — элементы с большим z-index находятся выше элементов с меньшим z-index. К несчастью, все гораздо сложнее. Я уверен, что z-index самое сложное css свойство за всю его историю. А также уверен, что проблемы связанные с z-index встречаются чаще других при работе с css. Надеюсь, что мы просветим возможные пути их решения.
Для начала. Свойство z-index не имеет эффекта на статических элементах. Чтобы иметь возможность перемещать элемент по оси Z, нам нужно изменить его позиционирование на relative, absolute или fixed.
Важно понимать в z-index то, что не все элементы в DOM дереве размещены на одном уровне. Это значит, что изменение z-index у элемента до очень большого значения, не гарантирует того, что он будет помещен на передний план. Это называется контекстом наложения.
Простыми словами, контекст наложения является, своего рода, группой на основе одного html элемента, у которого все дочерние элементы получают ту же позицию в контексте и такой же z-index. Изменения z-index у элемента может привести к перекрыванию им других элементов, так как вам необходимо. Вот как располагаются элементы в одном контексте наложения (снизу вверх):
- Фон и границы элемента, формирующего контекст
- Дочерние контексты наложения с негативным z-index (самый маленький первый)
- Не позиционированные элементы
- Позиционированные элементы со значением z-index равным auto или 0
- Позиционированные элементы с положительным z-index (каждый следующий по порядку расположен выше предыдущего, при равенстве z-index)
Когда ситуация становится неприятной
Итак, мы рассмотрели основы z-index понимание которых сэкономит вам кучу времени, уж поверьте. К сожалению, их недостаточно. Тогда все было бы слишком просто.
Дело в том, что каждый контекст наложения имеет свою ось Z. Например, элемент A в контексте 1 и элемент B в контексте 2 не могут взаимодействовать через z-index. Это значит, что элемент A, как часть контекста наложения находящегося в самом низу общего контекста наложения, никогда не сможет перекрыть элемент B другого контекста, находящегося выше уровнем, даже с очень большим значением z-index.
Но, что еще хуже. Элемент html создает корневой контекст наложения. Затем, каждый не статично-спозиционированный элемент со свойством z-index не равным auto, также создает свой контекст наложения. Ничего нового. Но вот где все начинает рушиться: некоторые, никак не связанные с контекстом наложения css свойства, также создают новые контексты. Например, свойство opacity.
Все верно, свойство opacity создает новый контекст наложения. То же самое делают свойства transform и perspective. Хотя это не имеет никакого смысла, не так ли? Например, если у вас есть какой-нибудь элемент с opacity меньше 1 или с любой трансформацией, у вас потенциально может возникнуть проблема.
К сожалению, каждая проблема с z-index имеет свой контекст (не каламбур) делающий невозможным универсальное решение.
Давайте подведем краткий итог вышесказанного:
- Перед применением z-index убедитесь, что установили свойство position не равным static
- Не используйте более 5 цифр для значения z-index, это абсолютно бессмысленно; в большинстве случаев, значение z-index в районе 10, будет более чем достаточно
- Убедитесь, что элемент, который вы хотите перекрыть находится в том же контексте наложения.
- Если у вас все еще что-то работает не так, как должно, убедитесь в отсутствии трансформаций и opacity выше у родительских элементов.
В тему, я так же рекомендую к прочтению What No One Told You About Z-index от Филипа Волтона (Philip Walton) и официальную спецификацию css.
Борьба со схлопыванием отступов
Как мне кажется — это один из глюков css, который крадет наибольшее количество времени, чтобы разобраться в чем же дело. Можно сказать, что он чем-то похож на баг с z-index. Как бы то ни было, схлопывание отступов — это когда верхний и нижний отступ двух элементов схлопываются в один (самый большой из двух).
К счастью, как правило, такое поведение и ожидается. Возможно, поэтому оно так и работает (так указано в спецификации css). Однако, иногда вы не хотите, чтобы вертикальные отступы схлопнулись. Чтобы понять как этого избежать, мы для начала посмотрим, почему так происходит. Схлопывание отступов может произойти в трех разных случаях.
Соседние элементы
Когда два соседних элемента имеют вертикальные отступы — они схлопываются до самого большого из них. Есть несколько способов предотвратить схлопывание:
- clear: left; (right то же работает)
- display: inline-block;
Пример на jsFiddle иллюстрирует работу фиксов.
Родитель и первый/последний дочерний элемент
Обычно, верхний отступ родительского и дочернего элементов схлопываются до самого большого. Аналогичным образом работает и для последнего дочернего элемента и нижних отступов. Для решения этой проблемы, также есть несколько способов. Большинство из которых заключаются в добавлении одного из следующих свойств родительскому элементу:
- overflow: hidden (или любой другой, но не visible)
- padding: 1px (или другое значение больше 0)
- border: 1px solid transparent (или любой другой border)
- float: left (right то же работает)
Пример на jsFiddle иллюстрирует работу фиксов.
Пустые блоки
Когда пустой блок не имеет границ, padding`ов, высоты, его верхние и нижние отступы схлопываются в один. Так или иначе, использовать пустые блоки плохая практика, так что такое встречается не часто.
Заключение
К сожалению, тут описана только верхушка айсберга из багов и хаков css. Но это действительно те, которые встречаются чаще других, но есть еще множество вещей таких как: несовместимость браузеров, вендорные префиксы, специфичность селекторов, каскады и наследование и многое другое.
Также я бы рекомендовал к ознакомлению следующие статьи и сайты:
-
за авторством Philip Walton и ее перевод на хабре, спасибо SelenIT2 за наводку за авторством Roger Johansson’s за авторством Nicolas Gallagher за авторством Robert Nyman за авторством Tim Pietrusky и меня
Надеюсь, статья помогла понять некоторые вещи, которые смогут уберечь вас от проблем в будущем.
Каскадность и специфичность
Напомню, что CSS в переводе – это «Каскадные таблицы стилей», уже одно это показывает важность понятия «каскадность».
В верстке самой распространенной является ситуация, когда на один элемент действуют множество CSS-правил. И то, как именно будет выглядеть элемент определяют именно каскадность и специфичность.
Каскадность
Каскадность – это механизм CSS, который определяет какие стили в итоге будут применены к элементу.
Посмотрите на пример:
<h3 class="attention highlight"> Заголовок третьего уровня </h3> font-size : 24px ; color : red ; background-color : yellow ;Видим, что для данного элемента имеются 3 правила. Итоговыми стилями, примененными к элементу, будут:
font-size : 24px ; color : red ; background-color : yellow ;С каскадностью теснейшим образом связана специфичность.
Дело в том, что одни и те же свойства, для одного и того же элемента, могут быть определены в разных css-правилах, и даже, в разных файлах.
Какое же значение у свойства будет в итоге? Это определяется через механизм, называемый специфичность.
Специфичность
<div class="sidebar"> . sidebar h3 < color : red ; color : blue ;В примере цвет текста для тега < h3 > , находящегося в контейнере с классом . sidebar , прописан 2 раза.
Вопрос: «Какой цвет будет у этого элемента?»
Ответ: «Красный, поскольку селектор . sidebar h3 более специфичен, еще говорят: селектор имеет больший вес».
Специфичность (вес) селектора определяется при помощи 4-х различных значений. Эти значения можно, условно, представить как цифры: тысячи, сотни, десятки, единицы.
- Тысяча – это встроенные стили, добавляемые непосредственно в сам элемент в HTML-разметке.
- Сотня – это идентификатор.
- Десятки – это классы.
- Единицы – это сам элемент или псевдоэлемент.
Если не очень понятно, то посмотрите таблицу ниже и все станет ясно:
В ситуации, если специфичность у селекторов одинакова, действовать будет правило, которое находится ниже в css-файле.
Если правила находятся в разных css-файлах, то действовать будет правило, которое расположено в файле, подключенном позднее (ниже).
Практика
Итак, мы подошли к самому главному. Начнём с @import .
import
Изначально, до использования SCSS, весь CSS код движка, с которым мне по долгу службы приходится работать, находился в 1-ом огромном style.css файле. Моя IDE (Netbeans (кстати, вот плагин для подсветки синтаксиса)) работала с ним с существенными тормозами. Разбивать же его на множество файлов поменьше, и, при необходимости, склеивать их в 1 ― никто не хотел. SCSS решает этот вопрос автоматически.
Стоит отметить 1 нюанс. Если скормить sass не конкретный файл-источник, а директорию, то css файлы не будут генерироваться для файлов начинающихся с _ . Т.е. наличие файла style.scss приведёт к созданию style.css , а наличие файла _some.scss ― нет.
Итак, для того, чтобы включить содержимое файла _template.scss или template.scss пишем
В конечном счёте, вместо 1-го большого style.css файла у меня получилось более сотни мелких scss -файлов. С первого взгляда может показаться, что такое количество слишком велико и приведёт к страшным мукам. Однако, нужный мне файл я нахожу сразу исходя из удобной структуры каталогов. К тому же, я полагаю, что благодаря кешированию такая "схема" более производительна.
@вложенность
Одна из самых желанных "фич" для CSS ― вложенность селекторов. Пример:
Символ & равносилен родительскому селектору. Допустим тег <body> у нас имеет класс ie_7 , в случае если в качестве обозревателя у нас Internet Explorer 7 . Следующий код позволяет избавиться от всех "хаков" и спец.комментариев:
$variables
Переменные ― удобная штука. Определяются они так:
Переменные ― не константы, их можно менять по ходу кода :) Одна из первых моих мыслей вылилась в _const.scss файл, который заключает в себе все базовые цвета, размеры шрифтов и пр.
Предполагается, что цвет ссылок на сайте ― $link .
Если в дальнейшем выяснится, что цвет ссылок изменился ― достаточно поменять 1 переменную (в случае CSS нужно было бы пройтись авто-заменой по файлам, возможно даже выборочно). Предположим, что внезапно выясняется, что в некотором модуле contacts , цвет ссылок другой. Есть, как минимум, два пути решения.
Переменные у нас не типизированные, поэтому с равным успехом могут содержать строки, числа и цвета.
@математика
Разделим математику на 2 категории ― цвета и числа. Начнём с чисел. Простой пример:
При желании можно и padding с border-ом задавать переменными. Всё зависит от сложности вёрстки.
Хочу отметить, что подобного рода манипуляции применяются очень часто. Без них я как без ног.
А теперь цвета. Цвета можно складывать, перемножать:
Довольно удобная штука, когда лень подбирать цвета. Также доступны такие функции как opacify и transparentize (более подробно).
@строки
Полагаю, что наибольшее применение операциям над строками можно найти в @миксинах и переменных, указывающих пути к изображениям и пр.
Упорядочивание CSS-файлов: принцип «7–1»
Пришло время познакомиться с принципом «7–1».
Эти цифры ни о чем вам не говорят, да?
Но всё довольно просто. Нужно следовать двум правилам:
- Размещайте частичные файлы в 7 папках.
- Импортируйте их все в один файл main.scss , расположенный в корне. Вот и всё.
Семь папок:
- Папка base — шаблонный CSS-код, который вы пишете всякий раз, когда начинаете новый проект. Это могут быть правила верстки, анимации, вспомогательные классы (например, margin-right-large , text-center , …) и так далее.
- Папка components — все компоненты, используемые для формирования страниц: кнопки, формы, модули листания — «свайперы», всплывающие окна и т. д.
- Папка layout — для компоновки различных частей страницы, то есть шапки, подвала, навигации, разделов, собственной сетки и т. д.
- Папка pages — для страниц, которым нужен отдельный стиль, отличающийся от стандартного.
- Папка themes — для различных тем приложения (темный режим, администрирование и т. д.).
- Папка abstracts — все функции, переменные и примеси. Короче говоря, вспомогательные штуки.
- Папка vendors — внешние библиотеки, без которых не обходится, пожалуй, ни одно приложение. В папке vendors лежат файлы, которые от вас не зависят: файлы Font Awesome, Bootstrap и всё такое.
Основной файл
Сюда импортируются все частичные файлы.
Да, выглядит немножко раздуто, признаю. Но эта архитектура придумана для крупных проектов — а для задач помельче есть другой вариант.
Во-первых, нам не понадобится папка vendors : весь внешний CSS-код будет в теге link , помещенном в заголовок. Также не нужна папка themes : скорее всего, у небольшого приложения будет всего одна тема. Наконец, не будет и стилей для конкретных страниц — поэтому убираем соответствующую папку. Итак, осталось четыре папки — отлично!
Теперь у нас два варианта:
- Если следовать принципу «7–1», нужно сохранить папки abstracts , components , layout и base .
- Если вам удобнее работать с большой папкой, в которой будут все частичные файлы и main.scss , получится что-то такое:
Убедил! Как всё это применять? В смысле, браузеры же не поддерживают файлы scss , да?
Верно подмечено! На последнем этапе мы будем компилировать SCSS в CSS.
Наследование
Для сокращения количества правил в CSS имеется механизм наследования.
Наследование – это механизм, когда определенные в контейнере свойства, автоматически назначаются вложенным в этот контейнер элементам.
Для примера, рассмотрим правило:
color : blue ;В примере выше, мы устанавливаем синий цвет текст для тега < body > . При этом все остальные элементы, находящиеся внутри этого тега, независимо от уровня вложенности, унаследуют синий цвет текста.
Описанное выше поведение очень удобно, иначе вам бы пришлось, для всех элементов, прописывать цвет текста вручную.
Наследуются далеко не все свойства. Свойства, относящиеся к тексту, наследуются – это такие свойства, как: color , font , letter - spacing , line - height , list - style , text - align , text - indent , text - transform , visibility , white - space и word - spacing и некоторые другие.
А вот свойства, которые отвечают за форматирование блоков не наследуются: background , border , display , float и clear , height , width , margin , overflow , padding , position , text - decoration , vertical - align , z - index и другие.
В самом деле, представьте если бы наследовалась, скажем, граница – верстка бы сильно усложнилась.
В спецификации css имеется ключевое слово inherit . С его помощью можно принудительно наследовать любое свойство от родительского блока (как наследуемое, так и не наследуемое).
overflow : inherit ;В этом примере параграфы, находящиеся внутри блока с классом . sidebar будут наследовать значение свойства overflow от своего контейнера.
Модификатор !important
Если для объявления задан модификатор ! important , то такое объявление будет иметь приоритет над всеми остальными объявлениями для данного элемента.
Модификатор ! important пишется в конце объявления, после значения перед точкой с запятой.
Пишем CSS лучше и красивее
Когда при разработке приложений приходилось браться за CSS, это была не самая радостная часть работы. Но ее ведь не избежать, верно? Сегодня порадовать пользователя дизайном приложения настолько важно, что без CSS — никак.
Это я, когда сражаюсь с CSS
Переведено в Alconost
Моя задача сегодня — научить вас писать CSS лучше. Я хочу, чтобы, взглянув на старые проекты, вы подумали: «О боги! Как можно было написать такое?»
А как же CSS-фреймворки? — спросите вы. Они ведь для этого и придуманы — писать хороший CSS-код.
Правильно. Но у них есть недостатки:
- Дизайн на выходе часто получается скучный.
- Бывает сложно сделать нужные настройки или выйти за рамки возможностей фреймворка.
- Чтобы пользоваться фреймворками, сначала нужно их изучить.
Примечание. Это статья не о том, как создавать красивые приложения, а о том, как писать поддерживаемый CSS-код и как его упорядочить.
В примерах я буду использовать SCSS.
SCSS — это препроцессор CSS, по сути — надмножество CSS, которое добавляет некоторые классные возможности, например, переменные, вложенность, импорт и примеси («миксины»).
Далее я расскажу, какие возможности мы будем использовать здесь.
Переменные
В SCSS есть переменные, и основное их преимущество — повторное использование. Предположим, у вас есть палитра цветов для приложения, и основной цвет — синий.
Поэтому синий у вас везде: фон background-color кнопок, цвет color заголовков, ссылок. СИНИЙ — ПОВСЮДУ.
И вдруг синий вам разонравился. Новый фаворит — зеленый.
- Если вы не использовали переменные, придется изменять все строки, в которых стоит синий.
- А с переменными достаточно изменить значение одной из них.
Вложенность
В SCSS можно использовать вложенность. Поэтому из фрагмента
можно сделать такой код:
Последнее читается лучше, правда? Вложенность позволяет меньше времени тратить на написание сложных селекторов.
Импорт и частичные файлы
Если нужно обеспечить поддерживаемость и удобочитаемость, хранить весь код в одном огромном файле — плохая идея. Если вы экспериментируете или пишете небольшое приложение, это еще терпимо, но на профессиональном уровне… даже не пытайтесь. К счастью для нас, SCSS решает эту проблему.
Мы можем создавать «частичные файлы» — у которых имя начинается с символа подчеркивания: _animations.scss, _base.scss, _variables.scss и так далее.
Для их импорта используется соответствующая директива: @import . Например, можно сделать так:
Вы могли подумать: «Ага! У него здесь ошибка! Нужно писать _animations.scss , а не animations ».
Не-а. SCSS достаточно умен, чтобы понять, что в этом случае речь идет о частичном файле.
Это все, что нам нужно знать о переменных, вложенности, частичных файлах и импорте. У SCSS есть и другие возможности — примеси, наследование и различные директивы ( @for , @if , …), но их я затрагивать здесь не буду.
Если вам интересно — почитайте документацию: она достаточно понятно и хорошо написана.
Кое-что еще
Перезагрузка на лету
Чтобы работа лучше спорилась, можно добавить автоматическую перезагрузку локального файла index.html .
- Устанавливаем пакет live-server : npm install -g live-server
Примечание: это глобальный пакет. - Добавляем npm-run-all в зависимости проекта: npm install npm-run-all --save-dev — это позволит запускать несколько сценариев одновременно.
- Добавляем в package.json такие сценарии:
Теперь, если запустить npm run start , изменения будут отображаться сразу — без лишних движений с вашей стороны.
Автоматические префиксы
Мы настроили инструменты разработки — отлично! Теперь поговорим об инструментах сборки, в частности — об этом: Autoprefixer.
Этот инструмент (а точнее, плагин «postcss») анализирует CSS и добавляет к правилам CSS префиксы поставщиков, используя значения из Can I Use.
При создании веб-сайта могут использоваться новые функции, которые поддерживаются не во всех браузерах. Реализовать поддержку таких функций позволяют префиксы поставщиков.
Пример того, как оно будет выглядеть:
Да-да, писать это вручную — утомительно. Облегчит нам жизнь инструмент для автоматического добавления префиксов, который сделает CSS-код совместимым с браузерами без дополнительных усилий.
Итак, чтобы собрать CSS:
- Компилируем все SCSS-файлы в один CSS-файл.
- Добавляем префиксы, используя Autoprefixer.
- Сжимаем CSS-файл.
- Добавляем две зависимости — postcss-cli и autoprefixer : npm install autoprefixer postcss-cli --save-dev
- Изменяем сценарий build и добавляем в package.json эти строки:
Теперь при запуске npm run build будут добавлены префиксы поставщиков, а сам CSS-код будет сжат. Просто магия!
А хотите еще немножко волшебства? Я поднял репозиторий — чтобы вы могли разобраться побыстрее?
Если вам интересно, как я применил эти навыки на странице своего портфолио, загляните в этот репозиторий и полюбуйтесь на результат. Надеюсь, эти примеры помогут лучше понять то, о чем шла речь в статье.
И… это всё на сегодня! Теперь вы умеете писать поддерживаемый модульный CSS-код с возможностью повторного использования.
О переводчике
Перевод статьи выполнен в Alconost.
Alconost занимается локализацией игр, приложений и сайтов на 68 языков. Переводчики-носители языка, лингвистическое тестирование, облачная платформа с API, непрерывная локализация, менеджеры проектов 24/7, любые форматы строковых ресурсов.
Мы также делаем рекламные и обучающие видеоролики — для сайтов, продающие, имиджевые, рекламные, обучающие, тизеры, эксплейнеры, трейлеры для Google Play и App Store.
Комбинации селекторов.
Селекторы можно комбинировать друг с другом используя, так называемые комбинаторы.
В задачу, описанную выше, мы можем решить, написав два правила.
Для заголовков статей:
.articles h3 < text-align : center ;Для заголовков новостей:
. sidebar h3 < color : darkred ;Здесь мы использовали комбинатор пробел . Т.е. селектор . articles h3 выберет для изменений теги < h3 > , которые находятся внутри элемента с классом articles (вне зависимости от уровня вложенности).
Этот комбинатор называется «комбинатор потомков» и используется очень часто.
Дочерний селектор
Давайте немного изменим верстку блока со статьями.
<div class = "articles" > <h3> Заголовок статьи 1 </h3> <h3> Заголовок статьи 2 </h3> <div class = "promo" > <h3> Рекламная акция </h3> <h3> Заголовок статьи 3 </h3> <h3> Заголовок статьи 4 </h3>У нас, среди статей, появился рекламный блок, и в нем также используется заголовок < h3 > .
Использованный нами ранее селектор . articles h3 подействует и на заголовок рекламной акции, поскольку он не учитывает уровень вложенности.
.articles > h3 < text-align : center ;Селектор . articles > h3 выберет для изменения теги h3, которые находятся непосредственно в элементе с классом articles , а теги рекламных заголовков затронуты не будут.
Комбинатор всех соседних элементов
выберет все соседние элементы, т.е. элементы у которых такой же контейнер, как и у указанного элемента. Слово «соседний» в данном случае обозначает, что будут выбраны все элементы находящиеся после указанного.
<div class="articles"> <h3 class="first-article"> Заголовок статьи 1 </h3> <h3> Заголовок статьи 2 </h3> <div class="promo"> <h3> Рекламная акция </h3> <h3> Заголовок статьи 3 </h3> <h3> Заголовок статьи 4 </h3> . first - article color : blue ;В примере выше все заголовки <h3>, которые находятся после заголовка с классом . first - article , станут синего цвета. Заголовок, находящийся внутри <div> с классом . promo затронут не будет, поскольку у него другой контейнер.
Комбинатор следующего соседнего элемента
Комбинатор + позволяет выбрать элемент, который находится сразу после указанного элемента. При этом, конечно, у них должен быть общий контейнер.
.first-article + * < margin-top : 3rem ;В примере выше, написано правило, которое обеспечивает, что любой (один) элемент, который находятся сразу после заголовка с классом . first - article , будет иметь отступ сверху размером 3rem .
Комбинатор запятая
Комбинатор, позволяет сгруппировать селекторы, т.е. задать несколько селекторов для одного правила.
h1, h2, h3, h4, h5, h6 < margin-bottom : 0 ;В примере выше, мы обнуляем отступы снизу сразу у всех заголовков.
SCSS — немного практики, часть I
Статей про SASS ( SCSS ), Less на хабрахабре уже полно, но на мой взгляд не хватает такой, в которой было бы немного реальной практики. Я постараюсь восполнить этот пробел. Около года назад одна из SASS -статей меня "зацепила", и с тех пор я полюбил эту технологию настолько, что ручной набор обычного CSS кода представляется мне лишней тратой времени. Сия статья посвящается тем верстальщикам (или web-программистам), которые про SCSS ещё не слышали, или же ещё не пробовали в деле. Более опытным товарищам, полагаю, в ней ловить нечего.
Упорядочивание CSS-кода: методология БЭМ
Я бесчисленное множество раз использовал общие названия для CSS-классов. Ну, вы знаете: .button .page-1 .page-2 .custom-input .
Часто мы понятия не имеем, какое имя выбрать — хотя именование это важная задача. Представьте, что вы начали писать приложение, а затем решили отложить это дело на несколько месяцев — или, что еще хуже, кто-то взял ваш проект на себя. Если не продумать именование в CSS-коде, будет сложно сходу понять, что имеется в виду в конкретной строчке.
БЭМ помогает решить эту проблему. БЭМ — это соглашение об именовании; расшифровывается как блок, элемент, модификатор.
Эта методология поможет структурировать код, сделать его более модульным и упростить повторное использование. Разберемся, что же значат «блок», «элемент» и «модификатор».
Блоки
Блок можно представить себе как компонент. Возьмем, к примеру, конструктор Lego.
Как из конструктора сделать простой дом? Понадобятся окно, крыша, дверь, пару стен — и всё. Как раз это и есть наши блоки — они несут смысл сами по себе.
Элементы
А как из кубиков конструктора сделать окно? Можно найти кубики, которые выглядят как части рамы, и собрать из них красивое окно. Это и будут наши элементы. Они представляют собой необходимые части блока, но вне блока сами по себе бесполезны.
Именование: название блока + __ + название элемента: .block__element
Примеры: .post__author, .post__date, .post__text
Модификаторы
Итак, мы сделали какое-то окно. Теперь нам понадобилось зеленое или, например, маленькое окно. Это будут наши модификаторы. Они представляют собой флаги на блоках и элементах, которые используются для изменения поведения, внешнего вида и т. д.
Именование: название блока ИЛИ элемента + -- + название модификатора: .block__element--modifier, .block--modifier
Примеры: .post--important, .post__btn--disabled
Примечания
- БЭМ подразумевает именование классов и только классов. Не идентификаторов и не тегов — только классов.
- Блоки и элементы могут вкладываться в другие блоки и элементы, но они должны быть полностью независимыми. Обязательно независимыми. Поэтому не нужно добавлять кнопке поля, чтобы она была под заголовком, иначе она будет привязана к заголовку. Лучше использовать вспомогательные классы.
- Да, HTML-файл будет перегружен, но это не страшно: преимущества БЭМ перевешивают этот недостаток.
Пример
Небольшое упражнение для читателей. Походите по сайтам, на которых вы часто бываете, и подумайте, какие там могли бы быть блоки, элементы и модификаторы.
Например, такую картину я могу вообразить в магазине Google:
Теперь ваша очередь. Проявите любопытство и подумайте, что можно было бы сделать лучше. И конечно, чтобы совершенствовать собственные навыки, нужно самостоятельно искать, экспериментировать и писать код.
Из SCSS делаем CSS
Нам понадобятся Node.js и NPM (или Yarn).
Мы будем использовать пакет node-sass , который позволит компилировать файлы .scss в .css .
Интерфейс у него довольно простой:
- Параметр -w — следить за каталогом или файлом. Пакет node-sass будет ждать изменений в коде, а как только обнаружит их, сразу же скомпилирует соответствующий файл в CSS, что очень удобно при разработке.
- Параметр --output-style — как будет выглядеть выходной CSS-файл. Может принимать следующие значения: nested|expanded|compact|compressed . Мы будем использовать этот параметр при сборке CSS-файла.
Теперь мы знаем, какие инструменты будут использоваться. Остальное сделать еще проще:
- Создаем проект: mkdir my-app && cd my-app
- Инициализируем его: npm init
- Добавляем библиотеку node-sass : npm install node-sass --save-dev
- Создаем нужные папки, файлы index.html и main.scss :
- Добавляем в файл package.json такие сценарии:
- Добавляем ссылку на скомпилированный CSS-файл в тег head файла index.html:
Вот и всё! Когда будете писать код, запустите npm run watch и откройте в браузере файл index.html . Чтобы уменьшить CSS, достаточно запустить npm run build .
Установка и использование
Для начала нужно установить ruby. После чего нужно установить sass-gem ( gem install sass в консоли ). Если всё прошло гладко, то теперь вам доступна консольная программа sass . О всех нюансах её использования вы можете прочесть здесь ― sass --help . Я расскажу лишь о двух базовых возможностях:
--watch
Если запустить sass с ключом --watch , то программа будет следить за указанными вами файлами. В случае их изменения, она автоматически пересоберёт все необходимые css-файлы (не все вообще, а только связанные с изменёнными).
Предположим, что у вас есть следующая структура проекта:
Необходимо чтобы sass отслеживал все изменения в css/scss/* и результат сохранял в css/*.css . В таком случае запускаем sass так ― sass --watch css/scss:css/. . Т.е. sass --watch [что]:[куда] .
--update
Если вам нужно единожды обновить css-файлы, то в место --watch применяем --update . Никакой слежки проводится не будет, так же как и проверок на необходимость обновления.
Стоит отметить, что в отличии от Less , SASS не умеет компилировать свой код прямо в браузере. На мой взгляд, такой подход (компиляция на сервере или ПК-верстальщика) является единственно верным.
Что такое SCSS
SCSS — "диалект" языка SASS. А что такое SASS? SASS это язык похожий на HAML (весьма лаконичный шаблонизатор), но предназначенный для упрощения создания CSS-кода. Проще говоря, SASS это такой язык, код которого специальной ruby-программой транслируется в обычный CSS код. Синтаксис этого языка очень гибок, он учитывает множество мелочей, которые так желанны в CSS. Более того, в нём есть даже логика (@if, each), математика (можно складывать как числа, строки, так и цвета). Возможно, некоторые возможности SCSS покажутся вам избыточными, но, на мой взгляд, лишними они не будут, останутся "про запас".
Отличие SCSS от SASS заключается в том, что SCSS больше похож на обычный CSS код. Пример SASS-кода:
И то же самое на SCSS:
Я выбрал SCSS в виду того, что он проще для восприятия коллегам с ним ещё не знакомым. Ещё стоило бы отметить что обычный CSS код вполне вписывается в SCSS синтаксис.
Основы CSS. Часть 2. Комбинации селекторов, наследование, каскадирование и специфичность
В прошлой статье мы разобрали что такое CSS, как подключать стили к HTML страницам, поговорили о синтаксисе CSS-правил, и познакомились с многообразием CSS-селекторов.
В этой статье разберем немного более сложные вещи.
Предположим, есть страница на сайте, где слева размещены статьи, а справа, в боковой колонке идет новостная лента. Ниже псевдоразметка, чтобы было понятно, о чем идет речь.
<div class = "articles" > <h3> Заголовок статьи 1 </h3> <h3> Заголовок статьи 2 </h3> <div class = "sidebar" >Для заголовков и статей, и новостей, используются теги <h3>. Мы можем отформатировать эти заголовки, используя селектор элемента, например:
font-size : 1.5rem ; font-weight : bold ;Cтоит задача, что заголовки статей должны быть по центру, а заголовки новостей надо сделать темно-красного цвета.
Мы можем написать отдельные классы для заголовков статей и заголовков новостей, и в этом классе прописать нужные нам свойства.
Но тогда нам придется эти классы указать в разметке для каждого тега <h3> как в статьях, так и в новостях, да и в целом количество классов увеличится. Однако известный философский принцип «Не следует множить сущности без необходимости» актуален везде, в том числе и программировании.
Мы можем поступить красивее, а именно использовать комбинации селекторов.
Статья
В виду того, что статья получилась довольно объёмной, я решил разбить её на 2 части. В следующей статье я рассмотрю (синтаксис и область применения):
Читайте также: