Pull to refresh

Comments 36

Модульный CSS реально вещь! Столкнулся с ним недавно при изучении Angular2 на небольшом проекте, очень удобная штука как оказалась: самое важное тут то, что более не нужно хранить контекст селекторов. Т.е. вот в новом ангуляре, ты работаешь с каким-то компонентом интерфейса: у тебя в этом компоненте и логика вся основная тут, и шаблон чисто под компонент, и стили которые применяются только к этому компоненту — это реально круто!

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

Затем появилась связка virtual dom + es6/browserify imports, и всё, чего ей не хватало, это изолированные стили.
Теперь, возможно, и так неспешное внедрение shadow dom'а затянется ещё сильнее. Посмотрим!
CSSModules круты да, но этого не достаточно против
*{
 //
}


рекомендую еще postcss-initial и postcss-autoreset.
Это, безусловно, круто и нужно. Напрягает только кривление (или кривляние?) душой: ведь по сути проблема глобальной природы CSS никуда не делась, и это решение — просто ещё один БЭМ, только автоматизированный. Очередной костыль. А раз костыль, то, по закону дырявых абстракций, где-нибудь он вылезет боком.
Я люблю webpack и, скорее всего, попробую использовать этот инструмент, но, все-таки, очень хочется, чтобы вещи называли своими именами, не превознося один способ обходить ограничения технологий над другим.
Ну вы уж определитесь, вам нужна или кроссбраузерная реализация, или обратно несовместимая переделка CSS.
Я за кроссбраузерность.
Совсем не вижу, каким боком этот костыль может вылезти, кроме отладки на продакшене.
Я за то, чтобы не пиарить на недостатках других решений собственное, имеющее, по сути, те же самые недостатки, ибо природа используемой технологии не изменилась от того, что придумали инструмент.
Так не должно быть. Пора оставить позади эру глобальных стилей. Наступило время закрытого CSS.

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

Всё изменилось 22 Апреля 2015

Это ложь. Селекторы так и остались глобальными. Просто работать с ними стало удобнее. И за это автору решения большое спасибо. Равно как и переводчику за проделанную работу.
Согласен, что звучит громковато и это тоже способ борьбы с существующей проблемой, а не её устранение. Но подход к решению как раз совсем другой — не такой хрупкий, как у существующих «ручных» методик по именованию классов. И он действительно меняет подход к написанию css.

При разработке, в общем-то, важно, чтобы решение работало. Например, какая разница, используется ли browserify, webpack или нативный браузерный es6 import, если в любом случае мы пишем строчку

import Module from './Module';

и эта строчка работает? Безо всяких поправок на то, как именно обеспечили её работу. Да, абстракции дают протечки, и хорошо знать, что там под капотом, но это не значит, что абстракции плохая концепция. Ими можно и нужно пользоваться.
UFO just landed and posted this here
Вот это жесть… К смешанному HTML и JavaScript домешали немного CSS с кастомным синтаксисом — и получилось вообще непонятно что.

Используйте веб-компоненты — естественный способ создания элементов, где HTML, JavaScript, CSS лежать отдельно, CSS не находится в глобальной области видимости и всё работает по стандартах без всяких WebPack.

С такими системами сборки можно сломать всё — сначала ноги, потому руки, а в конце и голову.
Если хотите всё в кучу намешать — что ж, Polymer позволяет и так, хотя четкое разделение всё же остается, просто в одном файле:

<dom-module id="my-element">
    <template>
        <style>
            .super {color: red;}
        </style>
        <div class="super">Hello, red!</div>
    </template>
    <script>
        Polymer({
            is : 'my-element'
        });
    </script>
</dom-module>


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

Не усложняйте веб, всё может быть гораздо проще.
Веб-компоненты — отличная идея, а <template></template> с собтвенным тэгом <style></style> — офигительно удобно.

Проблема в том, что до их внедрения ещё не скоро. Shadow DOM — штука, под которую практически невозможно сделать полифилл.

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

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

А импорт css внутри javascript модуля я бы не назвал «мешаниной». Это идея цельного компонента. Ингредиенты: html, css, javascript. Вполне логично, когда они вместе. Web components ведь о том же говорят :)
На самом деле полифил уже есть несколько лет как и используется на многих сайтах в продакшене. Да, он не идеален, но работает очень даже хорошо. И для работы Polymer не нужно ничего настраивать, вся настройка заканчивается на одной строчке:

