Почему не найден main.css? — CodeRoad
Примечание: Я использую Jekyll
Я пытался связать внешнюю таблицу стилей, но она не находит файл (это main.css)so), я снова попытался проверить его путь и имя, и это все равно не сработало. Вы не могли бы мне помочь?
Здесь вы можете увидеть изображение моей папки и мой код:
html css externalПоделиться Источник Pier 30 декабря 2017 в 23:26
2 ответа
1
Попробуйте добавить type="text/css"
к вашему <link>
:
<link href="_layouts/main.css" type="text/css" rel="stylesheet">
Поделиться Chesswithsean 31 декабря 2017 в 00:01
0
Ваши структуры папок, похоже, используют jekyll , если да! тогда нужно менять название папке
Поделиться PratapRockerss 31 декабря 2017 в 00:26
Похожие вопросы:
`play dist», » main. css » возвращает 404
Создайте новый образец приложения play2: play new test Затем: cd test play run Посетите http://localhost:9000 , мы увидим, что домашняя страница по умолчанию отображается правильно. Но когда я его…
Symfony 3 — {{asset(‘assets/css/main.css’)}} не работает
привязка файла CSS должна быть простой в symfony 3 в соответствии с каждым учебником и документацией. Но в моем случае это просто не работает. В моем base.html.twig году у меня есть <link…
yeoman, SCSS, bower server, styles/main.css не найден Я хотел сегодня попробовать scss поддержку yeoman. Я следовал процедуре : $ йо angular включить Twitter Bootstrap? Да , используйте SCSS-ю версию Twitter Bootstrap с Compass CSS Authoring Framework?…
Ссылка на файл main.css в index.html указывает на файл main.scss
В моем файле index.html у меня есть вот это: <link rel=stylesheet href=styles/main.css> Когда я смотрю на путь styles/, я вижу там файл main. scss. Почему вышеприведенная ссылка на main.css…
Играй! 2.3.1 — main.css 404 (государственные активы не маршрутизируются?)
Я только что загрузил семя Play Java из UI, чтобы создать новое приложение. Я написал некоторый код CSS в public/stylesheets/main.css , и это единственное изменение, которое я внес в этот проект….
CSS код в HTML и main.css
Есть идеи, почему этот код CSS не работает, когда я помещаю его в файл main.css? Я пытаюсь сделать полноэкранный фон. <html> <head> <link rel=stylesheet type=text/css…
Webpack css-loader: «модуль не найден: ошибка: не удается разрешить ‘main.css’ in …»
Я пытаюсь включить свой css в сервер, размещенный webpack-dev-server. Чтобы это произошло, я, по-видимому,должен использовать style-loader и css-loader вместе, чтобы bundle css в JavaScript. Я не…
<link rel=»stylesheet» type=»text/css» href=»main.css»/> не получилось
Я понятия не имею, почему это не работает. <!DOCTYPE html> <html lang=en> <head> <meta charset=UTF-8> <title>Title</title> <link rel=stylesheet type=text/css…
main.css файл не загружается
Вступление У меня есть два домена, http://mauricevandorst.com/ и http://tacticalmotion.nl/ . Чего я хочу Я хочу, чтобы сайт https://mauricevandorst.com/personal-page/index.html был таким же сайтом,…
Jekyll блог-сайт на git хабе — правки, внесенные в main.css, не будут применяться к файлам markdown
Каждый раз, когда я редактирую файл main.css в каталоге активов, изменения не применяются к моему сообщению в блоге, есть идеи, почему? Пожалуйста помочь.
Изоляция CSS в ASP.NET Core Blazor
- Чтение занимает 2 мин
В этой статье
Автор: Дейв Брок (Dave Brock)
Изоляция CSS упрощает использование CSS в приложении, предотвращая зависимости от глобальных стилей, и помогает избежать конфликтов стилей между компонентами и библиотеками.
Включение изоляции CSS
Чтобы определить стили, относящиеся к компоненту, создайте файл .razor.css
, соответствующий имени файла .razor
для компонента в той же папке. Этот файл .razor.css
будет файлом CSS с назначенной областью.
Для компонента Example
в файле Example.razor
создайте файл рядом с компонентом с именем Example.razor.css
. Файл Example.razor.css
должен находиться в той же папке, что и компонент Example
(Example.razor
). В базовом имени Example
файла регистр не учитывается.
Pages/Example.razor
:
@page "/example"
<h2>Scoped CSS Example</h2>
Pages/Example.razor.css
:
h2 {
color: brown;
font-family: Tahoma, Geneva, Verdana, sans-serif;
}
Стили, определенные в файле Example.razor. css
, применяются только к отображаемым выходным данным компонента Example
. Изоляция CSS применяется к элементам HTML в соответствующем файле Razor. Все объявления CSS h2
, определенные в других областях приложения, не будут конфликтовать со стилями компонента Example
.
Примечание
Чтобы обеспечить изоляцию стиля при выполнении объединения, импорт CSS в блоки кода Razor не поддерживается.
Объединение изоляций CSS
Изоляция CSS выполняется во время сборки. Blazor переписывает селекторы CSS в соответствии с разметкой, отображаемой компонентом. Переписанные стили CSS объединяются и создаются как статический ресурс. Ссылка на таблицу стилей содержится в теге <head>
wwwroot/index.html
(Blazor WebAssembly) или
(Blazor Server). Следующий элемент <link>
добавляется по умолчанию в приложение, созданное из шаблонов проектов Blazor, где заполнитель {ASSEMBLY NAME}
является именем сборки проекта:
<link href="{ASSEMBLY NAME}. styles.css" rel="stylesheet">
Следующий пример взят из размещенного приложения Blazor WebAssembly Client
. Имя сборки приложения — BlazorSample.Client
. <link>
добавляется шаблоном проекта Blazor WebAssembly при создании проекта с вариантом размещения (параметр -ho|--hosted
в .NET CLI или параметр ASP.NET Core hosted (С размещением в ASP.NET Core) в Visual Studio):
<link href="BlazorSample.Client.styles.css" rel="stylesheet">
В объединенном файле каждый компонент связан с идентификатором области. Для каждого компонента, имеющего стиль, атрибут HTML добавляется в формате b-<10-character-string>
. Идентификатор уникален и отличается для каждого приложения. В отображаемом компоненте Counter
Blazor добавляет идентификатор области к элементу h2
:
<h2 b-3xxtam6d07>
Файл {ASSEMBLY NAME}. styles.css
использует идентификатор области для группирования объявления стиля с его компонентом. В следующем примере представлен стиль для предыдущего элемента <h2>
:
/* /Pages/Counter.razor.rz.scp.css */
h2[b-3xxtam6d07] {
color: brown;
}
Во время сборки создается пакет проектов с использованием соглашения {STATIC WEB ASSETS BASE PATH}/Project.lib.scp.css
, где заполнитель
является базовым путем к статическим веб-ресурсам.
Если используются другие проекты, такие как пакеты NuGet или библиотеки классов Razor, то объединенный файл:
- ссылается на стили с помощью импорта CSS;
- не публикуется как статический веб-ресурс приложения, использующего стили.
Поддержка дочерних компонентов
По умолчанию изоляция CSS применяется только к компоненту, привязанному с помощью формата {COMPONENT NAME}.razor.css
, где заполнитель {COMPONENT NAME}
обычно является именем компонента. Чтобы применить изменения к дочернему компоненту, используйте объединение ::deep
для всех элементов-потомков в файле .razor.css
родительского компонента. Объединение ::deep
выбирает элементы, которые являются потомками идентификатора области, созданного элементом.
В следующем примере показан родительский компонент с именем Parent
и дочерний компонент с именем Child
.
Pages/Parent.razor
:
@page "/parent"
<div>
<h2>Parent component</h2>
<Child />
</div>
Shared/Child.razor
:
<h2>Child Component</h2>
Измените объявление h2
в Parent.razor.css
, добавив объединение ::deep
для указания того, что объявление стиля h2
должно применяться к родительскому компоненту и его дочерним элементам.
Pages/Parent.razor.css
:
::deep h2 {
color: red;
}
Стиль h2
теперь применяется к компонентам Parent
и Child
без необходимости создания отдельного CSS-файла с областью действия для дочернего компонента.
Объединение ::deep
работает только с элементами-потомками. Следующая разметка должным образом применяет стили h2
к компонентам. Идентификатор области родительского компонента применяется к элементу div
, поэтому браузеру известно, что нужно наследовать стили от родительского компонента.
Pages/Parent.razor
:
<div>
<h2>Parent</h2>
<Child />
</div>
При этом исключение элемента div
удаляет отношение потомков. В следующем примере стиль не применяется к дочернему компоненту.
Pages/Parent.razor
:
<h2>Parent</h2>
<Child />
Поддержка препроцессоров CSS
Препроцессоры CSS полезны для улучшения разработки CSS с помощью таких функций, как переменные, вложенность, модули, примеси и наследование. Хотя изоляция CSS изначально не поддерживает препроцессоры CSS, такие как Sass и Less, интеграция препроцессоров CSS происходит прозрачно, поскольку компиляция препроцессора выполняется до того, как Blazor перезаписывает селекторы CSS в процессе сборки. С помощью Visual Studio, например, настройте существующую компиляцию препроцессора в качестве задачи перед сборкой в диспетчере выполнения задач Visual Studio.
Многие сторонние пакеты NuGet, такие как Delegate.SassBuilder, могут компилировать файлы SASS и SCSS в начале процесса сборки перед выполнением изоляции CSS, и дополнительная настройка не требуется.
Конфигурация изоляции CSS
Изоляция CSS может работать без дополнительных настроек, но она предоставляет возможности конфигурации для некоторых сложных сценариев, например при наличии зависимостей от существующих инструментов или рабочих процессов.
Настройка формата идентификатора области
По умолчанию для идентификаторов областей используется формат b-<10-character-string>
. Чтобы настроить формат идентификатора области, измените шаблон в файле проекта:
<ItemGroup>
<None Update="Pages/Example.razor.css" CssScope="my-custom-scope-identifier" />
</ItemGroup>
В предыдущем примере CSS, сформированный для Example. razor.css
, изменяет свой идентификатор области с b-<10-character-string>
на my-custom-scope-identifier
.
Используйте идентификаторы областей, чтобы обеспечить наследование файлов CSS с назначенной областью. В следующем примере файла проекта файл BaseComponent.razor.css
содержит общие стили для компонентов. Файл DerivedComponent.razor.css
наследует эти стили.
<ItemGroup>
<None Update="Pages/BaseComponent.razor.css" CssScope="my-custom-scope-identifier" />
<None Update="Pages/DerivedComponent.razor.css" CssScope="my-custom-scope-identifier" />
</ItemGroup>
Используйте оператор подстановочного знака (*
), чтобы предоставить идентификаторы областей для нескольких файлов:
<ItemGroup>
<None Update="Pages/*.razor.css" CssScope="my-custom-scope-identifier" />
</ItemGroup>
Изменение базового пути для статических веб-ресурсов
Файл scoped. styles.css
создается в корне приложения. Чтобы изменить путь по умолчанию, используйте свойство StaticWebAssetBasePath
в файле проекта. В следующем примере файл scoped.styles.css
и остальные ресурсы приложения размещаются по пути _content
:
<PropertyGroup>
<StaticWebAssetBasePath>_content/$(PackageId)</StaticWebAssetBasePath>
</PropertyGroup>
Отключение автоматического объединения
Чтобы отказаться от того, как Blazor публикует и загружает файлы с заданной областью во время выполнения, используйте свойство DisableScopedCssBundling
. При использовании этого свойства за получение изолированных файлов CSS из каталога obj
и их публикацию и загрузку во время выполнения отвечают другие средства или процессы:
<PropertyGroup>
<DisableScopedCssBundling>true</DisableScopedCssBundling>
</PropertyGroup>
Поддержка библиотеки классов Razor (RCL)
Когда библиотека классов Razor (RCL) предоставляет изолированные стили, атрибут href
тега <link>
указывает на {STATIC WEB ASSET BASE PATH}/{ASSEMBLY NAME}. bundle.scp.css
со следующими заполнителями:
{STATIC WEB ASSET BASE PATH}
: базовый путь к статическому веб-ресурсу.{ASSEMBLY NAME}
: имя сборки библиотеки классов.
В следующем примере:
- Базовый путь к статическому веб-ресурсу —
_content/ClassLib
. - Имя сборки библиотеки классов —
ClassLib
.
wwwroot/index.html
(Blazor WebAssembly) или Pages_Host.cshtml
(Blazor Server):
<link href="_content/ClassLib/ClassLib.bundle.scp.css" rel="stylesheet">
Дополнительные сведения о RCL и библиотеках классов Razor см. в следующих статьях:
Как на самом деле работает position: sticky в CSS — Веб-стандарты
У position: sticky
уже очень неплохая браузерная поддержка, но большинство разработчиков так и не используют это свойство.
У этого есть две основные причины: во-первых, браузерам потребовалось много времени на реализацию адекватной поддержки этого свойства. И все просто успели забыть о нём.
Во-вторых, многие разработчики до конца не понимают логику, по которой это свойство работает. И тут появляюсь я!
Я полагаю, что вы хорошо знакомы с позиционированием в CSS, но давайте кратко повторим основные моменты:
Ещё три года назад существовало четыре типа позиционирования: static
, relative
, absolute
и fixed
.
Основное различие между static
и relative
, absolute
и fixed
в том, какое место они занимают в потоке документа (DOM). Элементы с позицией static
и relative
сохраняют своё естественное положение в потоке документа, в то время как absolute
и fixed
«вырываются» из потока документа и становятся плавающими.
Новое значение sticky
похоже на все предыдущие значения сразу. Я проиллюстрирую это чуть позже.
Моё первое знакомство с «липким» позиционированиемСкопировать ссылку
Думаю, что большинство из вас игрались с «липким» позиционированием. Так было и у меня, пока в один момент я не осознал, что совсем не понимаю это свойство.
При первом знакомстве с position: sticky
все быстро понимают, что элемент залипает, когда область просмотра достигает определённой позиции.
Пример:
.some-component {
position: sticky;
top: 0;
}
Проблема в том, что иногда это работает, а иногда нет. Когда всё работает, то элемент и правда залипает. Но когда не работает, то при прокрутке элемент перестаёт залипать. Как человеку, который живёт одним только CSS, мне было важно разобраться в сути проблемы. Именно поэтому я решил тщательно изучить «липкое» позиционирование.
«Липкая» разведкаСкопировать ссылку
Во время своих экспериментов я заметил, что если элемент с position: sticky
является единственным ребёнком своего родителя-обёртки, то этот «липкий» элемент не залипает.
<!-- НЕ РАБОТАЕТ!!! -->
<style>
. sticky {
position: sticky;
top: 0;
}
</style>
<div>
<div>
Некий контент
</div>
</div>
Когда я добавлял больше элементов внутрь родителя-обёртки всё начинало работать как ожидалось.
Почему так происходит?
Причина кроется в том, что элемент с position: sticky
может перемещаться только в пределах контейнера, в котором находится. А поскольку в моём случае он был единственным ребёнком, у него не было элементов-братьев, поверх которых он мог перемещаться.
Как на самом деле работает position: sticky в CSSСкопировать ссылку
«Липкое» позиционирование состоит из двух основных частей: «липкого» элемента и «липкого» контейнера.
«Липкий» элемент — это элемент, которому мы задали position: sticky
. Элемент будет становиться плавающим, как только область видимости достигнет определённой позиции, например top: 0px
.
Пример:
.some-component {
position: sticky;
top: 0px;
}
«Липкий» контейнер — это HTML-элемент, который оборачивает «липкий» элемент. Это максимальная область, в которой может перемещаться наш элемент.
Когда вы задаёте элементу position: sticky
, его родитель автоматически становится «липким» контейнером! Очень важно это запомнить! Контейнер будет являться областью видимости для элемента. «Липкий» элемент не может выйти за пределы своего «липкого» контейнера.
В этом причина, почему в предыдущем примере «липкий» элемент не залипал: он был единственным дочерним элементом контейнера.
Наглядный пример:
Пример на CodePen.Понимание «липкого» поведенияСкопировать ссылку
Как я и говорил, position: sticky
ведёт себя не так, как другие типы позиционирования. Но, с другой стороны, у них есть определённые сходства. Позвольте мне пояснить:
Относительное (или статичное) — «липкий» элемент похож на элемент со статическим или относительным позиционированием поскольку сохраняет свою естественную позицию в DOM (остаётся в потоке). Фиксированное — когда элемент залипает, то ведёт себя как будто у него заданы стили position: fixed
, остаётся на той же позиции в области видимости и вырывается из потока документа. Абсолютное — в конце доступной для перемещений области элемент останавливается и остаётся поверх другого элемента. Точно также, как ведёт себя абсолютно спозиционированный элемент в контейнере с position: relative
.
Залипает внизу?!Скопировать ссылку
В большинстве случаев вы будете использовать position: sticky
чтобы прикрепить элемент к верхнему краю страницы. Что-то вроде этого:
.component {
position: sticky;
top: 0;
}
Именно для таких сценариев и был создан этот тип позиционирования. До его появления такой трюк приходилось проворачивать с помощью JavaScript.
Но вы с тем же успехом можете использовать это свойство для того, чтобы прилепить элемент к нижней границе. Это значит, что футеру можно задать «липкое» позиционирование и при скролле он всегда будет залипать у нижнего края. И когда мы дойдём до конца «липкого» контейнера наш элемент остановится на своей естественной позиции. Лучше использовать эту особенность для элементов, находящихся в самом конце контейнера.
Полный пример:
HTML
<main>
<header>HEADER</header>
<div>MAIN CONTENT</div>
<footer>FOOTER</footer>
</main>
CSS
.main-footer {
position: sticky;
bottom: 0;
}
Пример на CodePen.В реальной жизни я использую такое поведение для сводных таблиц. И, я думаю, с помощью этого приёма можно реализовать «липкую» навигацию в футере.
Браузерная поддержкаСкопировать ссылку
- «Липкое» позиционирование поддерживается всеми основными современными браузерами. Исключение: старый-добрый IE.
- Для Safari потребуется префикс
-webkit
position: -webkit-sticky; /* Safari */
position: sticky;
Более 86% браузеров поддерживает sticky по данным Can I Use.В заключенииСкопировать ссылку
Вот и всё. Я надеюсь, что вам понравилась эта статья и мне удалось поделиться своим опытом. Я буду признателен, если вы поделитесь этим постом и поаплодируйте.
Другие мои посты о CSSСкопировать ссылку
Учебник CSS — Урок 1 — подключаем CSS-стили
Я не буду объяснять зачем нужен CSS. Если вы открыли этот учебник значит вы желаете его выучить. От себя лишь скажу, что возможности CSS очень широки и позволяют верстать макеты любой сложности. В свою очередь использование css означает, что вам придется отказаться от использования различных атрибутов тегов size, color, bgcolor, align и других, которые будут «мешать» CSS.
Существует по крайней мере три способа подключения CSS к вашему HTML файлу. Давайте рассмотрим самый простой, потом второй и правильный способ.
CSS внутри тега
CSS можно подключить c помощью атрибута style:
<div> Блок </div>
Так мы задаем блок размером 200 на 100 пикселей. Давайте рассмотрим как пишется CSS. Сначала мы пишем атрибут. И потом уже в ковычках пишем css-стили.
style="параметр:значение;параметр:значение;параметр:значение"
Пишем стили мы так сначала идет параметр (widht, height и другие), потом идет двоеточие и значение параметра. Разделяем каждый параметр точкой с запятой.
Теперь ко второму способу написания CSS.
CSS в начале HTML-документа
Для этого мы используем тег <style></style> в котором мы пишем CSS-код.
<html> <head> <title>Учебник CSS</title> <style type="text/css"> здесь мы будем писать css-код </style> </head> <body> <p>Учите CSS вместе с drupalbook.org</p> </body> </html>
Тег style мы пишем в теге <head></head> после тега <title>. Давайте напишем какой-нибудь CSS-код:
<html> <head> <title>Учебник CSS</title> <style type="text/css"> body{ background: #eeeeee; /* фон страницы */ font-size: 14px; /* размер шрифта */ } p{ color: #ff0000; /* цвет текста */ } </style> </head> <body> <p>Учите CSS вместе с drupalbook.org</p> <p>2 строка учите CSS вместе с drupalbook.org</p> </body> </html>
Давайте посмотрим как пишется css для тегов. Если мы пишем название тега в css, то для всех этих тегов будут применены параметры CSS. Так например если мы пишем p то значит для всех параграфов будет выбраны следующие параметры.
Когда мы пишем CSS-код, то сначала мы указываем тег для которого применяем css-стили, дальше мы в фигурных скобках пишем css-стили. CSS-стили пишутся также как и в атрибуте:
параметр:значение;параметр:значение;параметр:значение
Параметр, двоеточие, значение, точка с запятой и снова параметр, двоеточие, значение, точка с запятой и снова. .. После последнего стиля можно не ставить точку с запятой, но лучше всего поставить.
Мы вставили двумя способами css-стили, а теперь давайте используем третий способ, самый оптимальный.
CSS в отдельном файле
Это самый лучший способ, который позволяет отделить полностью CSS от HTML-кода. Конечно иногда хочется вставить CSS прямо в HTML-код, но надо бить себя по рукам в этом случае и выносить CSS в отдельный файл. Зачем?
Это основная идея CSS размежевать текст и оформление текста. HMTL нам нужен чтобы разметить текст, а вот CSS нужен для того чтобы этот текст гармонично выглядел. С помощью HTML выводиться только текст, а с помощью CSS размеры, цвета, формы, границы, отступы.
Это было во-первых, теперь во-вторых когда код HTML и CSS в одном файле, то это становится нечитабельно и грамоздко. А теперь в-третьих, css сохраняются в браузере, поэтому если вынести весь CSS отдельно, то страница будет загружаться быстрее, потому что загружать css нужно только один раз. Я думаю вам уже стало понятным к чему я клоню?
CSS нужно стараться выносить в отдельный файл! Вот к этому я и клоню. А теперь давайте создавать отдельный css файл. Для этого есть тег <link>:
<html> <head> <title>Учебник CSS</title> <link type="text/css" rel="stylesheet" media="all" href="styles.css" /> </head> <body> <p>Учите CSS вместе с drupalbook.org</p> <p>2 строка учите CSS вместе с drupalbook.org</p> </body> </html>
У тега <link> есть следующие атрибуты:
type=»text/css» — так мы указываем то что это css,
rel=»stylesheet» — это указывает на то что этот файл является css-файлом,
media=»all» — этот css файл будет отображаться для всех устройств, через которые просматривают сайт,
href=»styles.css» — путь к css файлу, в нашем случае путь относительный.
Кажется разобрались с тем как подключать css файл, теперь создавайте этот файл styles.css в той же папке где и html-файл.
Теперь открывайте файл styles.css и вставьте него css-стили:
body{ background: #eeeeee; /* фон страницы */ font-size: 14px; /* размер шрифта */ } p{ color: #ff0000; /* цвет текста */ }
Сохраните этот файл и откройте через браузер ваш html-файл. Теперь css подключен к вашему файлу как полагается, через отдельный файл. В следующем уроке мы подробно начнем разбирать, как писать стили в отдельном файле.
Работа с CSS | Vue CLI
Проекты Vue CLI предоставляют поддержку для PostCSS, CSS-модулей, а также пре-процессоров, включая Sass, Less и Stylus.
Указание ссылок на ресурсы
Весь скомпилированный CSS обрабатывается css-loader, который будет парсить url()
и разрешать их как зависимостями модуля. Это означает, что вы можете ссылаться на ресурсы, используя относительные пути на основе локальной файловой структуры. Обратите внимание, что если вы хотите ссылаться на файл внутри npm-зависимости или через псевдоним webpack, путь должен начинаться с префикса ~
для избежания двусмысленности. Подробнее в разделе Обработка статических ресурсов.
Пре-процессоры
Вы можете выбрать пре-процессоры (Sass/Less/Stylus) при создании проекта. Если вы этого не сделали, то внутренняя конфигурация webpack всё равно настроена для их использования. Вам лишь требуется вручную доустановить соответствующие загрузчики для webpack:
Примечание при использовании webpack 4
При использовании webpack
версии 4, по умолчанию во Vue CLI 4, следует убедиться в совместимости используемых загрузчиков. В противном случае будут появляться ошибки о конфликтующих зависимостях. В таких случаях можно использовать более старую версию загрузчика, которая всё ещё совместима с webpack
4.
Теперь вы можете импортировать соответствующие типы файлов, или использовать их синтаксис внутри файлов *.vue
с помощью:
Совет по производительности Sass
Обратите внимание, при использовании Dart Sass синхронная компиляция вдвое быстрее асинхронной по умолчанию, из-за накладных расходов на асинхронные коллбэки. Чтобы избежать их можно воспользоваться пакетом fibers для вызова асинхронных импортёров по пути синхронного кода. Для этого просто установите fibers
в качестве зависимости проекта:
Также имейте в виду, поскольку это нативный модуль, то могут возникнуть различные проблемы совместимости, в зависимости от ОС и окружения сборки. В таких случаях выполните npm uninstall -D fibers
для устранения проблемы.
Автоматические импорты
Если вы хотите автоматически импортировать файлы (для цветов, переменных, примесей…), можно использовать style-resources-loader. Вот пример для stylus, который импортирует ./src/styles/imports.styl
в каждый однофайловый компонент и в каждый файл stylus:
Вы также можете использовать vue-cli-plugin-style-resources-loader.
PostCSS
Vue CLI использует PostCSS внутри себя.
Вы можете настроить PostCSS через .postcssrc
или любую другую конфигурацию, которая поддерживается postcss-load-config, а также настраивать postcss-loader через опцию css.loaderOptions.postcss
в файле vue.config.js
.
Плагин autoprefixer включён по умолчанию. Чтобы определить целевые браузеры используйте поле browserslist в файле package.json
.
Примечание о префиксных CSS правилах
В сборке для production Vue CLI оптимизирует ваш CSS и удаляет ненужные префиксные правила CSS, основываясь на целевых браузерах. С autoprefixer
включённым по умолчанию, вы должны всегда использовать только CSS-правила без префиксов.
CSS-модули
CSS-модули в файлах *.vue
доступны из коробки с помощью <style module>
.
Для импорта CSS или других файлов пре-процессоров в качестве CSS-модулей в JavaScript, необходимо чтобы имя файла заканчивалось на .module.(css|less|sass|scss|styl)
:
Если вы не хотите указывать .module
в именах файлов, установите css.requireModuleExtension
в false
внутри файла vue.config.js
:
Если вы хотите настроить генерируемые имена классов для CSS-модулей, вы можете сделать это с помощью опции css.loaderOptions.css
в vue.config.js
. Все настройки css-loader
поддерживаются, например localIdentName
и camelCase
:
Передача настроек в загрузчики пре-процессоров
Иногда может возникнуть необходимость передать настройки в загрузчик пре-процессора для webpack. Вы можете сделать это с помощью опции css.loaderOptions
в vue.config.js
. Например, для передачи глобальных переменных во все стили Sass/Less:
Загрузчики которые можно настраивать с помощью опции loaderOptions
:
Совет
Это предпочтительнее, чем вручную обращаться к конкретным загрузчикам, используя chainWebpack
, потому что настройки необходимо применять в нескольких местах, где используется соответствующий загрузчик.
Создание и настройка проекта React + Webpack с нуля до SSR — Разработка на vc.ru
10 100 просмотров
Хочу вам показать наглядный пример и инструкцию того, как можно самому с «чистого листа» сконфигурировать Webpack для React и Server Side Render’а без каких-либо бойлерплейтов, вроде create-react-app.
Некоторое время назад я начал заниматься созданием сайтов на сей чудесном view-фреймворке и по ходу дела сталкивался со многими проблемами, начиная от того, как правильно и практично реализовать конфиг Webpack’а и как готовить SSR совместно с TypeScript. Было прочитано кучу мануалов, пользовательских решений в гитхабе и прочего, что новичка (да даже иногда и опытных разработчиков) может ввести в ступор. Конечно, можно использовать create-react-app и потом «костылить» eject‘ы (расширение базовой конфигурации), обмазывая все готовыми плагинами, но ведь мы хотим держать весь проект под своим видением, не так ли? Да и просто будет полезно понять весь принцип «приготовления» приложения «от» и «до».
Маленькое предисловие:
1) На клиенте используем Node JS 13й версии. К сожалению, на момент написания статьи (сентябрь 2020 г.) на >=14 версии не работает Webpack Dev Server (далее WDS) (никак не обновят в нем Chokidar).
2) В проекте будем использовать: Webpack, TypeScript (далее TS), React, React Router, Stylus, ExpressJS.
3) Постараюсь описать каждый установленный npm-пакет и мало мальски важные, на мой взгляд, параметры в Webpack’е.
Вся инструкция предназначена для программистов, которые уже имели опыт с выше описанными технологиями. Расписывая все с самой базы — не хватит и дня на чтение.
Проект основан почти на «голом» React’е, без всяких Redux’ов, MobX’ов, Helmet’ов и тэдэ. Я хочу продемонстрировать принцип работы сборки и запуска проекта на сервере. Все остальное, надеюсь, сможете отредактировать в дальнейшем под себя.
Итак, начнем с инита npm:
Можете и без ключа yes, чтобы предварительно занести нужную информацию в package.json.
Установим все необходимое для Webpack’a и чтобы он мог собирать TS:
npm i webpack webpack-cli webpack-dev-server webpack-notifier typescript ts-loader clean-webpack-plugin uglifyjs-webpack-plugin —save-dev
- webpack — сборщик собственной персоной
- webpack-cli — позволяет работать с Webpack’ом из консоли
- webpack-dev-server — небольшой сервер для разработки
- webpack-notifier — будет показывать нам уведомления, если вдруг что-то где-то сломаем
- typescript — компилятор TS-кода
- ts-loader — инжектор TS’а в Webpack
- clean-webpack-plugin — при каждой сборке автоматически очищает папку для итоговых файлов
- uglifyjs-webpack-plugin — для продовой версии будет сжимать и минифицировать JS-файлы
Для тех, кто не так давно работает с npm: с параметром —save-dev устанавливаем пакеты, которые нам нужны именно для разработки (webpack, typescript, например), с —save пакеты которые пойдут в сборку (react, react-dom, fontawesome).
Установим React с роутером:
npm i react react-dom react-router-dom —save
- react — view-фреймворк
- react-dom — плагин, который будет конвертировать React DOM в html-структуру
- react-router-dom — роутер, который интегрируется через React DOM
Для TS нам надо установить типизацию React, чтобы компилятор понимал с какими данными работает и было удобнее писать код в редакторе:
npm i @types/react @types/react-dom @types/react-router-dom —save-dev
Устанавливаем CSS-препроцессор (я использую Stylus), с которым будем взаимодействовать и пара плагинов, которые наши стили «доведут до ума» перед продом:
npm i stylus stylus-loader css-loader style-loader [email protected] postcss-csso postcss-loader —save-dev
- stylus — препроцессор
- stylus-loader — инжектор Stylus’а в Webpack
- css-loader — позволит нам работать в стилях с @import как import/require в JS
- style-loader — встраивает наши стили в DOM
- [email protected] — в релизной сборке будет добавлять префиксы к некоторым стилям (например, -webkit-transition). 10я версия в данном кейсе пока что не работает.
- postcss-csso — очень крутой плагин, который минифицирует CSS
- postcss-loader — инжектор PostCSS’а в Webpack
Все нужные плагины для разработки установили, далее немного разберемся с архитектурой наших файлов.
Создадим в корне проекта папку src со всеми исходниками:
|—src |—App // Энтрипоинт нашего приложения >—index.styl >—index.tsx |—Common // Директория для вспомогательных элементов, сюда же можно в дальнейшем и изображения класть, например |—Styles >—reset.styl // Сброс дефолтных стилей браузера >—variables.styl // Переменные для стилей |—Html >—Browser.html // Html-шаблон для разработки, в который будут подключаться наши итоговые JS-файлы |—Pages // Страницы нашего приложения |—Content >—index.styl >—index.tsx |—Home >—index.styl >—index.tsx >—Routes.ts // Конфигурация роутинга >—Client.tsx // Рендерим энтрипоинт в HTML-документ
Настраиваем TS. Особо сильно в конфигурацию упарываться не будем, пока просто укажем стоковые параметры для компиляции React со строгими правилами. За всей документацией можно сходить на официальный сайт: https://www.typescriptlang.org/docs
В корне проекта создаем файл tsconfig.json:
{ «compilerOptions»: { «target»: «es5», «jsx»: «react», «noEmitOnError»: true, «noUnusedLocals»: true, «removeComments»: true, «noImplicitAny»: true, «esModuleInterop»: true, «baseUrl»: «./», «paths»: { // Указываем ссылки до директорий в проекте, чтобы каждый раз в импортах не писать относительные пути «App»: [«src/App»], «Pages/*»: [«src/Pages/*»], } }, «exclude»: [ «node_modules» ] }
Сделаем внешний конфиг-файл с модулями и правилами для Webpack. Внешний нужен для того, что мы будем использовать его для 2х конфиг-файлов Webpack’a: клиент и сервер, но это чуть позднее. Документация https://webpack.js.org/concepts/
В корне проекта создаем webpack.config.js:
const path = require(«path») module.exports = (env) => { const modules = { js: { test: /\.ts(x?)$/, exclude: /node_modules/, use: [ { loader: «ts-loader», }, ], }, stylus: { test: /\.styl$/, use: [ { loader: «style-loader», }, { loader: «css-loader», }, { loader: «stylus-loader», options: { import: [ // Тут для Stylus’а можем объявить глобальные переменные или функции, чтобы каждый раз их не импортировать path.resolve(__dirname, ‘src/Common/Styles/variables.styl’), ], } }, ], }, } if (env === ‘production’) { modules.stylus.use.splice(2, 0, { loader: «postcss-loader» }) } const resolve = { extensions: [«.ts», «.tsx», «.js», «.jsx»], alias: { // Тут тот же момент, что и в tsconfig.json, чтобы Webpack смог понять ссылки на директории App: path.resolve(__dirname, ‘src/App/’), Pages: path.resolve(__dirname, ‘src/Pages/’), }, } return { modules, resolve, } }
Создаем в корне проекта файл клиентской конфигурации для Webpack’а webpack.client.js:
const path = require(«path») const HtmlWebpackPlugin = require(‘html-webpack-plugin’) const WebpackNotifierPlugin = require(‘webpack-notifier’) const UglifyJsPlugin = require(‘uglifyjs-webpack-plugin’) const { CleanWebpackPlugin } = require(‘clean-webpack-plugin’) const webpackConfig = require(‘./webpack.config’) module.exports = (env, argv) => { const watchMode = argv.liveReload || false const modeEnv = argv.mode || ‘development’ const isProd = modeEnv === ‘production’ const config = webpackConfig(modeEnv) const optimizations = { splitChunks: { // Чанки для нашего приложения. Все наши npm-пакеты вынесем в отдельный файл с определенным хешем, чтобы клиент каждый раз при изменениях не выкачивал все по-новой cacheGroups: { vendors: { name: ‘vendors’, test: /node_modules/, chunks: ‘all’, enforce: true, }, }, }, minimizer: [], } if (isProd) { optimizations.minimizer.push(new UglifyJsPlugin()) } return { devServer: { contentBase: path.join(__dirname, «dist»), compress: true, port: 4200, watchContentBase: true, progress: true, hot: true, open: true, historyApiFallback: true, // Не забудьте про этот параметр, ибо со значением false WDS будет «прямолинейно» обрабатывать ссылки для React Router’а. Т.е. он будет по путь->директория искать index.html, а он у нас один и в корне. }, resolve: config.resolve, module: { rules: [ config.modules.js, config.modules.stylus, ], }, plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ template: ‘./src/Html/Browser.html’, // Скармливаем наш HTML-темплейт }), new WebpackNotifierPlugin({ alwaysNotify: false }), ], entry: { main: ‘./src/Client.tsx’, // Энтрипоинт-файл, с которого и начнется наша сборка }, output: { filename: watchMode ? ‘assets/[name].[hash].js’ : ‘assets/[name].[chunkhash].js’, // небольшое условие, т.к. WDS не будет работать с chunkhash path: path.resolve(__dirname, ‘dist’), // Весь наш результат складываем в папку dist publicPath: ‘/’, }, performance: { hints: false, }, optimization: optimizations, } }
Осталось немного. Добавим в корень проекта конфиг PostCSS postcss.config.js:
module.exports = { plugins: [ require(‘autoprefixer’), require(‘postcss-csso’), ] }
И добавим скрипты для сборки в package.json с донастройкой PostCSS.
В секцию scripts добавляем команды:
«watch»: «webpack-dev-server —config webpack.client.js —mode development» // Запуск нашего дев-сервера и пересборка при изменении файлов «build»: «webpack —config webpack.client.js —mode production» // Билд проекта для продовой версии «dev»: «webpack —config webpack.client.js —mode development» // Билд версия с возможностью отладки
Для Autoprefixer’а в корень json’а добавим параметр, для каких браузеров добавлять префиксы:
«browserslist»: [ «last 2 versions» ]
Супер! Наш сборщик полностью готов собирать проект. Наполним src/Client.tsx тестовым контентом:
import React from ‘react’ import ReactDOM from ‘react-dom’ ReactDOM.render(<h2>Woohoo!</h2>, document.getElementById(‘root’))
Не забываем, что у нас еще есть index.html для WDS src/Html/Browser.html
<!DOCTYPE html> <html lang=»en»> <head> <meta charset=»UTF-8″> <meta name=»viewport» content=»width=device-width, minimum-scale=1.0, maximum-scale=1.0, initial-scale=1.0″> <meta http-equiv=»X-UA-Compatible» content=»ie=edge»> <title>React Starter Pack</title> </head> <body> <div></div> </body> </html>
Выполняем в консолях npm run watch и видим результат
Берем тестовый React-контент с GitHub’а, где я сделал страницы с роутингом и стили. Кстати, заметьте, стили я подключаю через require в самом компоненте (в методе render для классовых компонентов). Это позволяет в head добавлять стили только отображаемых компонентов, что снижает нагрузку на парсинг и рендер.
Представим, что наше приложение полностью написано и готово к релизу. Приступим к Server Side Render части.
Для работы SSR нам нужны следующие npm-пакеты:
- express — Node JS сервер
- @types/express — TS тип для ExpressJS
- mini-css-extract-plugin — плагин, который выгрузит стили не в JS-файлы, а отдельный CSS. Если понадобится, вы можете вывести его в серверную часть.
- webpack-node-externals — плагин, позволяющий исключать из сборки node_modules по дефолту
npm i express @types/express mini-css-extract-plugin webpack-node-externals —save-dev
В webpack.config.js добавим:
const MiniCssExtractPlugin = require(‘mini-css-extract-plugin’)
В массив модулей добавляем новый объект для компиляции отдельного изоморфного CSS-файла:
stylusIsomorph: { test: /\.styl$/, use: [ { loader: MiniCssExtractPlugin.loader, }, { loader: «css-loader», }, { loader: «stylus-loader», options: { import: [ path.resolve(__dirname, ‘./src/Common/Styles/variables.styl’), ], } }, ], }
И также добавим для него PostCSS для production-режима:
if (env === ‘production’) { … modules.stylusIsomorph.use.splice(2, 0, { loader: «postcss-loader» }) }
Казалось, мы могли бы все это запустить напрямую в ExpressJS, но нам надо все приложение прогнать через TS.
Создадим в корне проекта отдельный Webpack-конфиг для компиляции серверной части webpack.server.js:
const path = require(«path») const UglifyJsPlugin = require(‘uglifyjs-webpack-plugin’) const nodeExternals = require(‘webpack-node-externals’) const { CleanWebpackPlugin } = require(‘clean-webpack-plugin’) const MiniCssExtractPlugin = require(‘mini-css-extract-plugin’) const webpackConfig = require(‘./webpack.config’) module.exports = (env, argv) => { const modeEnv = argv.mode || ‘development’ const config = webpackConfig(modeEnv) const optimizations = { minimizer: [ new UglifyJsPlugin(), ], } return { plugins: [ new CleanWebpackPlugin(), new MiniCssExtractPlugin(), // Подключаем плагин для CSS ], resolve: config.resolve, module: { rules: [ config.modules.js, config.modules.stylusIsomorph, ], }, entry: { main: ‘./src/Server.tsx’, // Тут уже энтрипоинт сервера, который сделаем далее }, output: { filename: ‘[name].js’, path: path.resolve(__dirname, ‘server’), // Все компилируем в папку server }, performance: { hints: false, }, optimization: optimizations, target: ‘node’, // обязательно указываем режим сборки для node js, а не браузера externals: [nodeExternals()], // исключаем node_modules } }
Создадим наш энтрипоинт для сборки сервера src/Server.tsx:
import fs from ‘fs’ import express from ‘express’ import React from ‘react’ import ReactDOMServer from ‘react-dom/server’ import { StaticRouter } from ‘react-router’ import { App } from ‘App’ import { Html } from ‘./Html/Server’ const port = 3000 const server = express() const jsFiles: Array<string> = [] fs.readdirSync(‘./dist/assets’).forEach(file => { if (file.split(‘.’).pop() === ‘js’) jsFiles.push(‘/assets/’ + file) }) server.use(‘/assets’, express.static(‘./dist/assets’)) server.get(‘*’, async (req, res) => { ReactDOMServer.renderToNodeStream(<Html scripts={jsFiles}> <StaticRouter location={req.url} context={{}}> <App /> </StaticRouter> </Html>).pipe(res) }) server.listen(port, () => console.log(`Listening on port ${port}`))
1) «Обертку» HTML’а теперь генерируем динамически.
2) Обратите внимание на StaticRouter. ExpressJS будет автоматически генерировать роутер для отдачи статичного HTML с сервера.
3) В тело документа напрямую «опрокидываем» наш энтрипоинт приложения.
4) GET-метод реализуем через Node JS Streams.
Создадим для начала HTML в src/Html/Server.tsx:
import React from ‘react’ interface Html { scripts: Array<string> } export function Html({ children, scripts }: React.PropsWithChildren<Html>) { return ( <html> <head> <meta charSet=»UTF-8″ /> <meta name=»viewport» content=»width=device-width,minimum-scale=1,maximum-scale=1,initial-scale=1″ /> <meta httpEquiv=»X-UA-Compatible» content=»ie=edge» /> <title>React Starter Pack</title> </head> <body> <div>{children}</div> {scripts.map((script, index) => <script src={script} key={index} />)} </body> </html> ) }
У компонента есть аргумент scripts. ExpressJS собирает из /dist/assets все JS-файлы и явно указывает на них.
Кстати, все ваши meta-теги, ссылки на фавиконки надо указывать в этом файле. Browser.html нужен только для WDS’а.
import React from ‘react’ import ReactDOM from ‘react-dom’ import { BrowserRouter } from ‘react-router-dom’ import { App } from ‘App’ const entryBlock = document.getElementById(‘root’) const renderFunction: ReactDOM.Renderer = entryBlock.hasChildNodes() ? ReactDOM.hydrate : ReactDOM.render renderFunction(<BrowserRouter> <App /> </BrowserRouter>, entryBlock)
Вот тут могут быть «запуточки». Пояснение: когда запускаем наше приложение через WDS, сначала входим в src/Html/Browser.html, потом подгружаем JS и отрабатывает метод render, т.к. в div#root ничего нет. Инитим BrowserRouter и далее App. Когда же запускается React c ExpressJS сервера, в div#root уже присутствует контент: определенная страница или 404я — отрабатывает метод hydrate.
С ExpressJS алгоритм такой:
Строим основное тело HTML-документа из файла src/Html/Server.tsx ->
Определяем StaticRouter с нужными параметрами и контекстом ->
Рендерим главный компонент App ->
Отдаем страницу
Когда запускаем React на клиентской стороне с ExpressJS сервера:
Тело HTML уже получили ->
Рендерим динамический контент через метод hydrate
Добавим в package.json команду для сборки и запуска сервера:
«start»: «webpack —config webpack.server.js —mode production && node ./server/main.js»
Все, теперь наше приложение готово к запуску. Предварительно поставьте нужный порт для сервера в src/Server.tsx (в примере 3000).
npm run build npm run start
Сервер стартовал и можем протестировать работу по адресу http://localhost:3000
Также вместо node вы можете использовать nodemon.
Надеюсь, данная статья помогла вам понять, как правильно и удобно сплитовать конфиги Webpack и как работает SSR в связке с React’ом, в какой последовательности и принципе.
Методология CSS-модулей
В постоянно меняющемся мире фронтенд разработки очень сложно найти действительно оригинальную концепцию и правильно ее представить, вызвав у других людей желание попробовать ее.
Если взглянуть на CSS, то, на мой взгляд, последней значительной инновацией в нашем подходе к написанию стилей стало появление CSS-препроцессоров, в первую очередь это касается Sass, как наиболее известного из них. Также существует PostCSS, в котором реализован несколько иной подход, но общий принцип действия тот же — в постпроцессор передается неподдерживаемый браузерами синтаксис, а возвращается поддерживаемый синтаксис.
Сейчас у нас появилась очередная интересная новинка — CSS-модули. В этой статье я представлю эту новую технику, расскажу о ее сильных сторонах и о том, как начать с ней работать.
Что такое CSS-модуль ?
Начнем с определения из официального репозитория проекта:
CSS-модуль это файл CSS, в котором названия классов и анимаций по умолчанию заданы локально.
На самом деле все немного сложне. Так как названия классов заданы локально, это требует определенной настройки, сборочного процесса и немного магии, которую иногда сложно понять.
Но в конце концов, мы можем ценить CSS-модули за то, что они реализуют, а это способ ограничивать контекст CSS одним компонентом и возможность избежать ада глобального пространства имен. Больше нет необходимости искать методику именования компонентов, ведь этот шаг делается за вас на стадии сборки!
Как это работает
CSS-модули надо подключать в сборочный процесс, это значит, что они не работают сами по себе. Плагины есть для webpack или Browserify. На базовом уровне это работает так: при импорте файла в модуль JavaScript (например, в компонент React), CSS-модули переопределят объект с названиями классов из файла в динамически задаваемые пространства имен классов, которые можно использовать как строки в JavaScript. Проиллюстрируем это на примере:
Ниже показан очень простой файл CSS. Класс .base
не является уникальным в проекте и это не то название класса, которое будет присвоено элементу. Это своего рода псевдоним внутри таблицы стилей, который будет использован в модуле JavaScript.
.base {
color: deeppink;
max-width: 42em;
margin: 0 auto;
}
И вот его использование в тестовом компоненте JavaScript:
import styles from './styles.css';
element.innerHTML = `<div>
CSS Modules are fun.
</div>`;
В итоге у нас будет сгенирировано что-то вроде следующего кода (это пример использования CSS-модулей в Webpack с дефолтными настройками):
<div>CSS Modules are fun.</div>
._20WEds96_Ee1ra54-24ePy {
color: deeppink;
max-width: 42em;
margin: 0 auto;
}
Можно настроить генерацию более коротких названий классов или названий, следующих определенному паттерну. Это совершенно не важно (разве что более короткие названия классов дадут небольшой выигрыш в размере таблиц стилей), ведь главное, что они динамически генерируются, уникальны и связаны с правильными стилями.
Возможные возражения
Итак, мы разобрались, как это работает. И теперь вы думаете: “Что же с этим делать? Ведь это…”. ОК, я вас понимаю. Сейчас мы разберем все возражения по отдельности.
Это выглядит ужасно!
Это правда. Но имена классов не должны быть красивыми — их предназначение в применении стилей к элементу. И это именно то, что они делают, поэтому такой аргумент нельзя назвать веским.
Их трудно отлаживать!
Как только в вашей сборке производится какая-либо обработка таблиц стилей, их отладка становится болью. С Sass в этом плане не легче. Поэтому у нас есть sourcemaps, которые также можно настроить и для CSS-модулей.
Я на самом деле утверждаю, что непредсказуемость названий классов не влечет серьезных проблем с отладкой, так как классы по умолчанию специфичны для модулей. И если вы знаете, какой модуль вы сейчас проверяете в инструментах разработчика, то вы знаете, где искать соответствующие стили.
Это препятствует многократному использованию стилей
Да и нет. С одной стороны — да, но это на самом деле и есть цель: мы привязываем стили к компоненту, чтобы избежать конфликтов глобальных стилей. И согласитесь, что это хорошо.
С другой стороны, мы можем создавать глобальные классы (с помощью :global()
), например, вспомогательные классы, которые сохраняются в том же виде после сборки и позволяют абстрагировать стили также просто как и в обычных условиях. Эти классы можно использовать в ваших компонентах JavaScript.
:global(.clearfix::after) {
content: '';
clear: both;
display: table;
}
В CSS-модулях также есть способ расширения стилей из другого модуля, работающий аналогично директиве @extend
в Sass. Он не копирует стили, а складывает селекторы для расширения стилей.
.base {
composes: appearance from '../AnoherModule/styles.css';
}
Они требуют webpack, Browserify или другие инструменты?
Точно также как требуется Sass для компиляции .scss
в обычный CSS, PostCSS необходим для обработки стилей, чтобы сделать их понятными браузеру. От этапа сборки никуда не деться.
Почему мы вообще это обсуждаем?
Хм, я не совсем уверен, что в будущем CSS-модули останутся такими же как сейчас, но я думаю, что это разумный способ написания стилей. Глобальная массивная таблица стилей не слишком подходит к большим сайтам, разбитым на мелкие компоненты.
Уникальность пространства имен CSS делает его одновременно мощным и уязвимым. Такие решения как модули CSS или любой будущий инструмент, основанный на этой идее, позволяют нам сохранять силу глобальных стилей и в то же время избегать конфликтов внутри изолированных областей стилей. Это вин!
Начало работы с CSS-модулями
Как уже было сказано, нам нужен webpack или Browserify для работы CSS-модулей.
Webpack
Начнем с версии для webpack. В файл webpack.config.js
добавьте следующую конфигурацию, чтобы webpack обрабатывал файлы CSS с помощью CSS-модулей:
{
test: /\.css$/,
loader: 'style-loader!css-loader?modules'
}
С такой настройкой полученные стили будут размещаться внутри элемента <style>
на странице. Это не самое лучшее решение, поэтому мы сконфигурируем вывод итоговых стилей в отдельный файл благодаря плагину извлечения текста для webpack:
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader?modules')
}
Этого достаточно для работы с webpack.
Browserify
Я всегда использовал Browserify только через командную строку, так что это оказалось немного сложнее. Я добавил скрипт npm в файл package.json
:
{
"scripts": {
"build": "browserify -p [ css-modulesify -o dist/main.css ] -o dist/index.js src/index.js"
}
}
Эта строчка сообщает Browserify, что надо трансформировать src/index.js
, в dist/index.js
и скомпилировать файл dist/main.css
с помощью плагина css-modulesify. Если вы хотите добавить автопрефиксер, то вы можете завершить команду так:
{
"scripts": {
"build": "browserify -p [ css-modulesify --after autoprefixer -o dist/main.css ] -o dist/index.js src/index.js"
}
}
Как видите, вы можете использовать опцию --after
для обработки стилей после их компиляции.
Заключение
По состоянию на сегодня, система CSS-модулей еще сыровата, как вы можете заметить по конфигурации в Browserify. Но я убежден, что она будет совершенствоваться, поскольку все большее число людей понимает, что это устойчивое решение для больших и малых проектов.
Я думаю, что идея в основе CSS-модулей это направление, по которому надо двигаться. Я не скажу, что эта библиотека является лучшим из возможных решений, но в ней однозначно есть возможности реализующие то, какими должны быть стили: модульные, изолированные и при этом многократно используемые.
В качестве дальнейшего чтения по теме я рекомендую введение в CSS-модули от Глена Мэддерна, автора этого проекта.
/ * Модифицированная тема Jekyll по умолчанию | |
/ * | |
/ * Улучшения включают: | |
/ * | |
/ * 1. Адаптивный шаблон: добавлены медиа-запросы, чтобы он работал хорошо | |
/ * на большом количестве экранов. | |
/ * | |
Лицензия MIT (MIT) | |
Авторские права (c) 2013 Кашьяп | |
Разрешение предоставляется бесплатно любому лицу, получившему копию | |
этого программного обеспечения и связанных файлов документации («Программное обеспечение») для работы с | |
в Программном обеспечении без ограничений, включая без ограничений права | |
для использования, копирования, изменения, объединения, публикации, распространения, сублицензирования и / или продажи | |
копий Программного обеспечения, и разрешить лицам, которым Программное обеспечение принадлежит | |
предоставлено для этого при соблюдении следующих условий: | |
Вышеупомянутое уведомление об авторских правах и это уведомление о разрешении должны быть включены в | |
всех копий или существенных частей Программного обеспечения. | |
ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНЫХ ИЛИ | |
ПОДРАЗУМЕВАЕТСЯ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИИ КОММЕРЧЕСКОЙ ЦЕННОСТИ, | |
ПРИГОДНОСТЬ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ И НЕЗАЩИТА ОТ ПРАВ. НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ | |
АВТОРЫ ИЛИ ДЕРЖАТЕЛИ АВТОРСКИХ ПРАВ НЕСУТ ОТВЕТСТВЕННОСТЬ ЗА ЛЮБЫЕ ПРЕТЕНЗИИ, УБЫТКИ ИЛИ ДРУГИЕ | |
ОТВЕТСТВЕННОСТЬ, ВЫЯВЛЯЮЩАЯСЯ В РЕЗУЛЬТАТЕ ДОГОВОРА, ИЛИ ИНОСТРАННОЙ ДЕЯТЕЛЬНОСТИ, ВОЗНИКНУЮ ИЗ, | |
НЕ ИЛИ В СВЯЗИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ ИЛИ ИСПОЛЬЗОВАНИЕМ ИЛИ ДРУГИМИ ДЕЛАМИ НА | |
ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ. | |
/ ********************************************** ***************************** / | |
/ * | |
/ * Обычный | |
/ * | |
/ *********************************************** ***************************** / | |
/ * Общий сброс * / | |
* { | |
маржа: 0; | |
отступ: 0; | |
} | |
HTML, body {height: 100%; } | |
кузов { | |
цвет фона: #FFF; | |
размер шрифта: 130%; | |
семейство шрифтов: calluna, Calluna, Джорджия; | |
font-weight: 300; | |
line-height: 1.55em; | |
отступ: 0 2em; | |
рендеринг текста: optimizeLegibility; | |
цвет: # 555; | |
} | |
h2, h3, h4, h5, h5, h6 { | |
цвет: # 333; | |
семейство шрифтов: adelle, Адель, Джорджия; | |
font-weight: 800; | |
рендеринг текста: optimizeLegibility; | |
} | |
h2 { | |
размер шрифта: 170%; | |
margin-top: 1em; | |
нижнее поле: 0.5em; | |
line-height: 1.4em; | |
} | |
h3 { | |
размер шрифта: 150%; | |
margin-top: 1em; | |
нижнее поле: 0,5em; | |
line-height: 1.4em; | |
} | |
h4 { | |
размер шрифта: 130%; | |
верхняя маржа: 3,25em; | |
нижнее поле: 0,5em; | |
line-height: 1.4em; | |
} | |
h5 { | |
размер шрифта: 110%; | |
margin-top: 2em; | |
нижнее поле: 0.5em; | |
line-height: 1.4em; | |
} | |
h5 { | |
размер шрифта: 100%; | |
margin-top: 1,5em; | |
нижнее поле: 0,5em; | |
line-height: 1.4em; | |
} | |
п { | |
маржа: 0.5em 0 2.5em; | |
} | |
а {цвет: # 00а; } | |
a: hover {color: # 000; } | |
a: посетил {color: # a0a; } | |
цитата { | |
отступ: 0.1em 1.3em; | |
фон: #fafafa; | |
border-left: 5px # 81E26D solid; | |
цвет: # 666; | |
} | |
/ *********************************************** ***************************** / | |
/ * | |
/ * Дом | |
/ * | |
/ *********************************************** ***************************** / | |
ул.столбы { | |
list-style-type: нет; | |
нижнее поле: 2em; | |
} | |
ul.posts li { | |
высота строки: 1,75 мкм; | |
нижнее поле: 1em; | |
} | |
ул.пролет столбов { | |
цвет: #aaa; | |
семейство шрифтов: «Inconsolata», Consolas, «Courier New», моноширинный; | |
размер шрифта: 80%; | |
дисплей: элемент списка; | |
} | |
/ *********************************************** ***************************** / | |
/ * | |
/ * Зона | |
/ * | |
/ *********************************************** ***************************** / | |
.сайт { | |
маржа: авто; | |
max-width: 34em; | |
отступ: 0 1em; | |
цвет: # 333; | |
} | |
. Сайт. Заголовок а { | |
font-weight: жирный; | |
оформление текста: нет; | |
} | |
.site .header h2.title { | |
дисплей: строчно-блочный; | |
размер шрифта: 180%; | |
} | |
.site .header h2.title a { | |
цвет: # a00; | |
} | |
.site .header h2.title a: hover { | |
цвет: # 000; | |
} | |
.site .header a.extra { | |
цвет: #aaa; | |
левое поле: 1em; | |
} | |
.site .header a.extra: hover { | |
цвет: # 000; | |
} | |
. Сайт. Мета { | |
цвет: #aaa; | |
} | |
. Сайт. Нижний колонтитул { | |
размер шрифта: 80%; | |
цвет: # 666; | |
border-top: сплошной 4px #eee; | |
margin-top: 2em; | |
переполнение: скрыто; | |
} | |
.сайт .footer .contact { | |
поплавок: левый; | |
поле справа: 3em; | |
} | |
. Сайт. Нижний колонтитул. Связаться с { | |
цвет: # 8085C1; | |
} | |
.сайт .footer .rss { | |
margin-top: 1.1em; | |
margin-right: -.2em; | |
поплавок: правый; | |
} | |
.site .footer .rss img { | |
граница: 0; | |
} | |
до { | |
семейство шрифтов: ‘PT Mono’, Consolas, «Inconsolata», «Courier New», моноширинный; | |
переполнение: авто; | |
маржа: 1em авто; | |
} | |
код { | |
семейство шрифтов: ‘PT Mono’, Consolas, «Inconsolata», «Courier New», моноширинный; | |
} | |
/ *********************************************** ***************************** / | |
/ * | |
/ * Посты | |
/ * | |
/ *********************************************** ***************************** / | |
/ * стандарт * / | |
.пост до { | |
граница: сплошная 1px #ddd; | |
цвет фона: #eef; | |
высота строки: 1em; | |
заполнение: 0,2 мкм 0,5 мкм; | |
} | |
.post ul, .post ol { | |
левое поле: 1.5em; | |
нижнее поле: 1.5em; | |
} | |
.почтовый индекс { | |
граница: сплошная 1px #ddd; | |
цвет фона: #eef; | |
font-size: 0.7em; | |
} | |
.предварительный почтовый индекс { | |
граница: отсутствует; | |
} | |
/ * терминал * / | |
. Пост. Предтерминал { | |
граница: сплошной 1px # 000; | |
цвет фона: # 333; | |
цвет: #FFF; | |
} | |
.почтовый предтерминальный код { | |
цвет фона: # 333; | |
} | |
.post { | |
выравнивание текста: выравнивание; | |
} | |
/ ********************************************** ************************ / | |
/ * Медиа-запросы | |
/ * | |
/ *********************************************** ************************ / | |
@media screen и (макс. Ширина: 1000 пикселей) { | |
кузов { | |
размер шрифта: 130%; | |
отступ: 0 4em; | |
} | |
.почтовый индекс { | |
размер шрифта: 85%; | |
} | |
предварительный код { | |
line-height: 1.6em; | |
} | |
} | |
@media screen и (макс. Ширина: 800 пикселей) { | |
кузов { | |
размер шрифта: 125%; | |
отступ: 0 1.5em; | |
} | |
.почтовый индекс { | |
размер шрифта: 80%; | |
} | |
предварительный код { | |
размер шрифта: 80%; | |
} | |
} | |
@media screen и (макс. Ширина: 500 пикселей) { | |
кузов { | |
размер шрифта: 120%; | |
отступ: 0 0.5em; | |
} | |
. Нижний колонтитул { | |
выравнивание текста: по центру; | |
отступ: 1em; | |
} | |
.контакт { | |
ширина: 100%; | |
} | |
.почтовый индекс { | |
размер шрифта: 85%; | |
} | |
} | |
@media screen и (макс. Ширина: 320 пикселей) { | |
кузов { | |
отступ: 0; | |
} | |
} |
— HTML: язык разметки гипертекста
HTML
элемент представляет доминирующее содержимое
документа.Основная область содержимого состоит из содержимого, которое напрямую связано с центральной темой документа или с центральными функциями приложения или расширяет ее.
В документе не должно быть более одного элемента
, для которого не указан атрибут hidden
.
Содержимое элемента
должно быть уникальным для документа. Контент, который повторяется в наборе документов или разделах документа, таких как боковые панели, навигационные ссылки, информация об авторских правах, логотипы сайтов и формы поиска, не следует включать, если форма поиска не является основной функцией страницы.
не влияет на структуру документа; то есть, в отличие от таких элементов, как
, такие заголовки, как
и т. д.,
не влияют на концепцию DOM структуры страницы. Это строго информативно.
<основной>
Яблоки
Яблоко - это семечковые плоды яблони.
<статья>
Ред Делишес
Эти ярко-красные яблоки чаще всего встречаются во многих
супермаркеты.
...
...
<статья>
Бабушка Смит
Эти сочные зеленые яблоки отлично подходят для
яблочные пироги.
...
...
Ориентир
Элемент
ведет себя как главная роль ориентира. Ориентиры могут использоваться вспомогательными технологиями для быстрого определения больших разделов документа и перехода к ним.Предпочтительнее использовать элемент
вместо объявления role = "main"
, если нет проблем с поддержкой устаревшего браузера.
Пропустить навигацию
Пропустить навигацию, также известную как «skipnav», — это метод, который позволяет пользователю вспомогательных технологий быстро обходить большие разделы повторяющегося контента (основная навигация, информационные баннеры и т. Д.). Это позволяет пользователю быстрее получить доступ к основному содержимому страницы.
Добавление атрибута id
к элементу
позволяет ему быть целью для ссылки пропуска навигации.
Перейти к основному содержанию
<основной>
Режим чтения
Функциональность режима чтения в браузере проверяет наличие элемента
, а также элементов заголовка и секционирования содержимого при преобразовании содержимого в специализированное представление для чтения.
Таблицы BCD загружаются только в браузере
Для поддержки Internet Explorer 11 и ниже вы можете добавить роль ARIA "main"
к элементу
.Но имейте в виду, что в спецификации ARIA в HTML указано, что role = "main"
на самом деле не должен использоваться с элементом
, и валидатор W3C сообщит об этом предупреждение. Однако Internet Explorer 11 и ниже в противном случае не будет правильно отображать элемент
для программ чтения с экрана, таких как JAWS, если этот элемент также не имеет атрибут role = "main"
.
Основная таблица стилей (style.css) | Руководство разработчика тем
Стиль.css — это файл таблицы стилей (CSS), необходимый для каждой темы WordPress. Он контролирует представление (визуальный дизайн и верстку) страниц сайта.
Чтобы WordPress распознал набор файлов шаблона темы как допустимую тему, файл style.css должен находиться в корневом каталоге вашей темы, а не в подкаталоге.
Более подробное объяснение того, как включить файл style.css в тему, см. В разделе «Таблицы стилей» статьи «Постановка скриптов и стилей в очередь».
Вверх ↑
WordPress использует раздел комментариев в заголовке style.css для отображения информации о теме на панели инструментов «Внешний вид (Темы)».
Example #Example
Вот пример заголовочной части style.css.
/ *
Название темы: Двадцать двадцать
URI темы: https://wordpress.org/themes/twentytwenty/
Автор: команда WordPress
URI автора: https://wordpress.org/
Описание: Наша тема по умолчанию на 2020 год разработана таким образом, чтобы в полной мере использовать гибкость редактора блоков.Организации и предприятия имеют возможность создавать динамические целевые страницы с бесконечными макетами, используя блоки групп и столбцов. Центрированный столбец контента и точная типографика также делают его идеальным для традиционных блогов. Полноценные стили редактора дают вам хорошее представление о том, как будет выглядеть ваш контент, еще до публикации. Вы можете придать своему сайту индивидуальный вид, изменив цвета фона и цвет акцента в Настройщике. Цвета всех элементов на вашем сайте автоматически рассчитываются на основе выбранных вами цветов, обеспечивая высокий и доступный цветовой контраст для ваших посетителей.Теги: блог, один столбец, настраиваемый фон, настраиваемые цвета, настраиваемый логотип, настраиваемое меню, стиль редактора, избранные изображения, виджеты нижнего колонтитула, шаблон полной ширины, поддержка языка RTL, липкий- публикация, параметры темы, цепочки комментариев, готовность к переводу, стили блоков, широкие блоки, готовность к доступу
Версия: 1.3
Требуется минимум: 5.0
Проверено до: 5.4
Требуется PHP: 7.0
Лицензия: GNU General Public License v2 или новее.
URI лицензии: http://www.gnu.org/licenses/gpl-2.0.html
Текстовый домен: двадцать двадцать
Эта тема, как и WordPress, находится под лицензией GPL.Используйте его, чтобы сделать что-нибудь крутое, повеселиться и поделиться тем, что вы узнали, с другими.
* /
Примечание. Репозиторий тем WordPress использует номер после слова «Версия» в этом файле, чтобы определить, доступна ли для темы новая версия.
Вверх ↑
Пояснения # Пояснения
элементов, обозначенных ( * ), необходимы для темы в репозитории тем WordPress.
- Название темы (*): Название темы.
- URI темы : URL-адрес общедоступной веб-страницы, на которой пользователи могут найти дополнительную информацию о теме.
- Автор (*): Имя человека или организации, разработавшей тему. Рекомендуется использовать имя пользователя wordpress.org автора темы.
- URI автора : URL-адрес автора или организации.
- Описание (*): Краткое описание темы.
- Версия (*): версия темы, записанная в формате X.X или X.X.X.
- Требуется минимум (*) : самая старая основная версия WordPress, с которой будет работать тема, написанная на X.X формат. Темы требуются только для поддержки трех последних версий.
- Проверено до (*): Последняя основная версия WordPress, до которой тестировалась тема, то есть 5.4. Напишите только число в формате X.X.
- Требуется PHP (*) : самая старая поддерживаемая версия PHP в формате X.X, только номер
- Лицензия (*): Лицензия на тему.
- URI лицензии (*): URL-адрес лицензии темы.
- Текстовый домен (*): строка, используемая для текстового домена для перевода.
- Теги : слова или фразы, которые позволяют пользователям найти тему с помощью фильтра тегов. Полный список тегов находится в Руководстве по обзору тем.
- Путь к домену : используется, чтобы WordPress знал, где найти перевод, когда тема отключена. По умолчанию
/ языки
.
После обязательного раздела заголовка style.css может содержать все, что есть в обычном файле CSS.
Вверх ↑
Если ваша тема является дочерней темой, строка Template обязательна в стиле.css заголовок.
/ *
Название темы: Моя дочерняя тема
Шаблон: двадцать двадцать
* /
Для получения дополнительной информации о создании дочерней темы посетите страницу «Дочерние темы».
Live CSS | figwheel-main
Фигуил будет перезагружать ваши файлы CSS по мере их редактирования.
Чтобы это сработало, необходимо выполнить четыре действия:
- убедитесь, что вы предоставляете свою собственную страницу хоста HTML
- включить ссылку на ваш CSS на главную страницу HTML
- убедитесь, что ваш CSS находится в общедоступном каталоге
- настроить параметр конфигурации
: css-dirs
Включая ссылку на файл CSS
Включите тег ссылки на свой CSS на странице хоста HTML.
Обеспечение возможности обслуживания вашего файла CSS
Приведенный выше пример будет работать, если вы поместите свой файл CSS в
Каталог public / css
в пути к классам.Так как ресурсов
каталог обычно находится в пути к классам, по соглашению мы можем разместить
CSS файлы ресурсы / public / css
.
Скажите Фигуилу, чтобы он посмотрел и перезагрузил CSS
Вы будете использовать конфигурационный ключ : css-dirs
, чтобы сообщить Figwheel
в какие каталоги следует следить за изменениями файлов CSS.
Вы можете сделать это одним из двух способов: в файле сборки или в Файл figwheel-main.edn
.
В качестве примера предположим, что dev.{: css-dirs ["ресурсы / общедоступные / css"]}
{: основной example.core}
Или вы можете установить его для всех сборок и компиляций в figwheel-main.edn
:
{: css-dirs ["resources / public / css"]
;; остальная часть конфигурации
}
Затем вы перезапускаете сборку:
clojure -m figwheel.main -b dev -r
Теперь у вас должна быть возможность редактировать и сохранять resources / public / css / style.css
и просмотрите внесенные изменения.
жить в вашем приложении.
Свойство css — NuxtJS
Nuxt.js позволяет вам определять файлы / модули / библиотеки CSS, которые вы хотите установить глобально (включены на каждую страницу).
Если вы хотите использовать sass
, убедитесь, что вы установили пакеты sass
и sass-loader
. Если бы вы не только
npm install --save-dev sass sass-loader @ 10 волокон
nuxt.config.js экспорт по умолчанию {
css: [
'бульма',
'@ / assets / css / main.css ',
'@ / assets / css / main.scss'
]
}
Nuxt.js автоматически угадывает тип файла по его расширению и использует соответствующий загрузчик препроцессора для webpack. Вам все равно нужно будет установить требуемый загрузчик, если вам нужно их использовать.
Расширения стилей
Вы можете опустить расширение файла для файлов CSS / SCSS / Postcss / Less / Stylus / …, перечисленных в массиве css в вашем конфигурационном файле nuxt.
nuxt.config.js экспорт по умолчанию {
css: ['~ / assets / css / main', '~ / assets / css / animations']
}
Если у вас есть два файла с одинаковым именем e.грамм. main.scss
и main.css
, и не указывайте расширение в записи массива css, например css: ['~ / assets / css / main']
, тогда будет загружен только один файл в зависимости от порядка styleExtensions
. В этом случае будет загружен только файл css
, а файл scss
будет проигнорирован, потому что css
идет первым в массиве styleExtension
по умолчанию.
Порядок по умолчанию: ['css', 'pcss', 'postcss', 'styl', 'stylus', 'scss', 'sass', 'less']
ASP.Изоляция CSS
в .NET Core Blazor- 5 минут на чтение
В этой статье
Дэйв Брок
Изоляцияупрощает использование CSS в приложении, предотвращая зависимости от глобальных стилей и помогая избежать конфликтов стилей между компонентами и библиотеками.
Включить изоляцию CSS
Чтобы определить стили для конкретных компонентов, создайте .razor.css
, соответствующий имени файла .razor
для компонента в той же папке. Файл .razor.css
— это файл CSS с областью действия .
Для компонента Example
в файле Example.razor
создайте файл вместе с компонентом с именем Example.razor.css
. Файл Example.razor.css
должен находиться в той же папке, что и компонент Example
( Example.razor
). Базовое имя файла « Example
» без учета регистра .
Страниц / Пример.razor
:
@page "/ example"
Пример CSS с ограничением
Страниц / Example.razor.css
:
h2 {
коричневый цвет;
семейство шрифтов: Тахома, Женева, Вердана, без засечек;
}
Стили, определенные в Example.razor.css
, применяются только к визуализированным выходным данным компонента Example
. Изоляция CSS применяется к элементам HTML в соответствующем файле Razor.Любые объявления CSS h2
, определенные в другом месте приложения, не конфликтуют со стилями компонента Пример
.
Примечание
Чтобы гарантировать изоляцию стилей при объединении, импорт CSS в блоки кода Razor не поддерживается.
Сборка изоляции CSS
Изоляция CSS происходит во время сборки. Blazor переписывает селекторы CSS в соответствии с разметкой, отображаемой компонентом. Переписанные стили CSS объединяются и создаются как статический ресурс.На таблицу стилей есть ссылка внутри тега
из wwwroot / index.html
(Blazor WebAssembly) или Pages / _Host.cshtml
(Blazor Server). Следующий элемент
добавляется по умолчанию в приложение, созданное из шаблонов проекта Blazor, где заполнитель {ASSEMBLY NAME}
— это имя сборки проекта:
Следующий пример взят из размещенного приложения Blazor WebAssembly Client
.Имя сборки приложения — BlazorSample.Client
, а <ссылка>
добавляется шаблоном проекта Blazor WebAssembly, когда проект создается с параметром Hosted ( -ho | --hosted
option с использованием .NET CLI. или ASP.NET Core размещал флажок с использованием Visual Studio):
В связанном файле каждый компонент связан с идентификатором области действия.Для каждого стилизованного компонента добавляется атрибут HTML в формате b- <10-character-string>
. Идентификатор уникален и различается для каждого приложения. В визуализированном компоненте Counter
Blazor добавляет идентификатор области к элементу h2
:
Файл {ASSEMBLY NAME} .styles.css
использует идентификатор области для группирования объявления стиля с его компонентом. В следующем примере представлен стиль для предыдущего элемента
:
/ * / Pages / Counter.razor.rz.scp.css * /
h2 [b-3xxtam6d07] {
коричневый цвет;
}
Во время сборки создается пакет проекта с условным обозначением {STATIC WEB ASSETS BASE PATH} /Project.lib.scp.css
, где заполнитель {STATIC WEB ASSETS BASE PATH}
— это базовый путь статических веб-ресурсов. .
Если используются другие проекты, такие как пакеты NuGet или библиотеки классов Razor, связанный файл:
- Ссылается на стили с помощью импорта CSS.
- Не публикуется как статический веб-ресурс приложения, использующего стили.
Поддержка дочерних компонентов
По умолчанию изоляция CSS применяется только к компоненту, который вы связываете с форматом {COMPONENT NAME} .razor.css
, где заполнитель {COMPONENT NAME}
обычно является именем компонента. Чтобы применить изменения к дочернему компоненту, используйте комбинатор :: deep
для любых дочерних элементов в файле .razor.css
родительского компонента. Комбинатор :: deep
выбирает элементы, которые являются потомками сгенерированного идентификатора области действия элемента.
В следующем примере показан родительский компонент с именем Parent
и дочерний компонент с именем Child
.
Страниц / Parent.razor
:
@page "/ parent"
Родительский компонент
<Ребенок />
Общий / Child.razor
:
Дочерний компонент
Обновите объявление h2
в Parent.razor.css
с комбинатором :: deep
, чтобы обозначить, что объявление стиля h2
должно применяться к родительскому компоненту и его дочерним компонентам.
Страниц / Parent.razor.css
:
:: deep h2 {
красный цвет;
}
Стиль h2
теперь применяется к компонентам Parent
и Child
без необходимости создавать отдельный файл CSS с областью действия для дочернего компонента.
Комбинатор :: deep
работает только с дочерними элементами.Следующая разметка применяет стили h2
к компонентам, как и ожидалось. Идентификатор области родительского компонента применяется к элементу div
, поэтому браузер знает, как наследовать стили от родительского компонента.
Страниц / Parent.razor
:
Родитель
<Ребенок />
Однако исключение элемента div
удаляет отношение потомков. В следующем примере к дочернему компоненту применен стиль , а не .
Страниц / Parent.razor
:
Родитель
<Ребенок />
Поддержка препроцессора CSS
ПрепроцессорыCSS полезны для улучшения разработки CSS за счет использования таких функций, как переменные, вложение, модули, миксины и наследование. Хотя изоляция CSS изначально не поддерживает препроцессоры CSS, такие как Sass или Less, интеграция препроцессоров CSS выполняется без проблем, пока компиляция препроцессора происходит до того, как Blazor перезапишет селекторы CSS во время процесса сборки.Например, с помощью Visual Studio настройте существующую компиляцию препроцессора как задачу Before Build в обозревателе выполнения задач Visual Studio.
Многие сторонние пакеты NuGet, такие как Delegate.SassBuilder, могут компилировать файлы SASS / SCSS в начале процесса сборки до того, как произойдет изоляция CSS, и никакой дополнительной настройки не требуется.
Конфигурация изоляции CSS
ИзоляцияCSS разработана для работы «из коробки», но обеспечивает конфигурацию для некоторых сложных сценариев, например, когда есть зависимости от существующих инструментов или рабочих процессов.
Настройка формата идентификатора области
По умолчанию идентификаторы области видимости используют формат b- <10-character-string>
. Чтобы настроить формат идентификатора области, обновите файл проекта до желаемого шаблона:
<Группа элементов>
В предыдущем примере CSS, созданный для Example.razor.css
, изменяет свой идентификатор области с b- <10-character-string>
на my-custom-scope-identifier
.
Используйте идентификаторы области для достижения наследования с файлами CSS с заданной областью. В следующем примере файла проекта файл BaseComponent.razor.css
содержит общие стили для компонентов. Файл DerivedComponent.razor.css
наследует эти стили.
<Группа элементов>
Используйте оператор подстановочного знака ( *
) для совместного использования идентификаторов области в нескольких файлах:
<Группа элементов>
Изменить базовый путь для статических веб-ресурсов
Файл scoped.styles.css
создается в корне приложения. В файле проекта используйте свойство StaticWebAssetBasePath
, чтобы изменить путь по умолчанию. В следующем примере файл scoped.styles.css
и остальные ресурсы приложения помещаются по пути _content
:
_content / $ (PackageId)
Отключить автоматическое объединение
Чтобы отказаться от того, как Blazor публикует и загружает файлы с заданной областью во время выполнения, используйте свойство DisableScopedCssBundling
.При использовании этого свойства это означает, что другие инструменты или процессы отвечают за извлечение изолированных файлов CSS из каталога obj
, их публикацию и загрузку во время выполнения:
истина
Поддержка библиотеки классов Razor (RCL)
Когда библиотека классов Razor (RCL) предоставляет изолированные стили, атрибут href
тега
указывает на {STATIC WEB ASSET BASE PATH} / {ASSEMBLY NAME}.bundle.scp.css
, где заполнители:
-
{STATIC WEB ASSET BASE PATH}
: Базовый путь статического веб-актива. -
{НАЗВАНИЕ СБОРКИ}
: имя сборки библиотеки классов.
В следующем примере:
- Базовый путь статического веб-ресурса —
_content / ClassLib
. - Имя сборки библиотеки классов —
ClassLib
.
wwwroot / index.html
(Blazor WebAssembly) или Pages_Host.cshtml
(сервер Blazor):
Дополнительные сведения о RCL и библиотеках классов Razor см. В следующих статьях:
Основные функции: Встроенная поддержка CSS
Примеры Next.js позволяет импортировать файлы CSS из файла JavaScript.
Это возможно, потому что Next.js расширяет концепцию import
за пределы JavaScript.
Чтобы добавить таблицу стилей в приложение, импортируйте файл CSS в пределах страниц / _app.js
.
Например, рассмотрим следующую таблицу стилей с именем styles.css
:
body {
семейство шрифтов: 'SF Pro Text', 'SF Pro Icons', 'Helvetica Neue', 'Helvetica',
"Arial", без засечек;
отступ: 20 пикселей, 20 пикселей, 60 пикселей;
максимальная ширина: 680 пикселей;
маржа: 0 авто;
}
Создайте файл pages / _app.js
, если он еще не существует.
Затем импортирует
файл styles.css
.
import '../styles.css'
экспортировать функцию по умолчанию MyApp ({Component, pageProps}) {
return <Компонент {...pageProps} />
}
Эти стили ( styles.css
) будут применяться ко всем страницам и компонентам в вашем приложении.
Из-за глобального характера таблиц стилей и во избежание конфликтов вы можете импортировать их только внутри страниц / _app.js
.
В процессе разработки такое представление таблиц стилей позволяет выполнять горячую перезагрузку стилей по мере их редактирования, что означает, что вы можете сохранить состояние приложения.
В процессе производства все файлы CSS будут автоматически объединены в один минифицированный .css
файл.
Импорт стилей из
node_modules
Начиная с Next.js 9.5.4 , импорт файла CSS из node_modules
разрешен в любом месте вашего приложения.
Для глобальных таблиц стилей, таких как bootstrap
или nprogress
, вы должны импортировать файл внутри pages / _app.js
.
Например:
импортировать 'bootstrap / dist / css / bootstrap.css'
экспортировать функцию по умолчанию MyApp ({Component, pageProps}) {
return <Компонент {...pageProps} />
}
Для импорта CSS, требуемого сторонним компонентом, вы можете сделать это в своем компоненте. Например:
импортировать {useState} из "реагировать"
импортировать {Dialog} из '@reach / dialog'
import VisuallyHidden из '@reach / visually-hidden'
import '@reach / dialog / styles.css'
function ExampleDialog (props) {
const [showDialog, setShowDialog] = useState (ложь)
const open = () => setShowDialog (истина)
const close = () => setShowDialog (ложь)
возвращаться (
)
}
Next.js поддерживает модули CSS, используя соглашение об именах файлов [имя] .module.css
.
CSS локально охватывают CSS, автоматически создавая уникальное имя класса. Это позволяет использовать одно и то же имя класса CSS в разных файлах, не беспокоясь о коллизиях.
Такое поведение делает модули CSS идеальным способом включения CSS на уровне компонентов. Файлы модуля CSS можно импортировать в любое место вашего приложения .
Например, рассмотрим повторно используемый компонент Button
в папке components /
:
Сначала создайте компонентов / Button.module.css
со следующим содержимым:
.ошибка {
цвет белый;
цвет фона: красный;
}
Затем создайте components / Button.js
, импортировав и используя указанный выше файл CSS:
импортировать стили из './Button.module.css'
кнопка функции экспорта () {
возвращаться (
кнопка <
type = "кнопка"
className = {стили.ошибка}
>
Разрушать
)
}
Модули CSS являются дополнительной функцией , и включены только для файлов с расширением .module.css
.
Стандартные таблицы стилей
и глобальные файлы CSS по-прежнему поддерживаются.
В процессе производства все файлы модуля CSS будут автоматически объединены в много минифицированных и разделенных кодом .css
файлов.
Эти файлы .css и
представляют собой горячие пути выполнения в вашем приложении, гарантируя, что минимальный объем CSS загружен для вашего приложения для рисования.
Next.js позволяет импортировать Sass с использованием расширений .scss
и .sass
.
Вы можете использовать Sass на уровне компонентов через модули CSS и расширение .module.scss
или .module.sass
.
Прежде чем вы сможете использовать встроенную поддержку Sass в Next.js, обязательно установите sass
:
npm установить sass
ПоддержкаSass имеет те же преимущества и ограничения, что и встроенная поддержка CSS, описанная выше.
Примечание : Sass поддерживает два разных синтаксиса, каждый со своим собственным расширением. Расширение
.scss
требует использования синтаксиса SCSS, в то время как расширение.sass
требует использования синтаксиса с отступом («Sass»).Если вы не уверены, что выбрать, начните с расширения
.scss
, которое является надмножеством CSS и не требует изучения Синтаксис с отступом («Sass»).
Настройка параметров Sass
Если вы хотите настроить компилятор Sass, вы можете сделать это, используя sassOptions
в next.config.js
.
Например, чтобы добавить , includePaths
:
const path = require ('путь')
module.exports = {
sassOptions: {
includePaths: [path.join (__ dirname, 'styles')],
},
}
Примеры Можно использовать любое существующее решение CSS-in-JS. Самый простой — встроенные стили:
function HiThere () {
return привет
}
экспорт по умолчанию HiThere
Мы объединяем styled-jsx, чтобы обеспечить поддержку CSS с изолированной областью видимости.Цель состоит в том, чтобы поддерживать «теневой CSS», аналогичный веб-компонентам, которые, к сожалению, не поддерживают рендеринг на сервере и предназначены только для JS.
См. Приведенные выше примеры для других популярных решений CSS-in-JS (например, стилизованных компонентов).
Компонент, использующий styled-jsx
, выглядит так:
function HelloWorld () {
возвращаться (
Привет мир
с ограничением!
<стиль глобального jsx> {`
тело {
фон: черный;
}
`}
)
}
экспорт по умолчанию HelloWorld
Дополнительные примеры см. В документации по styled-jsx.
Работает ли он с отключенным JavaScript?
Да, если вы отключите JavaScript, CSS все равно будет загружен в производственную сборку ( при следующем запуске
). Во время разработки мы требуем, чтобы JavaScript был включен, чтобы обеспечить максимальное удобство для разработчиков с помощью Fast Refresh.