У меня разбиты таблицы стилей для представления отдельных компонентов (nav, nav-item и т. Д.). Я пытаюсь понять, как лучше разрешить родительскому элементу переопределять дочерний стиль в зависимости от его состояния или контекста (изменить элемент nav, когда навигация открыта, изменить nav, когда он находится на домашней странице и т. Д.).
Скажем, например, у меня есть навигация, которая содержит элементы навигации. Они разделены на свои собственные таблицы стилей nav.scss и nav-item.scss. Когда к компоненту .nav добавлен класс .open, я хочу, чтобы фон элемента .nav стал красным. Я мог бы сделать это так:
/* nav.scss */
@import nav-item.scss
.nav{
&.open{
.nav-item{
background: red;
}
}
}
/* nav-item.scss */
.nav-item{
background: blue;
}
Это работает нормально, но теперь стили, которые применяются к .nav-item, применяются вне таблицы стилей .nav-item, если это происходит в нескольких местах, это может затруднить отслеживание того, какой файл добавляется какие стили для .nav-элемента. Альтернатива такова:
/* nav.scss */
@import nav-item.scss
.nav{
}
/* nav-item.scss */
.nav-item{
background: blue;
.nav.open &{
background: red;
}
}
Этот синтаксис позволяет мне добраться до родительского дерева и посмотреть, вложен ли я в .nav.open, а затем применить красный фон. Это здорово, потому что все стили nav-items теперь содержатся в одном файле, что упрощает просмотр всех возможностей. Тем не менее, я все еще ссылаюсь на внешний класс, который кажется неправильным, плюс, если у меня есть много вариантов, этот файл может быстро испортиться:
/* nav-item.scss */
.nav-item{
background: blue;
.nav.open &{
background: red;
}
.nav.sticky.open &{
background: blue;
}
.homepage .nav.open &{
@media screen and (max-width: $break-small) {
background: green;
}
}
}
Мы можем попробовать использовать миксины:
/* nav.scss */
@import nav-item.scss
.nav{
&.open{
@include navItemRedWide();
}
}
/* nav-item.scss */
.nav-item{
background: blue;
}
@mixin navItemRedWide() {
.nav-item {
background: red;
width: 400px;
}
}
Это эффективно позволяет nav-item.scss содержать все его собственные стили и позволяет .nav определять, какие стили применять, без возможности прямого добавления / изменения свойств стиля в классе. Это кажется лучше, чем другое решение, но может привести к большому количеству миксинов и, возможно, к большому количеству повторяющегося кода, если мне придется повторять вложение в каждом миксине:
/* nav-item.scss */
@mixin navItemLargeIcon() {
.nav-item {
.inner{
.icon{
font-size: 4rem;
}
}
}
}
@mixin navItemSmallIcon() {
.nav-item {
.inner{
.icon{
font-size: 1rem;
}
}
}
}
Наконец, эта проблема усугубляется, если у меня есть дочерний компонент дочернего компонента, из которого вам необходимо извлечь миксины:
/* nav.scss */
@import nav-panel.scss
@import nav-item.scss
.nav{
&.open{
@include navItemRed();
@include navPanelRed();
}
}
/* nav-panel.scss */
@import nav-item.scss
.nav-panel{
background: blue;
&.collapse{
@include navPanelBlue();
}
}
@mixin navPanelRed() {
.nav-panel {
background: red;
}
}
/* nav-item.scss */
.nav-item{
background: blue;
}
@mixin navItemRed() {
.nav-item {
background: red;
}
}
@mixin navItemBlue() {
.nav-item {
background: red;
}
}
Теперь у меня есть корневые файлы, которые импортируют дочерние элементы детей, чтобы просто применить их миксин, в то время как средний дочерний элемент также импортирует дочерний элемент и, возможно, применяет перекрывающие миксины, в то время как все становится просто неразрывным беспорядком.
Каков наилучший способ применения стилей контекста или состояния и переопределений дочерних компонентов?