Как стать автором
Обновить

Комментарии 72

Я не web-разработчик и вёрстку знаю постольку поскольку, но…
Секция «Important во благо» выглядит как искусственное решение искусственно созданной проблемы
Да, так и есть. Разработчики либ добавляют импортанты к некоторым своим стилям не потому, что не знают как писать без импортантов, а чтобы не дать сломать свой код новичкам, ну или тем кто не понимает как это работает. Защита такая себе. И это больше похоже на защиту от дурака, но раз используют, значит всё таки помогает)
Есть и другой момент — «конечным» разработчикам бывает виднее, чем разработчикам либ, какой стиль они хотят получить в своём проекте. Как по мне, бездумно увлекаться !important не стоит, но тупо переопределить библиотечный стиль через !important вместо игры с селекторами — это абсолютно нормальная практика, если вам нужно не какое-то частное правило для одного элемента, а именно изменить библиотечный стиль глобально для своего проекта.
Опять же, в этом случае important нужен, только чтобы переопределить импортанты в этой либе. Если их там нет, то в этом нет необходимости. Особенно если стили надо переопределить глобально.
… и получить important во всех локальных?
Имо, правильное решение выкинуть его из библиотеки
Если бы всё так легко решалось) Ты предлагаешь переписать bootstrap?)
не обязательно переписывать. для многих проектов, особенно маленьких, достаточно выдернуть из всей библиотеки нужный кусок и вуаля. Зачем грузить целую либу ради одной модалки или навигации, в которой потом придется переопределять стили… жесть)

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

Я предлагаю решить искусственно созданную проблему с гибкостью. А переписывать для этого библиотеку или нет — это уже проблемы веб-разработчиков. (вообще, заметил за многими авторами библиотек манию запрещать модификацию поведения, вплоть до превращения хорошей библиотеки в бесполезную)
Плюсую. Я наблюдал плагины с инлайновыми стилями с !important. И проблемами в отображении.
классический пример в том же бутстрапе класс .d-none {display:none !important;} сделано для того чтобы однозначно скрыть элемент, ведь на том же элементе могут быть заданы другие display с более высоким приоритетом, например, .dropdown-menu.show { display: bock;} (пример высосан из пальца, но тем не менее)
Да, я это и имел в виду, когда описывал то как использует это бутстрап. Но именно по-этому я называл это «защитой от дурака», так как чисто по такому же совпадению разработчик может почему-то написать: .dropdown-menu.show { display: bock !important;}

И будет всё равно печаль.

Так, что этот способ существует, но сказать что он хороший или надежный — я бы не сказал.
если в этом случае не использовать !important, то придется писать display:none для всех вариантов, например в моем же примере придется прописать след правила .dropdown-menu.show.d-none { display: none;} ну и кучу кучу других
Вы попробуйте написать плагин для вордпресс и потом погоняйте его на разных вордпресс темах — вы увидите что всё поехало вкривь и вкось. Потому как автор темы посчитал что изображение обязательно быть круглым, ссылка такой то. Не говорю про input-ы и кнопки (button)
Если вы этот плагин будете отдавать в массы — то вам придется решать эти не искусственно созданные проблемы. Потому как ваш плагин будет работать с сторонними плагинами и кучей сторонних тем. А там такой зоопарк.

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

Я писал об этой проблеме и способах решения: «Верстка под контент выводимый плагином или дополнением в вордпресс» — картинка оттуда yadi.sk/i/l-If2cwF3K3txW

Ну и как вам? Надуманные проблемы или все же из жизни?
Да, в случае с плагинами и расширениями это оправданная мера. Не стопроцентная безопасность, но хоть что-то.
Моя мечта — important второго уровня. Чтобы можно было перекрыть все «обычные» important
Я боюсь в таком случае образования черной дыры, прям в браузере)
Просто иногда в библиотеках устанавливается important, и его никак не перебить, а код библиотеки править не хочется. Только с селекторами играться, чтобы приоритет повысить.
Код библиотеки править — точно плохая идея. А вот с селекторами играться, вполне здоровое решение, так как вот этот «импортант второго уровня» скорее всего сделает всё ещё хуже и ещё больше запутает.

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

