элементы - псевдо селекторы css




Есть ли предыдущий селектор CSS? (9)

+ для следующего брата. Есть ли эквивалент для предыдущего брата?

Вы можете использовать два селектора ! и ?

В традиционном CSS есть 2 последующих селектора:

  • + является непосредственным последующим селектором
  • ~ - это любой последующий селектор

В обычном CSS нет предыдущего селектора .

Однако в пост-процессорной библиотеке ax ax есть 2 предыдущих селектора:

  • ? - это непосредственный предыдущий селектор (напротив + )
  • ! - это любой предыдущий селектор (напротив ~ )

Рабочий пример:

В приведенном ниже примере:

  • .any-subsequent:hover ~ div выбирает любой последующий div
  • .immediate-subsequent:hover + div выбирает немедленный последующий div
  • .any-previous:hover ! div .any-previous:hover ! div выбирает любой предыдущий div
  • .immediate-previous:hover ? div .immediate-previous:hover ? div выбирает ближайший предыдущий div

div {
  display: inline-block;
  width: 60px;
  height: 100px;
  color: rgb(255, 255, 255);
  background-color: rgb(255, 0, 0);
  text-align: center;
  vertical-align: top;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.6s ease-out;
}

code {
  display: block;
  margin: 4px;
  font-size: 24px;
  line-height: 24px;
  background-color: rgba(0, 0, 0, 0.5);
}

div:nth-of-type(-n+4) {
  background-color: rgb(0, 0, 255);
}

div:nth-of-type(n+3):nth-of-type(-n+6) {
  opacity: 1;
}

.any-subsequent:hover ~ div,
.immediate-subsequent:hover + div,
.any-previous:hover ! div,
.immediate-previous:hover ? div {
  opacity: 1;
}
<h2>Hover over any of the blocks below</h2>

<div></div>
<div></div>

<div class="immediate-previous">Hover for <code>?</code> selector</div>
<div class="any-previous">Hover for <code>!</code> selector</div>
<div class="any-subsequent">Hover for <code>~</code> selector</div>
<div class="immediate-subsequent">Hover for <code>+</code> selector</div>

<div></div>
<div></div>

<script src="https://rouninmedia.github.io/axe/axe.js"></script>

+ для следующего брата. Есть ли эквивалент для предыдущего брата?


Рассмотрим свойство order flex и grid layouts.

В приведенных ниже примерах я сосредоточусь на flexbox, но те же понятия применимы к Grid.

С помощью flexbox можно моделировать предыдущий селектор.

В частности, свойство flex order может перемещать элементы вокруг экрана.

Вот пример:

Вы хотите, чтобы элемент A загорелся, когда элемент B зависает.

<ul>
    <li>A</li>
    <li>B</li>
</ul>

ШАГОВ

  1. Сделайте контейнер ul гибким.

    ul { display: flex; }
    
  1. Измените порядок братьев и сестер в надбавке.

    <ul>
       <li>B</li>
       <li>A</li>
    </ul>
    
  1. Используйте селектор sibling для целевого элемента A ( ~ или + сделайте).

    li:hover + li { background-color: red; }
    
  1. Используйте свойство flex order чтобы восстановить порядок братьев и сестер на визуальном дисплее.

    li:last-child { order: -1; }
    

... и вуаля! Предыдущий родительский селектор рождается (или, по крайней мере, имитируется).

Вот полный код:

ul {
    display: flex;
}

li:hover + li {
    background-color: red;
}

li:last-child {
    order: -1;
}

/* non-essential decorative styles */
li {
    height: 200px;
    width: 200px;
    background-color: aqua;
    margin: 5px;
    list-style-type: none;
    cursor: pointer;
}
<ul>
    <li>B</li>
    <li>A</li>
</ul>

Из спецификации flexbox:

5.4. Заказ показа: свойство order

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

Свойство order управляет порядком, в котором элементы гибкости появляются в контейнере flex, назначая их порядковым группам. Он принимает единственное значение <integer> , которое указывает, к какой порядковой группе принадлежит элемент flex.

Начальное значение order для всех элементов flex равно 0.

Также см. order в спецификации CSS Grid Layout .

Примеры «предыдущих селекторов севера», созданных с помощью свойства flex order .

.container { display: flex; }

.box5 { order: 1; }    
.box5:hover + .box4 { background-color: orangered; font-size: 1.5em; }

.box6 { order: -4; }
.box7 { order: -3; }
.box8 { order: -2; }
.box9 { order: -1; }
.box9:hover ~ :not(.box12):nth-child(-1n+5) { background-color: orangered;
                                              font-size: 1.5em; }
.box12 { order: 2; }
.box12:hover ~ :nth-last-child(-1n+2) { background-color: orangered;
                                        font-size: 1.5em; }
