разработчик
0,0
рейтинг
26 ноября 2012 в 00:12

Разработка → Код CSS «с душком» перевод tutorial

Недавно Крис Койер отвечал на вопросы читателей Smashing Magazine. Один из вопросов был о том, как распознать код CSS с «душком»:
Как можно определить, что ваш CSS пованивает? Какие признаки указывают на то, что код неоптимален или что разработчик писал его спустя рукава? На что вы смотрите в первую очередь, чтобы определить, плох или хорош код?

Я подумал, что могу расширить и дополнить ответ Криса исходя из собственного опыта.

Я работаю в BSkyB. Я делаю большие сайты — над последним из них я тружусь уже больше года. Плохой код CSS доставляет мне очень много проблем. Когда занимаешься одним сайтом месяцами, ты просто не можешь себе позволить плохой код, и его обязательно надо исправлять.

Я хочу поделиться несколькими вещами, на которые я обращаю внимание прежде всего, чтобы составить впечатление о качестве, сопровождаемости и чистоте кода CSS.

Отмена стилей


Любые правила CSS, которые отменяют ранее установленные стили (кроме случая сброса стилей) — это тревожный звоночек. Каскадные таблицы стилей по определению должны наследовать предыдущим определениям и дополнять их, а не отменять.

Любое определение вроде:

border-bottom:none;
padding:0;
float:none;
margin-left:0;

обычно не значит ничего хорошего. Если вам приходится обнулять border, то, скорее всего вы слишком рано его установили. Это трудно объяснить, поэтому приведу пример:

h2{
    font-size:2em;
    margin-bottom:0.5em;
    padding-bottom:0.5em;
    border-bottom:1px solid #ccc;
}

Здесь мы задаём элементам h2 не только размер шрифта и отступы, но и поля, и подчёркивание снизу, чтобы визуально отделить заголовок от остального контента. Но, очень может быть, что в другом месте нам не понадобятся ни поля, ни подчёркивание. Возможно, мы напишем что-то вроде:

h2{
    font-size:2em;
    margin-bottom:0.5em;
    padding-bottom:0.5em;
    border-bottom:1px solid #ccc;
}
.no-border{
    padding-bottom:0;
    border-bottom:none;
}

Теперь у нас уже 10 строк кода и уродливое имя класса. Гораздо лучше будет сделать так:

h2{
    font-size:2em;
    margin-bottom:0.5em;
}
.headline{
    padding-bottom:0.5em;
    border-bottom:1px solid #ccc;
}

8 строк, никакой отмены стилей и красивое, осмысленное имя класса.

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

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

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

Магические числа


Их я особенно ненавижу! Магическое число — это бессмысленное значение, которое используется потому, что оно «просто работает». Например:

.site-nav{
/*    [styles]   */
}
.site-nav > li:hover .dropdown{
    position:absolute;
    top:37px;
    left:0;
}

top:37px; — это магическое число. Единственная причина, по которой оно здесь — так получилось, что элементы списка имеют 37 пикселей в высоту, и выпадающие подменю должны появляться внизу элемента меню.

Проблема в том, что эти 37 пикселей — чистая случайность, и на эту константу совершенно нельзя положиться. Что если кто-то изменит размер шрифта в пункте меню, и он будет иметь 29, а не 37 пикселей в высоту? Что если в Chrome пункт меню будет иметь 37 пикселей высоту, а в IE — 36? Это число работает только в одном конкретном случае.

Никогда, никогда не используйте значения которые «просто работают». В предыдущем примере гораздо лучше было бы написать top:100%; вместо top:37px;

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

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

Магические числа — это плохо. Они быстро устаревают, они мешают другим разработчикам, их нельзя объяснить и на них нельзя положиться.

Нет ничего хуже, чем наткнуться на такое необъяснимое число в чужом коде. Зачем оно здесь? Что оно значит? Можно ли его трогать или не стоит? Я задаю эти вопросы всякий раз, как вижу такое число. И самый главный вопрос: «Как можно добиться такого же результата без магии?»

Бегите от магических чисел как от чумы!

Излишне узкие селекторы


Примерно вот такие:

ul.nav{}
a.button{}
div.header{}

Это селекторы, в которые добавлены совершенно лишние уточнения. Они плохи потому что:

  • их практически невозможно использовать повторно;
  • они увеличивают специфичность;
  • от них страдает производительность.

На самом деле их можно (и нужно) было бы записать так:

.nav{}
.button{}
.header{}

Вот теперь можно применить .nav к ol, .button к input и быстро заменить div с классом .header на элемент header, когда будем приводить сайт в соответствие с HTML5.

Хотя производительность браузера страдает от таких селекторов не очень сильно, она всё же страдает. Зачем заставлять его перебирать все элементы a в поисках класса .button, если можно ограничиться одним лишь классом? Вот ещё более экстремальные примеры:

ul.nav li.active a{}
div.header a.logo img{}
.content ul.features a.butto

Все они могут быть сильно сокращены или переписаны:

.nav .active a{}
.logo > img {}
.features-button{}

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

Жестко заданные, абсолютные значения


Так же как и магические числа, они не сулят ничего хорошего. Вот пример:

h1{
    font-size:24px;
    line-height:32px;
}

Гораздо лучше было бы написать: line-height:1.333;

Интерльиньяж всегда лучше задавать относительно, чтобы код был гибче. При изменении размера шрифта он будет меняться автоматически. А если вы зададите его в пикселях, то вам придётся писать что-то вроде этого:

h1{
    font-size:24px;
    line-height:32px;
}

/**
 * Main site `h1`
 */
.site-title{
    font-size:36px;
    line-height:48px;
}

И так каждый раз, когда изменится размер шрифта заголовка. Вот так гораздо лучше:

h1{
    font-size:24px;
    line-height:1.333;
}

/**
 * Main site `h1`
 */
.site-title{
    font-size:36px;
}

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

Кстати, это относится не только к line-height. Практически любое жестко вписанное в код абсолютное значение должно вызывать подозрение.

Единственный случай, когда действительно имеет смысл захардкодить абсолютное значение — это в случае работы со вещами, которые всегда должны иметь определённый размер, например, спрайтами.

Грубая сила


Это один из крайних частных случаев жёстко заданных магических чисел и некоторых других приёмов, которые используются, чтобы заставить вёрстку работать:

.foo{
    margin-left:-3px;
    position:relative;
    z-index:99999;
    height:59px;
    float:left;
}

Это ужасный стиль! Все эти уродливые правила наворочены с единственной целью — запихнуть элемент на нужное место любой ценой. Такой код говорит либо об очень плохо спроектированной вёрстке, либо о недостаточном понимании того, как работает блочная модель CSS, либо о том и другом одновременно.

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