А вообще, иногда стоит задуматься, точно ли надо перебивать эти импортанты в сторонней библиотеке.
1. Никогда не понимал чем плох important. Если вы стреляете себе в ногу, то это ваши проблемы.

2. > Это свойство нарушает естественный поток написанных нами правил и менее приоритетным стилям даёт наибольший приоритет
Нет. important просто повышает приоритет правила. И нет никакого «естественного потока», есть вполне логичные приоритеты селекторов, зная которые перестаешь бить себе по пальцам.
Important просто повышает приоритет правила… До наибольшего приоритета. И автор не говорит о том что important плох, а о том что каждому инструменту своя ситуация. Микроскопом тоже можно гвозди забивать.

Емнип, не до максимума, а даёт +1000 к приоритету.


То есть если к какому-то блоку применяется два взаимоисключающих правила с приоритетами 1 и 5 (то есть применится второе, первое будет затёрто), и если у каждого написать !important, то результат не изменится, а приоритеты будут 1001 и 1005, соответственно. Но если написать этот модификатор только к первому правилу, то таки-да, будет применено оно, ибо 1001 > 5.

Это задокументированное поведение? Почему +1000, а не +10? =) Логично что при одинаковом весе, в данном случае оба имеют импортант, далее будут сравниваться менее приоритетные правила, пока мы не дойдем до того момента кто был раньше определен. Но +1000 это какая то ваша выдумка, не сочтите за оскорбление.

Это слышанное однажды краем уха со слов старшего товарища. :)


Дальше внизу там обсуждение, которое мне действительно пролило свет на некоторые моменты, происходящие в царстве css'а. Например, этот комментарий про 1.0.0.0.0 и эта статья про 256 классов и id. Мне ещё многому предстоит научиться. `:)

Так 1,0,0,0 и 1000 это разные вещи =) А статья насчет 256 интересная, спасибо.
Да, так и работает. Я про это не писал, так как написал сноску про то, что читая эту статью вы уже должны быть знакомы с тем как работает специфичность)
А так может быть 10 > 50? Немного не понятно объяснял человек и я был сбит с толку.
Да, может запутано. Но там не 10 > 50, а 10010 > 00050 имелось в виду.

Не совсем так. Во многих популярных руководствах вес селекторов записывают трех-четырехзначными числами, что возникает такое впечатление, но по стандарту это числа в "бесконечноричной", в крайнем случае "дофигаричной", системе:). Когда-то давно был в некоторых браузерах курьез, что 256 классов перебивали-таки один id. Но это с тех пор исправили. А !important и вовсе не перебить никаким кол-вом id, потому что по стандарту он считается отдельным уровнем происхождения и важности, который важнее специфичности.

Да, но я считаю, что его уместно учитывать в расчете веса селектора таким образом. Так как его приоритет может комбинироваться с обычным приоритетом селекторов по id, class, tag. Выглядит вполне уместно.

Не спорю, общая суть верна, просто хотел предостеречь от буквальной трактовки этой "тысячи" как какой-то реальной волшебной константы

Есть такое заблуждение, когда это начинают считать «тысячей».
На деле это ж скорее 1.0.0.0.0.

Где каждая цифра это:
!important | inline | id | class | tag

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

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

Вы лишь подтверждаете те заблуждения, которые есть в сообществе по поводу important исходя из которых я и писал этот материал
Лекарство в больших количествах станет ядом, а яд в малых дозах может стать лекарством. Вопрос в нашем здравомыслии и задокументированных соглашениях о том, что и каким образом использовать. С !important то же самое. Если не регламентировать — найдутся люди, которые превратят весь CSS на проекте в important-hell и убъют производительность труда на ровном месте, а если регламентировать, на уровне методологии, как например в rscss, то important станет удобным и полезным инструментом в тулбоксе верстальщика.
Полностью согласен)

Если полноценно использовать вменяемую методологию (БЭМ или тот же rscss), то important не нужен никогда.