.box21 { order: 1; }
.box21:hover ~ .box { background-color: orangered; font-size: 1.5em; }

/* non-essential decorative styles */
.container {
    padding: 5px;
    background-color: #888;
}
.box {
    height: 50px;
    width: 75px;
    margin: 5px;
    background-color: lightgreen;
    display: flex;
    justify-content: center;
    align-items: center;
    text-align: center;
    cursor: pointer;
}
<p>
Using the flex <code>order</code> property to construct a previous sibling selector
</p>

<div class="container">
    <div class="box box1"><span>1</span></div>
    <div class="box box2"><span>2</span></div>
    <div class="box box3"><span>3</span></div>
    <div class="box box5"><span>HOVER ME</span></div>
    <div class="box box4"><span>4</span></div>
</div>

<br>

<div class="container">
    <div class="box box9"><span>HOVER ME</span></div>
    <div class="box box12"><span>HOVER ME</span></div>
    <div class="box box6"><span>6</span></div>
    <div class="box box7"><span>7</span></div>
    <div class="box box8"><span>8</span></div>
    <div class="box box10"><span>10</span></div>
    <div class="box box11"><span>11</span></div>
</div>

<br>

<div class="container">
    <div class="box box21"><span>HOVER ME</span></div>
    <div class="box box13"><span>13</span></div>
    <div class="box box14"><span>14</span></div>
    <div class="box box15"><span>15</span></div>
    <div class="box box16"><span>16</span></div>
    <div class="box box17"><span>17</span></div>
    <div class="box box18"><span>18</span></div>
    <div class="box box19"><span>19</span></div>
    <div class="box box20"><span>20</span></div>
</div>

jsFiddle

Боковое примечание - две устаревшие убеждения о CSS

Flexbox разрушает давние убеждения в отношении CSS.

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

Сказать, что это убеждение широко распространено, было бы преуменьшением. Ниже приведена выборка связанных вопросов для переполнения стека:

  • Выберите предыдущий родственный элемент в CSS с помощью селекторов
  • CSS: выберите предыдущий брат
  • CSS выберите предыдущий брат
  • Предыдущий смежный селектор в CSS
  • Выбрать предыдущих братьев и сестер
  • Селектор CSS для получения предыдущего брата
  • Изменение цвета элементов-близнецов при наведении с помощью CSS
  • Как выбрать предыдущего брата с использованием синтаксиса selenium css
  • CSS Selector для выбора элемента, который приходит перед другим элементом?
  • Как добавить стиль к предыдущему брату активного входа, используя только CSS
  • Селектор CSS для следующих и предыдущих элементов
  • Как влиять на другие элементы, когда висит div

Как описано выше, это убеждение не совсем верно. Предыдущий селектор сиблинга может быть смоделирован в CSS с использованием свойства flex order .

Миф о z-index

Еще одна давняя вера заключалась в том, что z-index работает только с позиционируемыми элементами.

Фактически, самая последняя версия спецификации - W3C Editor's Draft - по-прежнему утверждает, что это правда:

9.9.1. Определение уровня стека: свойство z-index

z-index

  • Значение: авто | | унаследовать
  • Начальное: авто
  • Применяется к: позиционированным элементам
  • Унаследовано: нет
  • Процентное: N / A
  • Медиа: визуальное
  • Вычисленное значение: как указано

(выделено мной)

Однако на самом деле эта информация устарела и неточна.

Элементы, которые являются гибкими элементами или элементами сетки, могут создавать контексты стекирования, даже когда position static .

4,3. Flex Item Z-Ordering

Элементы Flex окрашиваются точно так же, как и встроенные блоки, за исключением того, что порядок ортогональных документов используется вместо необработанного порядка документа, а значения z-index отличные от auto создают контекст стекирования, даже если position static .

5.4. Z-axis Ordering: свойство z-index

Порядок окраски элементов сетки точно такой же, как и встроенные блоки, за исключением того, что порядок ортогональных документов используется вместо необработанного порядка документа, а значения z-index отличные от auto создают контекст стекирования, даже если position static .

Вот демонстрация z-index работающего над непозиционированными элементами гибкости: https://jsfiddle.net/m0wddwxs/


В зависимости от вашей конкретной цели существует способ достижения полезности родительского селектора без использования одного (даже если он существует) ...

Скажем, у нас есть:

<div>
  <ul>
    <li><a>Pants</a></li>
    <li><a>Socks</a></li>
    <ul>
      <li><a>White socks</a></li>
      <li><a>Blue socks</a></li>
    </ul>
  </ul>
</div>

Что мы можем сделать, чтобы блок Socks (включая цвета носка) выделялся визуально с использованием интервала?

Что было бы неплохо, но не существует:

ul li ul:parent {
  margin-top: 15px;
  margin-bottom: 15px;
}

