Универсальный селектор с потомственной спецификой селектора - PullRequest
2 голосов
/ 28 марта 2019

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

.container > * + * {
  margin-top: 1rem;
}

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

Если к дочернему компоненту был применен сброс к его полям, например…

.child {
  margin: 0
}

… и он загружается после .container css, его стильпобедит, потому что селектор подстановочного знака не имеет специфичности, что означает, что оба объявления имеют одинаковый вес (поэтому последнее объявление победит).

Я не хочу, чтобы контейнер знал или заботился о том, каковы его дочерние элементы (и я не хочу добавлять определенный класс всем детям).

Есть ли способ повысить специфичность первого селектора, оставляя его универсальным (таким образом, он применяется к любым дочерним элементам).

Ответы [ 2 ]

2 голосов
/ 28 марта 2019

Более элегантная альтернатива (то есть та, которая поставляется с необходимой вам дополнительной специфичностью, не требующей взлома специфичности) - это

.container > :not(:first-child)

, которая функционально эквивалентна вашему исходному селектору со спецификой (0, 2, 0) по сравнению с оригиналом (0, 1, 0).

.container {
  margin: 1rem 0;
  border-style: solid;
}

/* 1 class, 1 pseudo-class -> specificity = (0, 2, 0) */
.container > :not(:first-child) {
  margin-top: 1rem;
}

/* 1 class                 -> specificity = (0, 1, 0) */
.child {
  margin: 0;
}
<div class="container">
  <div class="child">Child</div>
  <div class="child">Child</div>
  <div class="child">Child</div>
</div>
<div class="container">
  <div class="child">Child</div>
  <div class="child">Child</div>
  <div class="child">Child</div>
</div>
1 голос
/ 28 марта 2019

добавив селектор

.container > * + [class] 

Вы можете получить более конкретный селектор, как кажется для правила поля.

Вы также можете использовать правило: not (), предложенное Temani Afif

.container, .container2, .container3 {
   background-color: goldenrod;
   border: 1px solid black;
   display: block;
   margin-bottom:50px;
}

.container > * + * {
  margin-top: 1rem;
}

.container2 > * + *,
.container2 > * + [class] {
  margin-top: 1rem;
}

.container3:not(#doyoudreamofelectricsheep) > * + * {
  margin-top: 1rem;
}


.child {
  margin: 0;
  height: 20px;
  background-color:red;
  color: black;
  
}

.foobar {
  height: 20px;
  background-color:black;
  color: white;
}
Without the "fix"
<section class="container2">
   <div class="foobar">
       foobar
   </div>
   <div class="child">
       child
   </div>
   <div class="foobar">
       foobar
   </div>
   <div class="child">
       child
   </div>
   <div class="foobar">
       foobar
   </div>
   <div class>
       just class
   </div>
</section>

With the [class] "fix"
<section class="container2">
   <div class="foobar">
       foobar
   </div>
   <div class="child">
       child
   </div>
   <div class="foobar">
       foobar
   </div>
   <div class="child">
       child
   </div>
   <div class="foobar">
       foobar
   </div>
   <div class>
       just class
   </div>
</section>

With the :not(#doyoudreamofelectricsheep) "fix"
<section class="container3">
   <div class="foobar">
       foobar
   </div>
   <div class="child">
       child
   </div>
   <div class="foobar">
       foobar
   </div>
   <div class="child">
       child
   </div>
   <div class="foobar">
       foobar
   </div>
   <div class>
       just class
   </div>
</section>
...