<link rel="import" href="polymer.html">

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

На счёт импорта согласен, вопрос скользкий, но как по мне, так импорт CSS/JS из HTML как-то более естественно чем CSS из JS + HTML тоже внутри JS. Делает то же самое, но как-то вывернуто всё с ног на голову.
Называется он ShadyDOM, и не дает 100% инкапсуляции. Чисто на бытовом уровне, да это отлично. Сам когда-то любит полимер)
Отчасти вы правы. Но не полностью. Если показать более полный пример:

<script src="webcomponents.js"></script>
<script>Polymer = {dom: 'shadow'};</script>
<link rel="import" href="polymer.html">

То будет у вас таки Shadow DOM (полифил для браузеров без нативной поддержки), это то что я имел ввиду, Shady DOM считаю весьма кривым компромиссом и поэтому не использую (имхо).
Я понимаю, но к сожалению на продакшене практически не используется из за малой поддержки и малой производительности на мобильных устройствах. Хоть полифиль хоть не полифиль, полимер еще очень костлявый. По этому комьюнити крутится вокруг того, что уже есть и что работает отлично.
как-то более естественно чем CSS из JS + HTML

В случае полимера контейнером является html, в случае с react jsx ну или js.
Вы говорите о производительности Polymer 0.5 или 1.x? Хотя по моему опыту даже 0.5 отлично бегает на iOS/Android с нормальным браузером (под нормальным я не имею ввиду встроенный браузер Android < 5)
Да в первом существенно улучшили, но все равно это не сравнимо. Понятное дело моб платформа развивается и будет мощней. Но сейчас, он сыроват и приубавил пыл после google IO. Между прочим на серваке даже отрендерить нельзя, что опять же важно, не говоря уже о размерах билда и нативе :))
Судя по статье и примерам, такой подход пытается решить самораздутую проблему с глобальной областью видимости с CSS это всё. При этом, во-первых, нифига её не решает, т.к. единственная разница в конечном CSS, так это названия селекторов в CSS станут короче. Во-вторых отхватите проблемы с кривыми импортами, дублированием импортов или импортом не того и не туда. В-третих, как это все замечательно будет смотреться в девтулзах, когда в браузере на проде ты видишь селектор ._1rJwx92-gmbvaLiDdzgXiJ { … } и не понимаешь откуда он.
Возможно, вы невнимательно прочитали статью.

такой подход пытается решить самораздутую проблему с глобальной областью видимости с CSS это всё

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

При этом, во-первых, нифига её не решает, т.к. единственная разница в конечном CSS, так это названия селекторов в CSS станут короче

Как это? Разница в том, что имена классов будут уникальными. Не «может быть уникальными», а уникальными. При этом исходный код содержит понятные и уместные названия.

Во-вторых отхватите проблемы с кривыми импортами, дублированием импортов или импортом не того и не туда

С чего вдруг? А при импорте .js файлов таких проблем нет? В чем разница?

В-третих, как это все замечательно будет смотреться в девтулзах, когда в браузере на проде ты видишь селектор ._1rJwx92-gmbvaLiDdzgXiJ { … } и не понимаешь откуда он

Именно этот вопрос в статье описан и решается просто и удобно для дев-режима. А на проде minified, uglified и concatenated javascript вы легко читаете? :)
Может я не правильно понял автора, мне показалось что проблема с глобальной обласью видимости заключается в 2-ух вещах: первая, то что все висит в глобальной области видимости, вторая, вытекает из первой, то что приходится писать длинные имена, чтобы небыло конфликтов селекторов, например: .button {} для первого виджета и .button {} для второго виджета.
Первую проблему описанный подход вообще никак не решает. Вторая проблема решается на уровне облегчения придумывания имен селекторов. Вот второй кейс мне и кажется раздутым.

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

Это как вообще? Импорты теперь анти-паттерн и опытные разработчики не используют их, чтобы не огрести проблем с импортом «не туда»? :D
В-третих, как это все замечательно будет смотреться в девтулзах, когда в браузере на проде ты видишь селектор ._1rJwx92-gmbvaLiDdzgXiJ { … } и не понимаешь откуда он.