Опасные селекторы


Под опасными селекторами я понимаю такие, которые намного шире, чем необходимо.Вот самый простой и очевидный пример такого селектора:

div{
   background-color:#ffc;
   padding:1em;
}

Зачем, зачем накрывать каждый div на странице этой ковровой бомбардировкой? Зачем кому-нибудь может понадобиться селектор вроде aside{}? Или header{}, или ul{}? Такие селекторы намного, намного шире чем необходимо, и ведут к тому, что нам придется отменять стили, о чём мы уже говорили.

Давайте рассмотрим пример с header{} более подробно. Многие используют этот элемент, чтобы создать шапку страницы, что совершенно правильно. Но если вы пишете стили для него вот так:

header{
    padding:1em;
    background-color:#BADA55;
    color:#fff;
    margin-bottom:20px;
}

то это уже совсем не так правильно. Элемент header вовсе не обязательно подразумевает шапку всей страницы, он может использоваться несколько раз в разных контекстах. Гораздо лучше использовать класс, например .site-header{}.

Задавать такие подробные стили для такого общего селектора очень опасно. Они просочатся в совершенно непредсказуемые места, как только вы начнёте повторно использовать этот элемент.

Убедитесь, что ваши селекторы бьют точно в цель.

Вот ещё пример:

ul{
    font-weight:bold;
}
header .media{
    float:left;
}

Когда я вижу, как стили применяются к элементу или к сильно обобщённому классу, как в этом примере, я начинаю паниковать. Я знаю, что они чересчур универсальны и у меня будут проблемы. Эти стили могут быть унаследованы в таких местах, в которых это будет совершенно нежелательно, и мне придётся их отменять.

Реактивное использование !important


Использовать !important можно. И это действительно важный инструмент. Тем не менее, его стоит использовать с умом.

!important надо использовать проактивно, а не реактивно.

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

Например, в уверены в том, что вы всегда хотите видеть ошибки красными:

.error-text{
    color:#c00!important;
}

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

А вот когда мы используем !important реактивно, то есть в ответ на возникшую проблему, когда мы запутались и вместо того, чтобы разобраться, прём напролом, тогда это плохо.

Реактивное использование !important не решает проблему, а только прячет её. Надо лечить болезнь, а не симптомы. Проблема никуда не делась, мы просто перекрыли её сверх-специфичным селектором, тогда как нужно было заняться рефакторингом и архитектурой.

ID


Этот вид «дурного запаха» очень важен при работе в большой команде. Я уже писал о том, что id — это плохо, потому что они сильно увеличивают специфичность селекторов. От них нет никакого толку, и их никогда не стоит использовать в CSS. Используйте их, чтобы связать элементы HTML с кодом на JavaScript, но не для того, чтобы задавать их стиль.

Причины этого просты:

  • id можно использовать на странице только один раз;
  • класс можно использовать сколько угодно;
  • большинство правил, применяемых к id можно разбросать по нескольким классам;
  • id в 255 раз специфичнее класса;
  • Это значит, что вам понадобится применить 256 классов к элементу, чтобы перевесить один id.

Если вам этого мало, то я уже и не знаю, что тут ещё сказать…

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

Напоследок — маленькое упражнение. Попробуйте элегантно решить эту проблему. Подсказка: так — не элегантно; и так — тоже.

Расплывчатые имена классов


Расплывчатое имя — это такое, которое недостаточно конкретно описывает назначение класса. Представьте себе класс .card. Что он делает?

Это очень расплывчатое имя, а расплывчатые имена плохи из-за двух главных причин:

  • вы не сможете догадаться, что оно означает;
  • оно настолько общее, что легко может быть случайно переопределено другим разработчиком.

Первый пункт очень прост: что означает .card? Стиль чего он задаёт? Карточки задач в системе управления проектами? Игральную карту в онлайн-казино? Изображение кредитной карты? Трудно сказать, потому что имя слишком туманное. Допустим, мы имеем в виду кредитную карту. Тогда намного лучше назвать класс .сredit-card-image{}. Да, намного длиннее, но и намного, намного лучше!

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

Этого легко можно избежать, если использовать более точные имена классов. Классы вроде .card или .user слишком туманны. Они малоинформативны и их легко случайно переопределить. Имена классов должны быть точны, насколько возможно.

Заключение


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

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