Что существует:

li > a {
  margin-top: 15px;
  display: block;
}
li > a:only-child {
  margin-top: 0px;
}

Это устанавливает, что все привязные ссылки имеют верхний край 15px и сбрасывают его обратно на 0 для тех, у которых нет элементов UL (или других тегов) внутри LI.


В настоящий момент нет официального способа сделать это, но вы можете использовать небольшой трюк, чтобы достичь этого! Помните, что это экспериментально, и у него есть некоторые ограничения ... (проверьте эту ссылку, если вы беспокоитесь о совместимости с навигатором)

Что вы можете сделать, это использовать селектор CSS3: псевдоклас, называемый nth-child()

#list>* {
  display: inline-block;
  padding: 20px 28px;
  margin-right: 5px;
  border: 1px solid #bbb;
  background: #ddd;
  color: #444;
  margin: 0.4em 0;
}

#list :nth-child(-n+4) {
  color: #600b90;
  border: 1px dashed red;
  background: orange;
}
<p>The oranges elements are the previous sibling li selected using li:nth-child(-n+4)</p>

<div id="list">
  <span>1</span><!-- this will be selected -->
  <p>2</p><!-- this will be selected -->
  <p>3</p><!-- this will be selected -->
  <div>4</div><!-- this will be selected -->
  <div>5</div>
  <p>6</p>
  <p>7</p>
  <p>8</p>
  <p>9</p>
</div>

Ограничения

  • Вы не можете выбирать предыдущие элементы на основе классов следующих элементов
  • Это одинаково для псевдо классов

Если вы знаете точную позицию и :nth-child() - исключение всех следующих братьев и сестер будет работать.

ul li:not(:nth-child(n+3))

Который выберет все li до третьего (например, 1-го и 2-го). Но, на мой взгляд, это выглядит уродливым и имеет очень плотную работу.

Вы также можете выбрать n-й-правый справа налево:

ul li:nth-child(-n+2)

Что делает то же самое.


К сожалению, нет «предыдущего» селектора, но вы можете получить тот же эффект, используя позиционирование (например, float right). Это зависит от того, что вы пытаетесь сделать.

В моем случае я хотел получить первую 5-звездочную рейтинговую систему. Мне нужно было бы покрасить (или поменять значок) предыдущих звезд. Путем плавания каждого элемента вправо, я по сути получаю тот же эффект (html для звезд, таким образом, должен быть записан «назад»).

Я использую FontAwesome в этом примере и обмениваюсь между юникодами fa-star-o и fa-star http://fortawesome.github.io/Font-Awesome/

CSS:

.fa {
    display: inline-block;
    font-family: FontAwesome;
    font-style: normal;
    font-weight: normal;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* set all stars to 'empty star' */
.stars-container {
    display: inline-block;      
}   

/* set all stars to 'empty star' */
.stars-container .star {
    float: right;
    display: inline-block;
    padding: 2px;
    color: orange;
    cursor: pointer;

}

.stars-container .star:before {
    content: "\f006"; /* fontAwesome empty star code */
}

/* set hovered star to 'filled star' */
.star:hover:before{
    content: "\f005"; /* fontAwesome filled star code */
}

/* set all stars after hovered to'filled star' 
** it will appear that it selects all after due to positioning */
.star:hover ~ .star:before {
    content: "\f005"; /* fontAwesome filled star code */
}

HTML: (40)

JSFiddle: http://jsfiddle.net/andrewleyva/88j0105g/


У меня был тот же вопрос, но потом у меня был момент «духа». Вместо написания

x ~ y

записывать

y ~ x

Очевидно, что это соответствует «x» вместо «y», но отвечает «есть ли матч?». вопрос и простой обход DOM могут привести вас к правильному элементу более эффективно, чем цикл в javascript.

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


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

  1. дайте всем вашим предметам стиль.
  2. придать выбранному элементу стиль.
  3. введите следующие элементы в стиле, используя + или ~.

и таким образом вы сможете создавать свои текущие предыдущие элементы (все элементы, переопределенные текущими и последующими элементами), и ваши последующие элементы.

пример:

/* all items (will be styled as previous) */
li {
  color: blue;
}

/* the item i want to distinguish */
li.milk {
  color: red;
}

/* next items */
li ~ li  {
  color: green;
}


<ul>
  <li>Tea</li>
  <li class="milk">Milk</li>
  <li>Juice</li>
  <li>others</li>
</ul>

Надеюсь, это поможет кому-то.


Селектор уровня 4 вводит :has() (ранее индикатор объекта ! ), Который позволит вам выбрать предыдущего брата:

previous:has(+ next) {}

... но на момент написания, это некоторая дистанция за пределы кровопускания для поддержки браузера.





css-selectors