Source maps
Если смотреть на предлагаемое решение, из него видно, что стили из MyComponent.css импортятся в некий неймспейс 'styles'.
Если же говорить об JS импортах, то там разруливание наймспейса идет в самом файле, т.е. вы не сможете запороть неймспейс, например, global.app неправильным импортом, запороть его сможет только код в файле.

Source maps — т.е. еще одно усложнение. Уже получается больше сложностей чем облегчений работы.

А разве бывает source map для html?
Как определять классы если верстка вынесена в отдельный html? К примеру, при использовании Marionette.
Если верстка не статическая, а шаблон, то в него можно прокинуть стили вместе с остальными данными.

Например, в Marionette:

import {ItemView} from 'backbone.marionette';
import styles from './styles.css';

export default class extends ItemView {

    serilalizeData() {
        // прокидываем стили в шаблон
        return Object.assign(super.serializeData(), {styles});
    }
}


В шаблоне

<div class={{styles.foo}}></div>
Это только для html, создаваемого на стороне клиента? А как быть нормальным людям старикам, которые возвращают уже законченную страницу?

Столько пафоса из ничего…
А также для тех, кто рендерит нодой на сервере.

Пафоса многовато, может быть, да, но и не то чтобы «из ничего»
На самом деле css-modules отдают вам map оригинальных имен на уникальные. Вы можете сохранить их в json и проводить замену на своем сервере, как вам удобно.
Модульность в CSS таки есть — это инлайн-стили. Тем не менее, каждый проект требует своего подхода.
Спасибо за перевод! Хоть я и считаю предложенный вариант полным трешем, но все равно рад, что все больше становится тем о веб-компонентности. Рад, что к этому движется мир. Глядишь через пару лет кто-то изобретет изящное решение, которое можно будет использовать в продакшене на реальных проектах.
Пускай сначала к единым стандартам придут и решат проблему кроссбраузерности. :)
UFO just landed and posted this here
Кстати на PostCSS вышел не только CSS Modules. Тут есть новая идея — локальный ресет с помощью postcss-autoreset и postcss-intial.

Изолированный CSS означает же не только изолированные имена селекторов. Идеальный изолированный компонент можно переместить в любое место страницы и он будет работать. Но даже с CSS Modules это не так. Следующая проблема после селекторов — наследуемые стили. Например line-height: 0.

Локальный ресет в postcss-autreset вставляет сброс стилей в каждый селектор «блока» или «элемента» (избегая модификаторов).

Я в Париже подробно рассказывал про изоляцию CSS: ai.github.io/postcss-isolation
Не совсем понятная проблема. Поэтому выскажу свое предположение:
Каскадные таблицы стилей призваны идти от общего к частному. Поэтому и селекторы в глобальной области видимости, что бы его можно было использовать везде. Иначе размещенный на проекте модуль, который содержит свой индивидуальный CSS и описывает, например, уже используемый на сайте шрифт, ведет к избыточности кода.
Ну и по поводу пересекающихся именований. Что бы селектор выиграл, можно ведь использовать «important», не?
Зачем намеренно усложнять вещи, которые призваны быть простыми?
Можно понять возможность расширения функционала, или устранения очевидных проблем вроде позиционирования, кроссбраузерности.
Иначе звучит как «Установить библиотеку из 100 строк, что бы 10 строк писать в 5 строк»

Больше нет необходимости лепить длинные префиксы

Что ж он не говорит, что «теперь есть необходимость возможность лепить уникальную вебпаковкую оболочку»? (Про необходимость я не случайно упомянул, потому что появляется ряд компаний, которые услышали звон и начинают компонентную разработку возводить в ранг необходимости.)

Я бы поступал проще. Зная об этих инструментах, чтобы парировать выпады восторженных менеджеров, наслушавшихся гиков, на данном этапе вводил бы кроссбраузерное соглашение о неймспейсах для CSS, по сути — тот же BEM. Это защитит ваш код от неожиданного желания того же менеджера поддержать старые браузеры и значительно облегчит отладку, т.к. при ошибках придётся разбирать нативный код, а во втором случае неймспейсы вам будут знакомы.
Sign up to leave a comment.

Articles