Перевод: Harry Roberts
Илья Сименко @ilya42
карма
526,7
рейтинг 0,0
разработчик
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (131)

  • –20
    Делать все классами страшновато, сейчас мне там не нужен js, а потом его там захочу, и что все переделывать?
    • +14
      А что вам мешает указать id в html и не использовать его в css?
      • –4
        Значит резервировать сразу ID но не юзать его в css, ну как вариант вполне разумно.
        А так мне вообще нравится идея классовой борьбы с id.
        • +3
          Этой идее сто лет в обед, её давно все применяют. А что мешает добавлять id только тогда, когда он понадобится?
          • +3
            Только на этой странице больше 80 id намекают вам на то, что не все и не везде.
            • –1
              Да, я преувеличил. Применяли бы все — не было бы этого пункта в статье и вашего первого комментария.
              • +3
                Да нет, вы просто хотели плюсиков, и написали не подумав, ничего страшного стадо и такое поведение одобряет, продолжайте и поглубже.
                • +5
                  Ура, плюсики!
                • НЛО прилетело и опубликовало эту надпись здесь
            • +3
              Большая часть из эти 80 используется исключительно для JS-кода.
              • –4
                То есть не все и не везде, верно?
                • +5
                  А, вы решили софистикой заняться. «Все и везде» выше были использовано приблизительно в том же смысле, что «все» во фразе «Все люди достаточно умны, чтобы не хвататься рукам за оголенные провода».
                  • 0
                    Хотя я согласен, что выражения вида «Как всем известно...», «Большинство считает...» — заведомо порочны в силу своей субъективности.
    • +7
      Щито?
  • +2
    Библия )
  • +6
    id в 255 раз специфичнее класса

    В комментариях к той статье подсказывают, что ID не в 255 раз «специфичнее» класса, он «бесконечно» более специфичен, чем класс. У некоторых браузеров есть баг, который позволяет классу переопределить идентификатор, но это нарушение в CSS.
    • +2
      Более того, Таб Аткинс говорит, что несколько недель назад исправил баг в Webkit таким образом, что 255+ классов специфичны как 255, и таким образом никогда не станут специфичнее id.
      От себя добавлю, что в Опере id специфичен как 65 536 классов, может в каких-то других, особенно 64-битных, браузерах так же или будет так же.
      • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        вот можно поиграться на эту тему dabblet.com/gist/4051137
  • –33
    хабр уже не тот…
    • +21
      Актуальный перевод хорошей статьи.
    • +6
      верстаю уже 3 года, и то нашлась полезная инфа
  • +15
    > Отмена стилей

    Этот вопрос меня давно мучит, и разумного решения я не нашел.

    Допустим, у параграфа имеются отступы:

    p { margin: 0.5em 0; }
    

    Но в определенном месте мне эти отступы не нужны. Скажем, в шапке.

    #header p {margin: 0; }
    

    Я не вижу способа отказаться от такой отмены стилей.

    Если сделать, как вы говорите (задавать отступы для параграфа более специфично), то код от этого только вырастет:

    article p,
    aside p,
    .block p,
    /* еще два десятка селекторов */
    footer p
    { margin: 0.5em 0; }
    

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

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

    Скажем, в проекте для ссылок задается огромное количество стилей: ховер, фон, скругленные углы, транзишены — строчек на десять. А потом нужно отменить этот стиль для ссылок, содержащих картинки вместо текста.

    Ситуация ужасно усугубляется тем, что HTML генерируется CMS'кой, и полного контроля над ним нет. Невозможно некоторым ссылкам добавить класс, а некоторым — нет.

    То есть ограничения CMS (да и просто наличие готового HTML-кода на тысячах страниц) не позволит решить вопрос элегантно:

    /* Применить ко всем элементам A, имеющим класс .clean-links */
    a:not(.clean-links) { transition: all 0.4s /* что там еще */; }
    a:not(.clean-links):hover { padding: 0.5em; margin: -0.5em; border-radius: 0.5em; background-color: lightblue; }
    

    Было бы здорово делать что-нибудь такое:

    /* Применить ко всем элементам A, не вложенным в элемент с классом .clean-links */
    :not(.clean-links) a { transition: all 0.4s /* что там еще */; }
    :not(.clean-links) a:hover { padding: 0.5em; margin: -0.5em; border-radius: 0.5em; background-color: lightblue; }
    

    К сожалению, это сработает, если только отменяющий класс присвоить ВСЕМ родителям, начиная с элемента HTML. :( Понятное дело, это невозможно.

    В результате приходится заниматься вот такой гадостью:

    a { transition: background-color 0.4s /* что там еще */; }
    a:hover { padding: 0.2em; margin: -0.2em; border-radius: 0.5em; background-color: lightblue; text-decoration: none; }
    
    .clean-links a { transition: none; }
    .clean-links a:hover { padding: 0; margin: 0; border-radius: 0; background-color: transparent; text-decoration: underline; }
    

    Если кто знает элегантный способ решать такую задачу, предлагайте.

    PS Код примеров высаывал из пальца, мог накосячить в мелочах.
    • +4
      С моей точки зрения, для многих ситуаций отмена стилей — вполне приемлемый способ достижения результата.
      • 0
        Я активно использую SASS, и лично меня отмена стилей расстраивает тем, что стиль нередко задается одной строчкой, а отменяется десятком, и этот десяток нужно еще составить. И выглядит это безобразно.
        • +1
          Более того, при добавлении стилей в наследуемый класс — модифицировать нужно и класс отмены, в то время как связь между этими классами совершенно не очевидна и находиться они могут ну в очень разных частях проекта, а тем более, если таких отмен десятки.
        • 0
          Давайте я на примере поясню, для каких ситуаций я считаю «отмену» приемлемой.

          Пусть у нас есть таблица и мы хотим, чтобы между столбцами были бордеры. Самый простой способ это сделать — задать правую/левую границу для всех ячеек и отменить её для последней/первой ячейки в строке. Это конечно не самый хороший пример, но в целом ситуацию вроде бы пояснил.
          • 0
            Не вижу ничего плохого в этом. А вы предлагаете для каждой строки таблицы. кроме первой и последней добавить класс?
            • 0
              Эээ, нет. Это я привел как раз как пример случая, когда, с моей точки зрения, «отмена» (отрекомендованная автором статьи) может быть вполне приемлемым приемом.
              • 0
                кстати, для примера со столбцами вполне сработает такое правило:
                .some-table td ~ td { border-left: ...; }
                и не понадобится ничего отменять :)
                • 0
                  Только такое правило, AFAIK, еще медленнее, чем .some-table td:first-child { border-left: none; }
                  • 0
                    Само собой, но речь же шла про самый простой способ :) Здесь мы снова возвращаемся к вопросу приемлемости отмены стилей в различных ситуациях. У меня, к сожалению, нет опыта вёрстки для сложных проектов, где разница между упомянутыми селекторами была бы сколько-нибудь заметна, но сдаётся мне что это неплохой пример того, когда отмена стилей приемлема — пожертвовать простотой в угоду скорости.
                • НЛО прилетело и опубликовало эту надпись здесь
      • +3
        Да если зайти на тот же sky.com, где вроде как работает автор, то присутствуют практически все признаки CSS с душком…
        Многие вещи делаются в CSS как лайфхаки (т.е. с поправкой, на то что часть кода генерится в CMS, не все браузеры показывают код идентично и т.п.). Те же обнуления зачастую позволяют сэкономить код, так как одно и то же обнуление можно применить к множеству стилей, и не дублировать его десятки раз.

        Что касается ID, то чаще всего он используется когда нужно с элементом взаимодействовать.
        А

        <header class="header">
        

        тоже весьма криво смотрится
        • +1
          В статье же сказано о том, что элемент <header> — не только для шапки сайта, и может быть использован и в других местах согласно его семантическому назначению. В такой записи нет ничего страшного — вы используете элемент <header> там, где его нужно использовать, и задаете ему класс .header, указывая тем самым, что это шапка сайта.

          Имя тега никак не связано с его классом, потому не стоит их сравнивать и заменять одно другим, они прекрасно могут существовать вместе.
        • –1
          А ещё кривее смотрится:

          <a id="super-link" class="super-link">
          

          id — для js, class — для оформления.
          • +1
            Смотрится отлично, когда вам вдруг неожиданно придется делать рефакторинг и поменять class=:«super-link» на class=«super-puper-link», вы можете быть уверенными, что ваш js по-прежнему работает.
            • 0
              Да, для этого и сделано. Но меня все равно передергивает, когда я такое пишу (хотя последнее время все меньше).
        • +1
          <header class="page_header">
          

          смотрится ещё лучше, имея в виду, что могут быть ещё content_header, menu_header и даже page_footer_header :)
    • +3
      Решение проблем просто и эленантно: не используйте селектор по элементам. Ведь каждый отдельный элемент в вёрстке имеет своё семантическое значение, а значение элемента без контекста слишком широкое чтобы на его можно было повесить какие-то общие для всей вёрстки параметры. Тот же пример с ul li который в статье может быть списком пунктов, а в навигации списком табов. Так что обходитесь без селектора по элементу и думайте как правильно назвать элемент в вёрстке, собственно об этом и статья.
      • +3
        Как же вы предлагаете оформлять, например, ссылки? В почти каждую ссылку на сайте вставить класс .link?

        Имхо, это не решение, а создание проблемы.

        Кроме того, это иногда просто невозможно (см. выше про CMS).
        • 0
          В зависимости от контекста и общих значений между ссылками. В навигации к примеру .nav-link, в статьях .post-link, если у них общие свойства которые не зависят от контекста можно и .link.
          • +3
            И зачем плодить такое счастье?
            У навигации есть блок, и я лучше сделаю .nav-link a
            Кажется люди стали забывать, что означает первая буква в CSS.
            • +1
              Только если у вас многоуровневая навигация такой способ не пройдёт, либо писать .nav-list > li > a, либо пойти другим путём и писать .nav-list .first-level-link. Когда у вас в навигации все элементы <a> одинаковы конечно удобнее будет написать .head-nav a, только в таком случае вы не учтёте что в навигацию могут добавиться какие-то специфичные ссылки и придётся отменять общие для элемента свойства.
              • 0
                почему же не ".nav-list a" для первого уровня и ".nav-list a a" — для остальных?
                • 0
                  Хотя, если у вас каждый уровень или того хуже каждый пункт особы и специфичны — разумеется у каждого пункта неизбежно будет свой класс. Я конечно допускаю, что подобное возможно и где-то даже является лучшим решением, но, имхо, это уже по своему стрёмно.
                • 0
                  Вот вёрстка

                  <ul class="nav-list">
                    <li><a>Домой</a></li>
                    <li><a>Каталог</a>
                      <ul>
                        <li><a>Такси</a></li>
                        <li><a>Шашечки</a></li>
                      </ul>
                    </li>
                  </ul>
                  


                  .nav-list a тут не прокатит.
                  • 0
                    Чего это не прокатит? Если у вас предполагается для второго уровня другие ссылки, то вполне можно написать .nav-list ul a, ну либо для вложенных ul сделать свой класс, вариантов масса. Т.е. наплодить кучу классов для ссылок, для вас не проблема, а вот сделать классы для блоков этих ссылок уже проблема.
                    Я делаю отдельные классы для ссылок, только тогда когда они не могут наследовать свойства блока.
                    • 0
                      Для первого уровня какой селектор предлагаете использовать? Со вторым проблем нет никаких, потому что он тут крайний.
                      • 0
                        .nav-list > li a
                        • 0
                          Подумайте ещё раз что вы написали.
                          • 0
                            О великий Гуру, не соизволите ли снизойти до более подробного объяснения моей ошибки?
                            • 0
                              Ваш код не исправит проблему, все <a> попадают под ваше определение.
                              • 0
                                Да, что-то я накосячил…

                                .nav-list > li > a
                                • 0
                                  Я уже предложил это выше, использование селектора > не самое лучшее решение проблемы.
                                  • 0
                                    Но вы не объяснили, почему.
                                    • 0
                                      В первую очередь потому что такой селектор треубет писать всю последовательность элементов, когда простое добавление класса нас от такой проблемы избавляет и внутри li можно разместить хоть 100 div'ов и селектор будет работать.
                                      • 0
                                        Эм… Зачем 100 div'ов внутри li в навигации?
                                        • +2
                                          Это же было преувеличение, не обязательно 100, но мало ли что нужно разместить внутри навигации, речь о том насколько просто будет добавлять элементы с <a> внутрь <li>.

                                          Я думаю ничего с вами не случится если каждой ссылке просто один класс добавите, к тому же с наличием разнообразных IDE и прочих инструментов объяснять процесс добавления классов как усложняющий работу считаю некорректным.
                                          • 0
                                            Не все верстают странички в статике.

                                            Большинство сайтов интернета работают на CMS. Возможность раздавать классы элементам по желанию верстальщика в них бывает сильно ограничена.
                                            • 0
                                              Какие CMS не позволяют полностью управлять содержимым если не всего html, то, как минимум, содержимым body?
                                              • 0
                                                Гм, прочитайте всю ветку, я уже подробно описал, в чем тут проблема.

                                                Например, тут:
                                                habrahabr.ru/post/160177/#comment_5495043
                  • 0
                    да, я действительно накосячил — подразумевалась селекция блоков, в которых а лежит, то есть что-то вроде ".nav-list a" и ".nav-list ul a" Однако обычно именно «a» для организации элементов навигации переопределять не приходится, на уровнях именно реализация ul и li различается, а их как раз логичнее через ".nav-list > li" и ".nav-list ul li" задать — соответственно первый уровень и остальные. Полагаю можно обойтись и без ">".
                  • 0
                    А если так .nav-list > a?
                    • 0
                      Предок ссылки — элемент списка, но не сам список. Это правило будет вообще нерабочим.
                    • 0
                      упс, то есть так .nav-list > li > a (в пред. накосячил просто, ссори)
                • +3
                  Вложенность ссылок недопустима по дефолту. Об остальных косяках CyberAP все верно говорит.
                  • 0
                    Сорри, действительно фигню написал ))
                    Ок, это выглядело бы ближе к .nav-list a и .nav-list ul a
                • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              Я работаю в достаточно крупном проекте, разработчиков много, поэтому, как мне кажется, наследуемость должна использовать минимально, только для задания базовых стилей. Вся остальная верстка должна писаться максимально независимой. В длинных названиях классов — тоже ничего страшного нет. И да, даже ссылки получаю свои классы, если они в каком-то контексте внешне отличаются от основных ссылок.

              Ведь постоянно появляются новые требования, функционал проекта дорабатывается, какие-то модули переносят из одних блоков в другие, какие-то обновляются, короче говоря, все двигается и преобразовывается. При этом, всем процессом управляет несколько человек. Один из ключевых способ свести количество багов к минимуму — использовать максимально изолированный стиль написания верстки.
              • +1
                Ага в результате получается как в twitter, для просмотра твита в сотню байт нужно метр скриптов и CSS загрузить.
                • +1
                  Нет. Каждый конечный набор блоков (который можно использовать, как единое целое) — это отдельный файл. При компиляции проекта наборы файлов собираются в пакет, в зависимости от нахождения кода на странице, т.е. например, если шапка у нас не меняется от страницы к странице, как и футер, она попадает с футером в отдельный css-файл. Остальные файлы группируется схожим образом.

                  В итоге каждая страница получает css-файл минимального размера, количество таких файлов так же минимально :)
                  • 0
                    Не совсем. Представьте себе, что у вас каталог товаров и каждую категорию товара (одежда, мебель, …) — верстает своя команда. Тогда на странице «выбор категории» у вас будет размер CSS = O(количества категорий). Кроме того, либо верстку каждого блока предпросмотра категории нужно вынести наверх (каскадно, простите мой французский), либо получится лоскутное одеяло. Кроме того, рано или поздно команда галстуков решит, что блок телевизоров сверстан так, как им нужно, и унаследует какой-нибудь .tv-preview-image.

                    Пример немного надуман, но смысл, полагаю, ясен.
                    • 0
                      Существуют внутренние спецификации по написанию стилей, так же в процессе разработки внутренне приложение, для упорядочивания хранения блоков верстки. В этом случае, в теории должен существовать, например, не .tv-preview-image, а .block-preview-detail-image, а потом, уже, дополнительно появится, например .block-preview-detail-image.for-tv-only. Дизайн, ведь, тоже не рождается случайным образом :) А так, в этом и идея, что любая команда берет код другой команды, применяет его в другом контексте и все прекрасно работает. Если же выходит так, что разные команды одновременно верстают одно и то же — тут уже проблема организационная, которая не зависит от подхода к описанию стилей. Кстати, еще одно преимущество — упрощается merge.

                      На счет — на странице «выбор категории» CSS будет равен 0, не очень понял, что вы имели в виду. На сайте CSS, думаю, в принципе не может быть равен 0, но если вы имели в виду, что на странице, где нет ни одной категории не выведутся стили для этих категорий — то да, это так.
                      • 0
                        Я имел в виду «о большое от количества категорий». Типа, того же порядка.

                        А если у вас есть «не .tv-preview-image, а .block-preview-detail-image» — то «наследуемость должна использоваться минимально» у вас тождественно равно «наследуемость должна использоваться разумно».

                        Никто же не говорит, что нужно картинку фотоаппарата и цену штанов одними стилями оформлять.

                        ;-)
    • 0
      HTML-код, генерируемый CMS, визуальными редакторами, пользователями, и просто содержимое любых конент-зон очень удобно окружать блоком с классом вроде .formatted, и уже внутри него задавать все отступы, выделения и другие свойства, присущие именно оформлению контента. Отступ у p это как раз такой момент.

      Для контент-зон я применяю что-то вроде этого: github.com/happyproff/yagel/blob/master/www/css/yagel/yagel.frmt.css
      • 0
        Это сгенерировано SASS'ом?

        Задолбаешься ведь окружать.

        Ради избавления от одного переопределения стилей приходится редактировать десятки шаблонов, хачить или манки-патчить код движка.
        • 0
          Это сгенерировано SASS'ом?
          Plain css.

          Задолбаешься ведь окружать.
          Не понимаю, о чём речь. На странице типового сайта в вакууме, этот класс нужно будет применить только на области, где выводится содержимое статьи / описание товара, содержимое какого-нибудь текстового блока. Итого 1 (2-3) употребления на шаблон.

          Ради избавления от одного переопределения стилей приходится редактировать десятки шаблонов, хачить или манки-патчить код движка.
          Что куда хачить-патчить, о чём речь?
          • 0
            Plain css.
            Аккуратненько! Очень похоже на выдачу SASS-компилятора:
            sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#output_style

            Не понимаю, о чём речь. На странице типового сайта в вакууме, этот класс нужно будет применить только на области, где выводится содержимое статьи / описание товара, содержимое какого-нибудь текстового блока. Итого 1 (2-3) употребления на шаблон.
            Да, и таких шаблонов множество: один материал на страницу, превьюха материала, блок в боковинке/шапке/футере, кастомная выборка материалов.

            Что куда хачить-патчить, о чём речь?
            В Drupal, к примеру, часть HTML, генерируемого движком, хранится в шаблонах, а часть — в PHP-функциях движка и модулей. Чтобы изменить последнюю, нужно перехватывать вызов этих функций.
            • 0
              Аккуратненько! Очень похоже на выдачу SASS-компилятора:
              Я своими руками написал эти строки на CSS. Не понимаю, к чему, вы твердите мне про SASS. С чем аккуратненько?

              а, и таких шаблонов множество: один материал на страницу, превьюха материала, блок в боковинке/шапке/футере, кастомная выборка материалов.
              В Drupal, к примеру, часть HTML, генерируемого движком, хранится в шаблонах, а часть — в PHP-функциях движка и модулей. Чтобы изменить последнюю, нужно перехватывать вызов этих функций.
              Очевидно, мы не понимаем друг друга. Вы говорили в самом начале о том, что задаёте отступ тегу p глобально, для всего шаблона. Вот так:
              p { margin: 0.5em 0; }
              

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

              И, хоть убей, не понимаю, к чему разговоры про Drupal, который зачем-то хранит html-шаблоны в PHP-функциях.

              Да, и таких шаблонов множество: один материал на страницу, превьюха материала, блок в боковинке/шапке/футере, кастомная выборка материалов.
              Эм, ну вы ведь всё-равно будете писать HTML и CSS для них. Думаю, можно и класс им вписать.
              • 0
                Я своими руками написал эти строки на CSS. Не понимаю, к чему, вы твердите мне про SASS. С чем аккуратненько?
                Я отмечаю высокую дисциплину написания кода по строгим правилам. Код настолько аккуратен, что неотличим от автоматически отформатированного.

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

                И, хоть убей, не понимаю, к чему разговоры про Drupal, который зачем-то хранит html-шаблоны в PHP-функциях.
                Drupal в PHP-функциях хранит не все шаблоны, а только динамически генерируемые. То есть те, где нужно динамически добавлять контент и классы. Например, навигационные меню, выборки, поля материалов, преобразование пользовательского текста (BB-код, Markdown, вики-синтаксис) в HTML и т. д…

                Разговор о Drupal я веду потому, что верстаю под Drupal. Если бы я писал статические сайты с возможностью вручную отредактировать любой конкретный элемент, я бы не заводил этот разговор. Кодерам, работающим с фреймворками, должно быть, гораздо проще в этом плане, а тем, кто работает с CMS, нередко приходится изворачиваться.

                Эм, ну вы ведь всё-равно будете писать HTML и CSS для них. Думаю, можно и класс им вписать.
                В том то и дело, что весь HTML генерируется движком. И если изменить структуру страницы или, скажем, обрамление различных блоков — просто (благодаря тому, что все это хранится в шаблонах), то переопределить такие вещи как, например, расстановка семантических классов .first, .last, .middle, .odd, .even для элементов списка, генерируемого из BB-кода, — хлопотно.

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

                И неблагодарная, ведь объем этой работы по сравнению с
                li { margin: 0.5em 0; }
                
                /* Переопределение первого и последнего элементов списка. Необходима, чтобы, к примеру, избежать двойных отступов, так как движок, допустим, вкладывает ul в p. */
                li:first-child { margin-top:    0; }
                li:last-child  { margin-bottom: 0; }
                
                /* Переопределение дефолтных отступов списка там, где они не нужны. */
                .menu li, .tabs li, #block-foo li, #block-bar li { margin: 0; }
                — огромный. А все зачем? Ради того, чтобы код был идеологически правильным?

                Кстати, на языке SASS такие переопределения делаются еще проще и читабельнее:
                .menu, .tabs, #block-foo, #block-bar
                  li
                    margin: 0
                
                (этот код генерирует такой же CSS, как в последней строчке предыдущего сниппета)

                Вы поймите меня, я как раз таки хотел бы пользоваться вашим способом, потому что он логичнее. Но в реальной жизни многие вещи приходится делать не так, как хочется.
                • +1
                  Я отмечаю высокую дисциплину написания кода по строгим правилам. Код настолько аккуратен, что неотличим от автоматически отформатированного.
                  А, конечно, я неверно вас понял, прошу прощения.

                  Про SASS. Давно хочу внедрить LESS/SASS в свои процессы. Но уже довольно давно у меня не так много вёрстки. по сравнению с разработкой. Потому и стимула особого нет. Да, это прекрасные инструменты, полностью согласен.

                  Про код. Понял, о чём вы говорили. Соглашусь. Drupal выглядит не очень выгодно на фоне чего угодно. Практически полная свобода с шаблонами существует даже в Joomla и WordPress. Не говоря уже о виджетах в таких фреймворках, как Yii.

                  Если смотреть на этот момент глобально, действительно есть проблемы. Но если взять один только класс .frmt для типографики, то, думаю, с ним не должно быть проблем даже в Drupal, ведь всё, что нужно сделать, это присвоить его блоку со статьёй. А это больше похоже на обычную часть шаблона, чем на содержимое какого-либо системного виджета (вроде пагинации, например). Одно только использование github.com/happyproff/yagel/blob/master/www/css/yagel/yagel.frmt.css невероятно облегчило мне жизнь.

                  Немного рад, что не работаю с Drupal =)
                  • 0
                    Обязательно попробую вашу рекомендацию на следующем своем сайте.

                    А про Drupal я, конечно, сгустил краски. Переопределять функции в нем очень просто, для этого используется система обратных вызовов. К примеру, если вы хотите переопределить функцию foo, вы просто добавляете в специальный файл функцию myproject-foo, и она срабатывает вместо foo.
                    • 0
                      Пример использования: people.wikimart.ru/, все блоки с контентом постов имеют класс .frmt, который и даёт их содержимому всю типографику.

                      А Drupal в этом плане похож на WordPress с его множеством функций в глобальной области видимости. Что, конечно, не осень кошерно, но работает.
                    • 0
                      Обязательно попробую

                      Обязательно попробуйте :) Использую такой подход уже 3 года и никаких лишних стилей.
  • +6
    В итоге, всегда всё определяется в опыт, наработанный каркас и набитый стиль вёрстки.
    Подобные статьи лишь подкрепляют опыт, но твоя эффективность всегда зависит от твоей же трезвой логики, за которую отвечаешь только ты.
  • +1
    Очень много дельных советов.

    Мне интересно, как бы автор работал в случае, если проект уже обернут набором стилей, в который крайне нежелательно лезть, и приходится делать массовый оверрайдинг чужой структуры.
    Например это библиотека интерфейсных контролов или другой блок стороннего производителя, версию которого вместе с таблицами стилей могут взять и обновить. Поддерживать актуальность ручками и какждый раз делать merge с собственой пропатченной версией css неудобно.
    • 0
      Включение доп. CSS в оригинальный с оверрайдом исходных данных. Сохраняется совместимость при обновлении оригинального CSS, но при этом размер кода серьёзно растёт.
  • +1
    Никогда, никогда не используйте значения которые «просто работают». В предыдущем примере гораздо лучше было бы написать top:100%; вместо top:37px;

    О да! Основная идея этого метода к разработчикам интерфейсов windows-приложений тоже относится.
    Каждый раз, как встречается криво масштабируемый сайт, или полностью «едет» интерфейс приложения в windows при системно установленном мастшабе шрифтов 150%, удивляешься — я один что ли не хочу смотреть в монитор через микроскоп, раз они в таких условиях свой интерфейс не тестируют?

  • +3
    Статья с «душком».
    Хотя некоторые из описанных моментов, вроде отмены стилей или избыточных селекторов не вызывают сомнения (хотя и тут бывают исключения из правил), далеко не со всем я согласен:

    h2{
        font-size:2em;
        margin-bottom:0.5em;
    }
    .headline{
        padding-bottom:0.5em;
        border-bottom:1px solid #ccc;
    }
    


    Что за «вредные советы»? Вы напоминаете «нерадивым» о том, что css — это _каскадные_ таблицы стилей, и сами-же об этом забываете! Задавать стиль от контекста куда логичнее:

    h2 {
        font-size:2em;
        margin-bottom:0.5em;
    }
    .news_block h2 {
        padding-bottom:0.5em;
        border-bottom:1px solid #ccc;
    }
    


    «Магические числа» — иногда без них нельзя. Увы, бывают такие дизайнерские «изыски» что иначе сверстать невозможно. Как вы предлагаете обходиться без них (магических чисел), если какой-то элемент нужно разместить на сколько-то пикселей относительно края другого? Да ни как. Далеко не всегда есть возможность указать значение в процентах (да почти никогда, на самом-то деле ). И лично я не вижу в этом никакой проблемы. А ваш пример весьма примитивен и притянут за уши.

    h1{
        font-size:24px;
        line-height:32px;
    }
    
    /**
     * Main site `h1`
     */
    .site-title{
        font-size:36px;
        line-height:48px;
    }
    

    Во первых — так быстрее; во вторых — велика вероятность, что во втором случае будет не 48 а 42 например и вам придётся пересчитывать значение в процентах. И зачем?

    «Грубая сила»
    .foo{
        margin-left:-3px;
        position:relative;
        z-index:99999;
        height:59px;
        float:left;
    }
    

    Пример вырван из контекста. Читая статью мы не можем знать на сколько оно уместно. К стати — вы почему-то не предложили «правильный» на ваш взгляд вариант.

    Это лишь малая часть спорных утверждений.
    • 0
      Статья переводная, автор вас не услышит.

      Замечания дельные.
      • 0
        да, тупанул малость
    • 0
      Про магические числа.
      В таких случаях, как вы описали, эти числа не являются магическими. Автор так называет не любые абсолютно заданные значения, а только те, которые ничем по сути не обусловлены.
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Как рассказывал Яндекс, бывают даже такие уникальные случаи, что дублируется шапка сайта. Использование классов убережет от такой проблемы. Минусов в том, чтобы в css вместо классов использовать id нету.
      • 0
        Минусы есть, и один из таких примеров привел автор.

        Рассмотрим структуру
        <div id="#header">
          <a>...</a>
          <div class="message"> <a>...</a> </div>
        </div>
        
        <div class="message"> <a>...</a> </div>
        


        Имеется блок #header, со своими цветами ссылок (#header a {...})
        Также есть блок .message, со своими цветами (.message a {...})
        Теперь вопрос: какой стиль будет применен ко второй ссылке в примере выше и как сделать, чтобы применился второй?

        Ответ: только так — .message a, #header .message a {...}

        Фактически, если некоторый блок оформляется в css при помощи своего id, этому блоку требуется свой собственный набор стилей, без возможности автоматического повторного использования других элементов страницы.
        • –1
          .header a {...}
          .message a {...}
          

          У header будет свой цвет ссылок, а у .message свой. Также по html видно, что ссылки message внутри header более специфичны, чем ссылки header'а.

          А вот если
          #header a {...}
          .message a {...}
          

          то чтобы применить цвет ссылок message в header, нужно будет писать
          #header a {...}
          #header .message a {...}
          .message a {...}
          
  • +1
    Такого маньяка, да нанять бы, завалы старого разгрести, особенно когда проект старый и запущенный.

    Видел как-то шаблон (кстати, на templatemonsters), в котором css файл весил 287 Кб (!!!!). Это он без внедренных картинок был, просто стили на все-все-все случаи жизни. Упростить такое — нереально, проще заново сверстать. Вот бы автора статьи подрядить, с его страстью к красоте.

    Правда, кроме упрощения css, надо еще как-то убедиться, что новая версия не будет «съезжать» больше, чем старая…
    • 0
      Я думаю, Крис Койер дороговато берет.
      • +1
        Я думаю, таким образом он за свои слова не совсем чтобы отвечает. Хорошо, когда все с нуля делаешь, все можно сделать красиво. Но когда получаешь в наследство «нечто», что имеет расширение .css, а в нем «мама-дорогая», то начинаешь забывать об идеалах красоты.

        Но спорить о том, что шашечки не менее важны, чем сама езда — это благодатная почва. Он — апологет идеи красоты и логичности, вот я и иронизирую, что его бы руками, да разгрести иную авгиеву конюшню, а уже потом побеседовать о красоте кода :)

        Впрочем, дядька, конечно, прав. Хоть и в куда более теоретическом виде, чем хотелось бы :)
        • 0
          Как говорится, любой каприз за ваши деньги. Если менеджер.владелец проекта понимает важность такой характеристики кода как поддерживаемость, то он выделит ресурсы (вплоть до найма отдельных людей) для рефакторинга.
          • +1
            Я говорю о том, что цена такого рефакторинга обычно не стоит получаемой пользы. Красота ради красоты — на это, и правда, идут не все, за свои-то деньги.

            По сути, за косяки и некрасивости CSS расплачиваются юзеры — своим CPU, трафиком, местом в кеше.

            Другое дело, что с тем же LESS и иже с ним куда проще поддерживать читаемость (и, простите за тафтологию, «поддерживаемость») кода — равно как при работе с модульными системами надо приучать себя держать кусочки стилей «имени модуля» не в общем файле стилей, а отдельно, и настроить систему сборки должным образом. Да Вы и сами понимаете, о чем я — в любом случае, от снобистских текстов до реалий жизни большое расстояние, и именно нам (а не автору статьи) преодолевать его так, чтобы нам было удобно и в разработке, и в дальнейшем сопровождении.
          • 0
            О, да, рефакторинг посредством специально нанятых для него случайных людей — это мечта любой команды.
            • 0
              Если команда не хочет заниматься рефакторингом, то почему нет? Причём процесс это непрерывный и совсем уж случайных людей на него не берут. По личному опыту — позиция уровня сеньора\ведущего инженера.
              • 0
                Ну, не знаю. Я уж лучше свою команду заставлю. Это какой-то лишний в моем понимании agile, когда за плугом идет борона и все перепахивает по-своему.
                И знакомый понятный код сразу превращается в незнакомый.
                • 0
                  Заставлять не всегда эффективно. Ну и не в полном отрыве друг от друга они работают. Лёгкий рефакторинг (без изменения точек входа и выхода) как правило лишь повышает читаемость, а глубокий обсуждается так, что все в курсе.
  • +1
    Отличные правила написания красивого кода. Всегда и всем советую им следовать.

    Правда есть еще кое что, о чем забыл написать автор. Можно добавить еще один пункт, противоположный последнему «Расплывчатые имена классов».

    Назовем его «Чересчур точные имена классов»
    Эта болезнь известна многим новичкам. Напимер классы:

    .blue-nav-button {
        background: #00a;
        float: left;
        color: #fff
    }
    
    .column-45 {
        width: 45%;
    }
    
    .column-10 {
        width: 10%;
    } 
    


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

    Самая очевидная и главная причина этого — это то что вам придется переписывать имя класса(!) в html коде, когда вы захотите изменить дизайн. Напимер изменить ширину колонки на 35%, или кнопку в красный цвет.
    • +4
      Проблема здесь не в чрезмерной точности имен классов, а в их несемантичности.

      Имена классов должны отражать функцию, а не оформление. Тогда с переопределением проблем не будет.

      К сожалению, существует такое явление как CSS-фреймворки, функционал которых как раз опирается целиком на несемантические классы.

      Решение — использовать SASS, решающий проблему с другого конца.

      Вместо того, чтобы писать несемантические классы в HTML:

      <aside id="sidebar" class="columns columns-24 col-6">

      можно писать семантический SASS:

      #sidebar { @include column(6); }

      Лично я использую SASS + Compass + Susy. Не представляю верстку без них.
  • 0
    С некоторыми частностями и нюансами можно поспорить (выше уже обсудили отмену стилей), но в целом — очень-очень хорошо и правильно. Согласен с автором на 99%.
    «Нужно бороться с первопричиной, а не симптомами» — это вообще была моя любимая фраза на прошлой работе по отношению к подчиненной верстальщице.
  • +1
    Должен заметить, что иногда, знание о том, что элемент с данным id является единственным на странице — очень важно. Кроме того, автор рассуждает в отрыве от реалий верстки с JS, забывая, что представление — это не только стили, в остальном замечания достаточно здравые.

    P.S. Сайт автора сверстан не лучшим образом, надо сказать.
    image
    • 0
      У андроида есть проблемы с поддержкой position: fixed. Не сайт в этом виноват.
      • 0
        Эти проблемы надо фиксить, а не оставлять. Например, iScroll или примение JS хаков. В последнем проекте, мне попалось нижнее меню с позицией fixed, которое прыгало за клавиатурой андроида, пришлось его хайдить в момент изменения размера экрана клавиатурой, а при закрытии опять показывать.
      • 0
        Не буду утверждать, но кажется у всех девайсов со сменой ориентации (landscape, portrait) есть проблема c position: fixed.
        • 0
          Не замечаю каких-то проблем на айпаде.
  • +1
    Кое с чем не согласен.
    Я не супер-специалист по CSS, но всё же не могу понять, почему от div.header{} производительность страдает больше, чем от .header{}. Должно ведь быть наоборот. Ведь если мы указываем «узкий» селектор, то он быстрее находится. В случае с div.header{} будут перебираться только теги, а в случае .header{} будут перебираться все теги. По-моему производительность пострадает, если будет перебираться больше тегов.
    Поправьте меня, пожалуйста, если я не прав.

    Для шапки я обычно делаю вообще так: body > .header {}, чтобы парсер перебирал минимум элементов.
    Сейчас не могу найти тот сайт, забыл адрес, который долго прорисовывался в браузере из-за того, что там было 10к строк в css файле, он был один на весь сайт и там не было узких селекторов вообще. Там были только .class1 {} и т.п. Этот сайт наглядно показал мне, что так как сделано там — плохо.
    • +1
      Потому что справа налево. Сначала все .header, а потом из них выбрать все которые div
      • 0
        А можно ли какой-то пруфлинк к вашему утверждению? Не могу найти, кроме рекомендаций «не делать так».
    • +1
      Производительность страдает, да. На какие-то ничтожные значения. Забавно, что всегда, когда критикуют этот подход, забывают про контраргумент: отказ от сужения селекторов, на мой взгляд, снижает читабельность кода.

      Вообще вся эта шумиха с понижением производительности очень напоминает древнюю статью Темы Лебедева, где он предлагал из HTML повыкидывать кавычки везде где можно в целях экономии трафика. Не стоит сбрасывать со счетов то, как быстро меняется ситуация все-таки.
      • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        Вообще, чисто моё личное мнение, на продакшене должно быть всегда так:
        view-source:https://www.google.ru/
        или так
        view-source:http://www.yandex.ru/

        Отказ от сужения селекторов может и повышает читабельность, чисто субъективно, но это плохо для не всегда мощных компьютеров посетителей, особенно для тех, которые держат по 15-20+ открытых вкладок одновременно. Я на старом компьютере некоторые сайты очень хорошо «чувствовал» в этом плане. И не забывайте, что создание «универсальной фиговины» — это плохо. Так что сужение селекторов — это скорее хорошо, чем плохо. Вообще, конечно, зависит от случая, я это понимаю, но в общем случае вас могут вспомнить плохим словом (например, те, кто унаследует вашу работу или те же посетители), если ваши таблицы стилей и вёрстка будет не оптимальными.
  • +2
    эх… какие все перфекционисты. Иногда вообще не возможно следовать этим правилам.
    Я создаю шаблоны под SharePoint и там как раз приходится тупо переопеделять стили основного css файла. Иначе никак.
    Так что… решения выходят не только из потребностей, но и из возможностей.
    • 0
      >Я создаю шаблоны под SharePoint
      Мои искренние и глубочайшие соболезнования. Я чуть выше писал что необходимость овверайда существующих стилей, которые нельзя трогать, это частый и мерзкий кейс, когда вся премудрость катится к черту.
  • 0
    Статья не понравилась. Куча спорных правил. Верстаю 6 лет (с тех пор, как создаю сайты). Могу сказать, что из озвученных правил, при применении на практике, возникает то количество исключений, при котором их не только неразумно, но и немыслимо называть «правилами». Здесь уже привели ряд примеров, в том числе, упомянули о таком немаловажном обстоятельстве, как код CMS. На самом деле, примеров — необозримое множество. Начиная от «меню» сайта, с вложенностью ul li (когда в CSS присутствуют последовательные конструкции #menu ul li, #menu ul li li, #menu ul li li li — при которых постоянно приходится отменять часть предшествующих стилей), и продолжая стилями параграфов и другими элементами в связке с контекстом. С другой стороны, в статье изложены принципы оптимизации CSS-кода относительно конкретных случаев употребления, когда такая оптимизация допустима, логична и просто хороша. В таком качестве можно удачно интерпретировать материал. Но не в библиозном, как оно «кричит» и «выпячивается» сейчас, взрывая мозг практиков очередным прокрустовым ложем.
    • 0
      Верстаю 6 лет (с тех пор, как создаю сайты).

      Начиная от «меню» сайта, с вложенностью ul li (когда в CSS присутствуют последовательные конструкции #menu ul li, #menu ul li li, #menu ul li li li — при которых постоянно приходится отменять часть предшествующих стилей), и продолжая стилями параграфов и другими элементами в связке с контекстом.
      Откройте для себя дочерние селекторы.
      • 0
        При чем тут это? Проблемы отмены стилей это не решает.
        • 0
          На самом деле большинства — решает. Особенно хрестоматийного примера вложенного меню.
          • 0
            Я имею ввиду, что codda это не поможет. Сомневаюсь, что он не знает про дочерние селекторы, а даже если и не знает, корень проблемы всё равно не в селекторах или классах, а в чем-то другом в его случае.
            • 0
              Всё верно, смысл сказанного не меняется.) Отмена стилей, в рассматриваемых мной случаях, является всё-таки меньшим по объёму*меньшим злом*, чем написание нового стиля. Спасибо за внимание.
  • 0
    Не являюсь поклонником БЭМ, но тут вам может быть интересна разработка Яндекса под названием БЭМ.
    • 0
      Получаемся с его использованием связка css с DOM генерируется и на человека ни разу не рассчитана, то есть это хорошо, когда ты вообще не подзреваешь куда будет завтра воткнут элемент и из чего будет собираться страницу. Мало того, для js обращений к дому предполагается специальная библиотека с функциями селекторов, иначе (пример из документации) постоянно будут образовываться конструкции вроде $('menu__item').addClass('menu__item_state_current'); А верстальщику приходится мыслить локально в рамках блоков и элементов.

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

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

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.