Его приходится использовать временно, переходя с CSS, написанного "как получилось", на вменяемую методологию: в legacy часто встречаются излишняя вложенность и, как следствие, излишняя специфичность, и единственный способ — временно — пока то legacy не переписали — поставить !important и комментарий, поясняющий, почему он временно понадобился, и когда его можно будет убрать.


Что касается "универсальных классов" — лучше их просто не делать, а для DRY использовать миксины. Бутстрап вообще пример того, как делать не надо; точнее говоря, он удобен, если дизайна вообще как такового нет, и хочется быстро сделать что-то, выглядящее прилично (типа внутренней админки) не заморачиваясь. В проекте, где бутстрап используется по назначению, кастомного CSS вообще будет минимум.

Да, насчет методологий согласен.

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

То, что бутстрап стал использоваться не по назначению где попало — это вообще одна из главных бед фронтенда :)

Но это уже совсем другая история)
Ещё есть такая штука, что инлайн-стиль с important является последним в иерархии, его переопределить никак нельзя. Например, вы раздаёте какой-то платный виджет в демо-режиме с надписью «демо» (а шаловливые негодяи могут захотеть её скрыть). Ещё вариант — поля для ввода на страницах паролей, 3D-secure и прочего, которым нужна защита от кликджакинга и похожих техник.
Да, спасибо. Я про этот случай умышленно не писал, чтобы дополнительно не путать. Но это всё сводится к тем ситуациям, о которых я сказал в конце. Что это исключения, а не регулярное использование. И как раз чаще всего и используется в плагинчиках и расширениях.

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

Да это отличный пример, спасибо! Как мы можем называться верстальщиками если не используем таких хаков :)

Используя css-modules столкнулся с проблемой, что в библиотеках иногда селекторы довольно многословны и, поэтому, имеют высокий приоритет и просто с использованием модулей (ровно как и styled-component) перебить без impotant их иногда не выходит. Жутко раздражает, хотелось бы, конечно, иметь более декларативный способ описания приоритета стиля, чем через селектор.

Так модуль же изолирует свои стили, и в пределах модуля ты можешь переопределять все что тебе нужно обычным способом. Я не совсем понял кейс, когда там нужен импортант.
JS может переназначать значения свойств только с помощью inline-стилей.

let newStyle = document.createElement( 'style' );
newStyle.textContent = '.redBorder{border:solid 5px red;}';
document.body.appendChild( newStyle );
document.body.classList.add( 'redBorder' );

PROFIT!

Надеюсь ты так никогда не делаешь в реальных задачах)

А чем работа с CSS хуже работы с отдельными элементами (да ещё и в цикле, не дай Бог, если надо с несколькими)?
А так, можно и инлайн-стили менять по разному, хоть через
element.setAttribute('style', element.getAttribute('style') + newStyle);
Это и есть перезапись инлайн-стилей. А тот вариант, что ты привёл до этого — это очень не хорошо)
Я так и написал, что это способ менять инлайн-стили.
Хотя я обычно пользуюсь традиционным element.style.fontSize = '18pt';
Но всё же: «очень не хорошо» это субъективная оценка.
А что в этом объективно нехорошо?
Ну если даже не говорить уже о том, что просто, на то, чтобы поменять один цвет в CSS будет написано 4 строки JS, то плохо как минимум то, что мы вмешиваемся в DOM и с точки зрения производительности это значительно хуже, чем просто перезапись стилей, даже инлайном.
Ну, один цвет у меня всего лишь для примера, в newStyle.textContent может быть килобайт текста :).
Впрочем, и вставка нового элемента у меня лишь для ясности способа, можно вставить текст в последний имеющийся style. И только в случае его отсутствия использовать appendChild.
Что значит «быстро»? Разве узнать необходимый вес селектора для переопределения так сложно и долго? Мы очень активно используем DevTools при разработке, и для решения этой задачи ответ у нас есть там же.



Разве это долго? Мне кажется, по времени это мало отличается от того, чтобы дописать !important, однако намного правильнее и безопаснее.


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

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

