Style scoped что это
Атрибут ‘scoped’ элемента ‘style’
Введение
В этой статье я бы хотел рассмотреть одно из ново введений в HTML5, связанное с отображением содержимого документа, а именно атрибет ‘SCOPED’ для элемента ‘STYLE’. Сразу предупрежу, что данный атрибут пока находится в стадии разработки и не поддерживается ни одним браузером на сегодняшний день, но заслуживает внимания.
Основная часть
Атрибут ‘SCOPED’ является логическим. Если данный атрибут присутствует, это означает что стили будут применяться к дереву элементов корнем которого является элемент внутри которого находится элемент ‘STYLE’, а не ко всему документу. Причем элемент ‘STYLE’ должен быть первым элементом корневого элемета.
WHATWG
Где это можно использовать
Как это работает
В качестве примера я буду использовать следующий код:
Теперь изменим цвет текста у второго параграфа на красный:
Вот как это могло бы выглядеть в браузерах:
Для того чтобы применять внешние таблицы стилей в определенном контексте предлогается использовать следующий код.
Обратная совместимость
К несчастью данный атрибут не определяется браузерами. И поэтому если вы попытаетесть использовать этот атрибут вместе с элементом ‘STYLE’ то стили просто применяться ко всей странице.
Для обратной совместимости, как альтернатива был предложен(Louis Lazaris-ом) новый элемент ‘SCOPEDSTYLE’.
Использование ‘SCOPED’ сегодня
Если вы хотите использовать эту функциональность сегодня, для этого есть плагин для jQuery scoped CSS plugin on GitHub от Simon Madine.
Атрибут ‘scoped’ элемента ‘style’
Введение
В этой статье я бы хотел рассмотреть одно из ново введений в HTML5, связанное с отображением содержимого документа, а именно атрибет ‘SCOPED’ для элемента ‘STYLE’. Сразу предупрежу, что данный атрибут пока находится в стадии разработки и не поддерживается ни одним браузером на сегодняшний день, но заслуживает внимания.
Основная часть
Атрибут ‘SCOPED’ является логическим. Если данный атрибут присутствует, это означает что стили будут применяться к дереву элементов корнем которого является элемент внутри которого находится элемент ‘STYLE’, а не ко всему документу. Причем элемент ‘STYLE’ должен быть первым элементом корневого элемета.
WHATWG
Где это можно использовать
Как это работает
В качестве примера я буду использовать следующий код:
Теперь изменим цвет текста у второго параграфа на красный:
Вот как это могло бы выглядеть в браузерах:
Для того чтобы применять внешние таблицы стилей в определенном контексте предлогается использовать следующий код.
Обратная совместимость
К несчастью данный атрибут не определяется браузерами. И поэтому если вы попытаетесть использовать этот атрибут вместе с элементом ‘STYLE’ то стили просто применяться ко всей странице.
Для обратной совместимости, как альтернатива был предложен(Louis Lazaris-ом) новый элемент ‘SCOPEDSTYLE’.
Использование ‘SCOPED’ сегодня
Если вы хотите использовать эту функциональность сегодня, для этого есть плагин для jQuery scoped CSS plugin on GitHub от Simon Madine.
Стилизация однофайловых Vue компонентов
Эта статья — перевод оригинальной статьи Lindsay Wardell «Styling Vue Single-File Components»
Также я веду телеграм канал “Frontend по-флотски”, где рассказываю про интересные вещи из мира разработки интерфейсов.
Вступление
Если у вас есть опыт написания однофайловых Vue компонентов, вы, вероятно, сталкивались с написанием CSS в своем компоненте. Они позволяют разработчикам группировать код более логическими способами, а не разбивать компоненты по используемому языку (HTML, CSS или JavaScript). Возможность группировать стили компонентов непосредственно рядом с HTML-кодом, к которому он применяется, является одним из основных преимуществ Vue, включая возможность применять CSS к компоненту, чтобы он не влиял на другие части пользовательского интерфейса.
Однако есть ряд функций взаимодействия Vue с CSS, с которыми вы, возможно, не знакомы, например, применение стилей непосредственно к элементам со слотами или новейшие функции, доступные в Vue 3.2. Давайте рассмотрим некоторые из этих других способов стилизации однофайловых Vue компонентов и их преимущества для ваших приложений.
Scoped стили
Начнем с наиболее частого использования CSS в Vue: стили с ограниченными областями видимости. Одна из трудностей при написании современных приложений заключается в том, что наши CSS файлы начинают расти все больше и больше, пока никто не знает, где используются определенные стили или на что может повлиять данное изменение. Это может привести к копированию определенных CSS селекторов и простому дублированию их для каждого компонента. Для этого есть и другие решения (например, БЭМ или служебные классы), но при работе с компонентной структурой, такой как Vue, имеет смысл сгруппировать классы CSS внутри компонента.
Стили с ограниченной областью видимости позволяют нам писать CSS, который применяется только к компоненту, с которым мы работаем. Вот пример из документации Vue:
Класс из примера будет применяться только в этом компоненте. Это достигается путем добавления уникального атрибута data ко всем элементам в компоненте, поэтому по-прежнему применяется обычный CSS каскад. Внешние стили по-прежнему могут влиять на дизайн этого компонента, но его стили с областью видимости не могут проникать в другие компоненты.
Глубокие стили
Это приводит к интересной проблеме. Если стили нашего компонента имеют ограниченную область видимости, как насчет дочерних компонентов? По умолчанию они не получат стили родительского компонента. Однако Vue предоставляет способ сделать это. Давайте посмотрим на пример ниже.
Используя псевдокласс :deep(), мы можем сообщить Vue, что этот конкретный класс (.card-title) не должен иметь области видимости. Поскольку специальный идентификатор по-прежнему применяется к корневому элементу (заголовку), стиль по-прежнему ограничен, но доступен для любого дочернего компонента ниже него.
Slotted стили
Проблема, с которой я сталкивался во многих ситуациях, заключается в том, что у меня есть компонент, в который вставляются слоты, но я не могу контролировать его стиль, как хочу. Vue предлагает решение и для этого с помощью slotted стилей. Давайте рассмотрим приведенный выше пример, но на этот раз мы добавим slotted стиль к нашему компоненту Title.vue.
Глобальные стили
Конечно, иногда вам нужно применить стили глобально, даже внутри компонента с ограниченной областью видимости. Vue предоставляет нам два разных способа справиться с этим: псевдоселектор :global и несколько блоков стилей.
:global
В блоке стиля с ограниченной областью видимости, если вам нужно предоставить только один класс в качестве глобального значения, вы можете использовать псевдоселектор :global, чтобы отметить, что стиль не должен иметь области видимости. Из документации Vue:
Несколько блоков стилей
Также ничто не мешает вам иметь несколько блоков стилей в вашем компоненте. Просто создайте еще один тег
CSS модули
Если вы работали с React, вероятно, вы более знакомы с CSS модулями, в которых вы импортируете CSS файл и получаете доступ к его классам как к JavaScript объекту. То же самое можно сделать в Vue, используя
Динамические CSS значения
Этот компонент принимает число ( progress ), затем отображает это число и обновляет кастомное CSS свойство. По мере изменения хода выполнения CSS свойство постоянно обновляется, чтобы оставаться в синхронизации с JavaScript значением.
Однако в Vue 3.2 нам предоставляется специальная CSS функция, которая делает все это за нас! Взгляните на обновленный код:
Заключение
C O DEGURU
Совершенно очевидно, что CSS далёк от совершенства. При разработке больших комплексных проектов глобальная природа CSS легко может привести к появлению конфликтующих стилей, а наследование часто приводит к тому, что стили применяются не к тем, вернее не только к тем, элементам, которые мы имели в виду. Справедливости ради следует отметить, что большинство подобных ошибок возникает от непонимания особенностей CSS разработчиками. Но это не отменяет того факта, что указанные недостатки у CSS имеются, и даже опытный разработчик может стать их жертвой.
Чаще всего для борьбы с глобальной природой CSS используется методология БЭМ (Блок Элемент Модификатор). Но это решает только небольшую часть проблемы.
К счастью для нас коммьюнити уже разработало решение, которое поможет нам справиться с проблемами CSS. Вы, возможно, уже слышали о CSS Модулях, Стилизованных компонентах, Glamorous или JSS — это наиболее популярные инструменты, которые вы можете использовать в своих проектах уже сегодня. Если вам интересна эта тема, почитайте этот пост. В нём Индрек Ласн подробно описывает идею CSS-in-JS.
Каждое Vue.js приложение, созданное с помощью vue-cli, уже имеет на вооружении два мощных инструмента: Изолированный CSS (Scoped CSS) и CSS Модули. У каждого из них есть свои преимущества и недостатки. Давайте рассмотрим подробнее и определимся с тем, какое решение подойдёт вам.
Изолированные стили
Для подключения изолированных стилей необходимо добавить атрибут scoped в тэг style:
Это приведёт к тому, что стили применятся только к элементам компонента. В результате в скомпилированном виде стили будут выглядеть вот так:
Как видите это довольно просто. Всего одно слово — и у вас есть изолированные стили для компонента.
Теперь, если нужно, например, поменять ширину компонента на какой-то странице, просто добавляем класс и стилизуете его как необходимо:
И опять, без малейших усилий вы полностью контролируете стили.
Однако, у этого метода есть один серьёзный недостаток — если у корневого элемента дочернего компонента есть такой класс, как у родителя, то стили родителя применятся к дочернему компоненту. Посмотрите этот пример, чтобы увидеть это на практике.
CSS Модули
CSS Модули стали очень популярны благодаря коммьюнити React, которое активно использует и развивает этот инструмент. Vue.js, в свою очередь, выводит его на новый уровень, объединяя мощь с простотой использования и поддержкой «из коробки» при использовании vue-cli.
Давайте посмотрим, как использовать CSS модули:
Тут всё не намного сложнее, чем при использовании изолированных стилей. Вместо атрибута scoped мы используем атрибут module. Этот атрибут сообщает компилятору шаблонов, что необходимо использовать соответствующий загрузчик, который сгенерирует следующий CSS:
Это сгенерирует следующий HTML и стили:
Одно из преимуществ CSS модулей в том, что глядя на элемент в HTML мы сразу видим какому компоненту он принадлежит. Второе преимущество — всё работает очень предсказуемо и мы полностью контролируем процесс. Однако, необходимо проявлять осторожность при стилизации HTML тэгов. В отличие от изолированных стилей, при использовании CSS модулей стилизованные тэги в финальном файле будут стилизованы как есть (без уникального атрибута data), и окажут влияние на всё приложение. В любом случае, стилизовать тэги напрямую — плохая идея.
Теперь давайте посмотрим как стилизовать компонент в зависимости от контекста:
Представьте, что вы делает график и храните переменные с цветами в CSS. Вы можете экспортировать их для использования в компоненте:
Мы взглянули на очень небольшую часть того, что могут CSS модули. Их возможности гораздо шире и я настоятельно рекомендую вам ознакомиться с полной спецификацией.
Заключение
Оба решения очень просты в использовании и отлично выполняют свою задачу. Какое же выбрать?
Изолированные стили не требуют дополнительных знаний. Имеющиеся у них ограничения делают их использование очень простым. Они отлично подойдут для проектов небольшого и среднего размера.
Всё, что вы хотели знать об областях видимости в JavaScript (но боялись спросить)
У JS есть несколько концепций, связанных с областью видимости (scope), которые не всегда ясны начинающим разработчикам (и иногда даже опытным). Эта статья посвящена тем, кто стремится погрузиться в пучину областей видимости JS, услышав такие слова, как область видимости, замыкание, “this”, область имён, область видимости функции, глобальные переменные, лексическая область видимости, приватные и публичные области… Надеюсь, по прочтению материала вы сможете ответить на следующие вопросы:
— что такое область видимости?
— что есть глобальная/локальная ОВ?
— что есть пространство имён и чем оно отличается от ОВ?
— что обозначает ключевое слово this, и как оно относится с ОВ?
— что такое функциональная и лексическая ОВ?
— что такое замыкание?
— как мне всё это понять и сотворить?
Что такое область видимости?
В JS область видимости – это текущий контекст в коде. ОВ могут быть определены локально или глобально. Ключ к написанию пуленепробиваемого кода – понимание ОВ. Давайте разбираться, где переменные и функции доступны, как менять контекст в коде и писать более быстрый и поддерживаемый код (который и отлаживать быстрее). Разбираться с ОВ просто – задаём себе вопрос, в какой из ОВ мы сейчас находимся, в А или в Б?
Что есть глобальная/локальная ОВ?
Не написав ни строчки кода, мы уже находимся в глобальной ОВ. Если мы сразу определяем переменную, она находится в глобальной ОВ.
Глобальная ОВ – ваш лучший друг и худший кошмар. Обучаясь работе с разными ОВ, вы не встретите проблем с глобальной ОВ, разве что вы увидите пересечения имён. Часто можно услышать «глобальная ОВ – это плохо», но нечасто можно получить объяснение – почему. ГОВ – не плохо, вам нужно её использовать при создании модулей и API, которые будут доступны из разных ОВ, просто нужно использовать её на пользу и аккуратно.
Все мы использовали jQuery. Как только мы пишем
мы получаем доступ к jQuery в глобальной ОВ, и мы можем назвать этот доступ пространством имён. Иногда термин «пространство имён» используют вместо термина ОВ, однако обычно им обозначают ОВ самого уровня. В нашем случае jQuery находится в глобальной ОВ, и является нашим пространством имён. Пространство имён jQuery определено в глобальной ОВ, которая работает как ПИ для библиотеки jQuery, в то время как всё её содержимое наследуется от этого ПИ.
Что такое локальная ОВ?
Локальной ОВ называют любую ОВ, определённую после глобальной. Обычно у нас есть одна ГОВ, и каждая определяемая функция несёт в себе локальную ОВ. Каждая функция, определённая внутри другой функции, имеет своё локальное ОВ, связанное с ОВ внешней функции.
Если я определю функции и задам внутри переменные, они принадлежат локальной ОВ. Пример:
Все переменные из ЛОВ не видны в ГОВ. К ним нельзя получить доступ снаружи напрямую. Пример:
Переменная “name” относится к локальной ОВ, она не видна снаружи и поэтому не определена.
Функциональная ОВ.
Все локальные ОВ создаются только в функциональных ОВ, они не создаются циклами типа for или while или директивами типа if или switch. Новая функция – новая область видимости. Пример:
Так просто можно создать новую ОВ и локальные переменные, функции и объекты.
Лексическая ОВ
Если одна функция определена внутри другой, внутренняя имеет доступ к ОВ внешней. Это называется «лексической ОВ», или «замыканием», или ещё «статической ОВ».
С лексической ОВ довольно просто работать – всё, что определено в ОВ родителя, доступно в ОВ ребенка. К примеру:
В обратную сторону это не работает:
Всегда можно вернуть ссылку на “name”, но не саму переменную.
Последовательности ОВ
Последовательности ОВ определяют ОВ любой выбранной функции. У каждой определяемой функции есть своя ОВ, и каждая функция, определяемая внутри другой, имеет свой ОВ, связанный с ОВ внешней – это и есть последовательность, или цепочка. Позиция в коде определяет ОВ. Определяя значение переменной, JS идёт от самой глубоко вложенной ОВ наружу, пока не найдёт искомую функцию, объект или переменную.
Замыкания
Живут в тесном союзе с лексическими ОВ. Хорошим примером использования является возврат ссылки на функцию. Мы можем возвращать наружу разные ссылки, которые делают возможным доступ к тому, что было определено внутри.
Чтобы вывести на экран текст, недостаточно просто вызвать функцию sayHello:
Функция возвращает функцию, поэтому её надо сначала присвоить, а потом вызвать:
Можно конечно вызвать замыкание и напрямую:
Можно догадаться, что упрощённо их код выглядит примерно так:
Функция не обязана ничего возвращать, чтобы быть замыканием. Любой доступ к переменным извне текущей ОВ создаёт замыкание.
ОВ и ‘this’
Каждая ОВ назначает своё значение переменной “this”, в зависимости от способа вызова функции. Мы все использовали ключевое слово this, но не все понимают, как оно работает и какие есть отличия при вызовах. По умолчанию, оно относится к объекту самой внешней ОВ, текущему окну. Пример того, как разные вызовы меняют значения this:
Встречаются и проблемы со значением this. В следующем примере внутри одной и той же функции значение и ОВ могут меняться:
Здесь мы создали новую ОВ, которая вызывается не из обработчика событий, а значит, относится к объекту window. Можно, например, запоминать значение this в другой переменной, чтобы не возникало путаницы:
Иногда есть необходимость менять ОВ в зависимости от того, что вам нужно.
В примере:
Значение this не относится к перебираемым элементам, мы ничего не вызываем и не меняем ОВ. Давайте посмотрим, как мы можем менять ОВ (точнее, мы меняем контекст вызова функций).
.bind() не вызывает функцию, а просто привязывает значения переменных перед её вызовом. Как вы знаете, мы не можем передавать параметры в ссылки на функции:
Это можно исправить, создав новую вложенную функцию:
Приватные и публичные ОВ
В JavaScript, в отличии от многих других языков, нет понятий публичных и приватных ОВ, но мы можем их эмулировать при помощи замыканий. Для создания приватной ОВ мы можем обернуть наши функции в другие функции.
Но вызвать эту функцию напрямую нельзя:
Вот вам и приватная ОВ. Если вам нужна публичная ОВ, воспользуемся следующим трюком. Создаём пространство имён Module, которое содержит всё, относящееся к данному модулю:
Директива return возвращает методы, доступные публично, в глобальной ОВ. При этом они относятся к нужному пространству имён. Модуль Module может содержать столько методов, сколько нужно.
Не нужно стараться вываливать все методы в глобальную ОВ и загрязнять её. Вот так можно организовать приватную ОВ, не возвращая функции:
Мы можем вызвать publicMethod, но не можем privateMethod – он относится к приватной ОВ. В эти функции можно засунуть всё что угодно — addClass, removeClass, вызовы Ajax/XHR, Array, Object, и т.п.
Интересный поворот в том, что внутри одной ОВ все функции имеют доступ к любым другим, поэтому из публичных методов мы можем вызывать приватные, которые в глобальной ОВ недоступны:
Это повышает интерактивность и безопасность кода. Ради безопасности не стоит вываливать все функции в глобальную ОВ, чтобы функции, которые вызывать не нужно, не вызвали бы ненароком.
Пример возврата объекта с использованием приватных и публичных методов:
Удобно начинать название приватных методов с подчёркивания, чтобы визуально отличать их от публичных:
Удобно также возвращать методы списком, возвращая ссылки на функции: