Главная » Статьи » CSS: проблемы и способы их решения

CSS: проблемы и способы их решения

CSS: проблемы и способы их решения

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

Возможно, мое отношение немного несправедливое. Стили родились в то время, когда веб находился в разработке, идей было много, а популярных идей только начали придерживаться. Каким бы сложным CSS ни был, по моему мнению, он нужен всем сайтам на планете. Без него сайты бы не выжили. Но есть в CSS проблемы, которые могут сильно осложнить работу.

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

1. Глобальная область видимости

Первая и самая большая для меня проблема в CSS заключается в том, что любое объявление стилей может изменит любой аспект любого элемента на странице. Это супер круто и замечательно, если вы только начали окунаться в веб, но для более крупных сайтов (что происходит чаще) это опасно. Почти все front end разработчики в определенный момент в своей карьере добавляют/обновляют/удаляют стили лишь для того, чтобы найти случайные стили, которые просочились в другие разделы на другой странице.

Мне кажется, это самая существенная проблема CSS. Это сильно усложняет любую концепцию модульности. Завтра разработчик может вставить несколько !important и поломать ваш красиво инкапсулированный, повторно используемый видежт.

.blog-post { .title { font-size: 2rem; }
} # Grrrr, styles leaking everywhere
h1 { font-size: 5rem !important;
}

Sass/SCSS поможет, но не полностью. Если вы хороший маленький разработчик, то утечку стилей можно почти полностью прекратить через вложенность правил в родительский класс.

.blog-post { .title { font-size: 2rem; }
} # A bit better
.home { h1 { font-size: 5rem; }
}

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

Если вы скажете back end разработчику, что ему придется использовать язык программирования, который делает все переменные глобальными, все внутренние состояния объектов видимыми, а потом дадите переписать этот код другому разработчику, он, вероятно, сразу же уйдет. Такова безумная реальность CSS разработки. Захватывается вс. Неизменность? Да ладно вам.

Лучшее решение

Лучший выход для глобальной области видимости, который я нашел – это использовать систему именования CSS BEM, в которой разработчики должны однообразно писать модульный код. Это устраняет опасные привычки использовать в стилях теги (h1, p и т.д.). Лучше вместо них использовать классы. Названия классов заранее определяют пространство имен модуля (или блока в терминологии BEM), в котором они находятся, чтобы избежать случайных столкновений с похожими именами классов.

Зачастую можно использовать теги для создания стилей по умолчанию. Для большинства сайтов это хорошая идея. Однако если вы потом почти везде переписываете эти стили, я бы сказал, не стоит утруждаться. Поместите их в общий класс-утилиту (.paragraph, .heading-1 и т.д.) и используйте при необходимости.

BEM отнюдь не идеальный инструмент. Кому-то будет трудно писать большие, длинные классы везде. Вы все еще пишите CSS. Вы все еще можете писать хитроумные стили. У вас все еще нет дисциплины. Но эта система дает вам структуру и набор правил, которые помогут писать стили лучше.

2. Специфичность

Специфичность – механизм, с помощью которого CSS определяет важность стилей. На моем опыте это почти всегда гонка вниз (или вверх, как в нашем контексте). Горсть !important, стили на произвольных ID и ненужные div обертки. Их цель – подтолкнуть специфичность выше проблемных стилей. Это правда.

Вы разрабатываете новый UI элемент, но на вашем пути стоит очень специфичный стиль вашего коллеги. Что вы сделаете?

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

Или подтолкнете свой стиль с помощью !important.

Ваш выбор может зависеть от среды, в которой вы работаете, а также от размера кода.

ООП языки обходят эту проблему путем наследования и создания подклассов. Менее важный и неспецифичный метод находится наверху дерева наследования, а самый специфичный – внизу. На мой взгляд, приложение этих OO принципов в области UI работает намного лучше, чем специфичность CSS. Любой знакомый с iOS UIKit, например, знает, как создавать общие UIView виджеты и более специфичные подклассы для перезаписи определенных атрибутов. С другой стороны, обычно приходится писать немного больше кода и больше думать над таким переопределением.

Лучшее решение

Не гонитесь в самый низ. Не делайте стили слишком специфичными.

Постарайтесь не использовать !important (иногда это необходимо при работе со сторонним вставляемым кодом).

Не пишите стили для ID (большая специфичность).

Используйте классы (неспецифичны).

Не включайте потомков в селекторы стилей, так как они усиливают специфичность. В Sass/SCSS вложенные стили компилируются до селекторов потомков, поэтому не вкладывайте их.

Если вы используете BEM, вы уже следуете этим правилам.

3. Правила с неявными процентами

Любой, кто использовал проценты в padding, поймет, насколько код ниже запутанный.

.sidebar { padding: 10%;
}

Новичкам в CSS нужно дать время, чтобы понять код выше. Неясно, как поведут себя эти 10%. 10% чего? Это может быть…

Ширина вьюпорта

Высота вьюпорта

Ширина .sidebar

Высота .sidebar

Родительская ширина .sidebar

Родительская высота .sidebar

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

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

Лучшее решение

К сожалению, с этим почти ничего нельзя сделать.

Если вы хотите, чтобы размеры соотносились с шириной и высотой вьюпорта, рекомендую использовать единицы vw и vh. У них довольно хорошая поддержка, и вам не придется использовать проценты. Просто следите за особенностями на мобильных устройствах, так как ширина и высота вьюпорта могут меняться в зависимости от того, просматривается ли сайт в Chrome.

Я считаю, что vw и vh – это хорошее решение проблемы с неявными процентами. Просто жаль, что они не продвинули идею дальше.

4. z-index

Если у вас болит голова от z-index, вы принимаете атомное решение — z-index: 999999. Когда это происходит, начинается хаос. Все что должно быть выше этого элемента в будущем должно иметь еще одну 9.

Мне кажется, что все начинает рассыпаться из-за нехватки контекста. Правила z-index определяются отдельно через все стили, поэтому связь между ними нечеткая.

Лучшее решение

Если мы дисциплинированы, нам поможет Sass/SCSS. Можно получить нужный нам контекст, если занести все z-index в переменные.

$z-index-page: 100;
$z-index-navigation: 200;
$z-index-newsletter-modal: 300;

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

Я обычно использую сотни, чтобы можно было вставить другие значения z-index между основных при необходимости. Это не так важно, если все z-index хранятся, как показано выше. Вы можете просто обновить все значения в одном месте.

5. Вы обязаны использовать его

Как и JS, CSS — де факто язык браузера. Это единственная возможность стилизовать веб-страницы, поэтому ее необходимо принять как есть. Надеюсь, когда-то браузеры перестанут зависеть от языков. Когда-то.

С другой стороны, CSS используется (справедливо) однообразно в разных платформах и не отгораживается, как iOS, Android и остальные технические экосистемы.

Лучшее решение

Увольняйтесь с front end разработки. Если это не выход, вам придется использовать CSS.

Источник: https://www.joeforshaw.com/

Редакция: Команда webformyself.