То есть я не спорю, что чем меньше !important, тем правильнее, но таки да, написать !important в основном быстрее. В этом-то и его trade-off.
Ну это ж уже следствие другой проблемы, а не импортантов. Если в проекте плохая организация кода и чтобы заменить цвет заголовка, нужно несколько часов искать все места где этот цвет назначался, то да, в таком случае используя !important ты ускоряешь процесс. Но при этом ухудшаешь и без того паршивую ситуацию)

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

!important нужно использовать только для скрытия через display: none в медиа-выражениях. Например для адаптивных хелперов. Это нужно если порядок свойств компонентов идёт после наших хелперов и мы гарантированно хотим скрыть элемент. Во всех остальных случаях повышайте специфичность селектора (потому что если вы сделали это один раз скорее всего вы сделаете это ещё раз) и используйте изоляцию стилей. Переопределять стили в атрибуте style совсем плохо. Лучше обновите сам style.

Ну это ж тоже может породить потом important поверх important'ов. Типа: мы скрываем на маленьком размере экрана какой-то блок, а потом решаем что на всех маленьких экранах он должен быть скрыт, а на маленьком экране с соотношением сторон 4:3, например, показать. И начинается та же проблема. Случай синтетический, но вполне реальный. Кажется тут тоже можно просто на весе селекторов сделать.
Это уже ошибка архитектуры, не должно быть таких правил в медиа-выражениях которые перезаписывают то что уже задано через !important. Чтобы эту проблему решить нужно указывать более конкретные условия в медиа-выражении.
Просто я не до конца понимаю зачем тут нужны импортанты в принципе. Лучший вариант не перезаписывать импортанты это не писать их вообще)
Они нужны потому что вы можете в каком-то куске кода иметь повышенную специфичность, в таком случае в этих хелперах придётся её ещё раз повышать чтобы перезаписать это правило, это можно повторять до бесконечности. Так как мы наверняка уверены что элемент должен быть скрыт то здесь оправдано использование !important, а не специфичности. Перезаписывать !important я не предлагаю, я предлагаю им перекрывать стили которые мы гарантированно хотим перекрыть и мы можем гарантировать что их не придётся перекрывать ещё раз (выше ответил как это сделать: через уточнение самих правил).
Аналогом css-правила !important для кода является использование оператора goto — пользоваться можно, но очень аккуратно и осознавая последствия.
С умом)

Вообще не использую! important, потому что всегда пишу стили от родителя. Сам Яша рекомендует использовать импортант, только в самых необходимых моментах, когда например стили слайдера у вас на 2560 строчке в файле css, а стили доп блока в слайдере вы уже написали на 30 строчке, тут можно конечно перетащить эти стили на 2561 строчку, но тогда может поехать стиль другого блока и т.д, вот поэтому и надо задавать такой селектор

Ну опять же, то, что стили в файле записаны раньше, это еще не значит, что нам нужен импортант. У нас для этого есть вес селектора и он с этим справляется. Это как раз тот случай, в котором я бы точно не советовал использовать !important
В версии сайта для слепых мне кажется очень неплохо заходит
Если я бы писал плагин, который помогает такой версии страницы стать лучше, или аналогичное расширение, то с большой вероятностью использовал бы там important. Но если это просто моя вёрстка, то в принципе, могу вполне обойтись весом селектора. По крайней мере вспоминая все такие случаи, не помню исключений.
очень спорная статья, в important нет ничего критического, можно испольлзывать для быстрого фикса пробллемы и для переопределения (но всегда с умом)
а статья разве не об этом?
сейчас перечиталл статью, сорри, речь именно об этом)

Работал в одной вебстудии, так там один верстальщик писал стили как попало и потом когда дальше стили не применялись добавлял id к элементы и стили к нему с помощью !important дописывал, я сколько ему не объяснял, что это бред, но так и не добился результата. Сам !important использую когда inline нужно переопределить или когда заказ на тестирование нового интерфейса и этот код отдельно подключается и только на время

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации