Знак плюс ( +
) предназначен для следующего брата.
Есть ли эквивалент для предыдущего брата?
Знак плюс ( +
) предназначен для следующего брата.
Есть ли эквивалент для предыдущего брата?
Ответы:
Нет, селектор «предыдущий брат» отсутствует.
С другой стороны, ~
это для родного брата-наследника (имеется в виду, что элемент идет после этого, но не обязательно сразу после) и является селектором CSS3. +
для следующего родного брата и CSS2.1.
См. Смежный братский комбинатор от селекторов уровня 3 и 5.7 Смежные соседние братские селекторы от каскадных таблиц стилей, редакция 1 уровня 2 (CSS 2.1) .
Я нашел способ стилизовать всех предыдущих братьев и сестер (напротив ~
), которые могут работать в зависимости от того, что вам нужно.
Допустим, у вас есть список ссылок, и при наведении на одну из них все предыдущие должны стать красными. Вы можете сделать это так:
/* default link color is blue */
.parent a {
color: blue;
}
/* prev siblings should be red */
.parent:hover a {
color: red;
}
.parent a:hover,
.parent a:hover ~ a {
color: blue;
}
<div class="parent">
<a href="#">link</a>
<a href="#">link</a>
<a href="#">link</a>
<a href="#">link</a>
<a href="#">link</a>
</div>
float:right
). Для этого потребовался пробел между единицами / словами и отступами вместо полей, но он работает совершенно иначе!
Селектор уровня 4 вводит:has()
(ранее индикатор предмета !
), который позволит вам выбрать предыдущего брата с:
previous:has(+ next) {}
... но на момент написания этой статьи, это некое преимущество за пределами поддержки браузеров.
:has()
псевдокласс.
order
свойство гибких и сеточных макетов.Я сосредоточусь на flexbox в примерах ниже, но те же понятия применимы к Grid.
С помощью flexbox можно смоделировать предыдущий селектор брата.
В частности, order
свойство flex может перемещать элементы по экрану.
Вот пример:
Вы хотите, чтобы элемент A стал красным, когда элемент B наведен.
<ul> <li>A</li> <li>B</li> </ul>
ШАГОВ
Сделайте ul
гибкий контейнер.
ul { display: flex; }
Обратный порядок братьев и сестер в разметке.
<ul>
<li>B</li>
<li>A</li>
</ul>
Используйте селектор брата, чтобы предназначаться для Элемента A ( ~
или +
сделаю).
li:hover + li { background-color: red; }
Используйте order
свойство flex, чтобы восстановить порядок братьев и сестер на визуальном дисплее.
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
управляет свойство порядок , в котором гибкие элементы появляются в гибком контейнере, назначая их порядковые группы. Он принимает одно<integer>
значение, которое указывает, к какой порядковой группе относится элемент flex.
Начальное order
значение для всех элементов flex - 0.
Также смотрите order
в спецификации CSS Grid Layout .
Примеры «предыдущих селекторов братьев и сестер», созданных с помощью order
свойства flex .
.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>
Flexbox разрушает давние убеждения о CSS.
Одним из таких убеждений является то, что предыдущий селектор брата не возможен в CSS .
Сказать, что это убеждение широко распространено, было бы преуменьшением. Вот выборка связанных вопросов только по переполнению стека:
Как описано выше, это убеждение не совсем верно. Предыдущий селектор брата может быть смоделирован в CSS с помощью order
свойства flex .
z-index
Миф
Другое давнее убеждение заключается в том, что он z-index
работает только с позиционированными элементами.
На самом деле, самая последняя версия спецификации - проект редактора W3C - все еще утверждает, что это правда:
9.9.1 Указание уровня стека:
z-index
свойство
z-index
- Значение: авто | | унаследуют
- По умолчанию: авто
- Относится к: позиционированным элементам
- Наследуется: нет
- Проценты: N / A
- Медиа: визуальный
- Расчетное значение: как указано
(выделение добавлено)
В действительности, однако, эта информация является устаревшей и неточной.
Элементы, которые являются гибкими элементами или элементами сетки, могут создавать контексты стекирования, даже когда они position
есть static
.
Элементы Flex отображаются точно так же, как и встроенные блоки, за исключением того, что порядок документов с измененным порядком используется вместо порядка необработанных документов, и
z-index
значения, отличные отauto
контекста стека, даже если ониposition
естьstatic
.5.4. Ось Z Порядок:
z-index
свойствоПорядок рисования элементов сетки точно такой же, как и у встроенных блоков, за исключением того, что порядок документов с измененным порядком используется вместо порядка необработанных документов, а
z-index
значенияauto
отличаются от контекста стека, даже если онposition
естьstatic
.
Вот демонстрация z-index
работы с не позиционированными элементами Flex: https://jsfiddle.net/m0wddwxs/
order
Свойство не является решением , поскольку оно предназначено исключительно для изменения визуального порядка, так что это не восстановить первоначальный семантический порядок , который вы вынуждены изменения в HTML для этого обходного пути на работу.
z-index
будет работать, даже если «omg, там не position
указано!», В спецификации упоминается концепция стекового контекста , что хорошо объясняется в этой статье о MDN
float: right
(или с любым другим способом отменить порядок, который flex/order
имеет небольшие (наименьшие?) Побочные эффекты). Взбил две скрипки: демонстрация float: right
подхода и демонстрацияdirection: rtl
У меня был тот же вопрос, но потом у меня был "дух" момент. Вместо того чтобы писать
x ~ y
записывать
y ~ x
Очевидно, что это соответствует «х» вместо «у», но отвечает «есть совпадение?» вопрос, и простой обход DOM может привести вас к нужному элементу более эффективно, чем зацикливание в javascript.
Я понимаю, что исходный вопрос был вопросом CSS, поэтому этот ответ, вероятно, совершенно не имеет значения, но другие пользователи Javascript могут наткнуться на вопрос с помощью поиска, как я.
y ~ x
можно решить мою проблему
y ~ x
не отвечает "есть совпадение?" вопрос, потому что два селектора, приведенные здесь, означают совершенно разные вещи. Там нет никакого способа, y ~ x
чтобы когда-либо произвести сопоставление, данное поддерево, <root><x/><y/></root>
например. Если вопрос "существует ли у?" тогда селектор просто y
. Если вопрос «существует ли у данного брата х в любой произвольной позиции?» тогда вам понадобятся оба селектора. (Хотя, может быть, я просто придираюсь к этому моменту ...)
Два трюка . В основном, инвертирование порядка HTML ваших желаемых элементов в HTML и использование оператора
~
Next siblings :
float-right
+ обратный порядок элементов HTMLdiv{ /* Do with the parent whatever you know just to make the
inner float-right elements appear where desired */
display:inline-block;
}
span{
float:right; /* float-right the elements! */
}
span:hover ~ span{ /* On hover target it's "previous";) elements */
background:red;
}
<div>
<!-- Reverse the order of inner elements -->
<span>5</span>
<span>4</span>
<span>3</span>
<span>2</span>
<span>1</span>
</div>
direction: rtl;
+ в обратном порядке внутренних элементов.inverse{
direction: rtl;
display: inline-block; /* inline-block to keep parent at the left of window */
}
span:hover ~ span{ /* On hover target it's "previous";) elements */
background:gold;
}
Hover one span and see the previous elements being targeted!<br>
<div class="inverse">
<!-- Reverse the order of inner elements -->
<span>5</span>
<span>4</span>
<span>3</span>
<span>2</span>
<span>1</span>
</div>
+
для следующего родного брата. Есть ли эквивалент для предыдущего брата?
!
и?
В обычном CSS есть 2 последовательных селектора :
+
является непосредственным последующим селектором родного брата~
это любой последующий селектор родственныйВ обычном CSS нет никакого предыдущего родственного селектора .
Однако в библиотеке постпроцессора Axe CSS есть два предыдущих селектора :
?
является непосредственным предыдущим селектором родного брата (напротив +
)!
это любой предыдущий селектор родственный (противоположность ~
)Рабочий пример:
В приведенном ниже примере:
.any-subsequent:hover ~ div
выбирает любой последующий div
.immediate-subsequent:hover + div
выбирает непосредственное последующее div
.any-previous:hover ! div
выбирает любой предыдущий 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>
Вы можете использовать обратный порядок элементов в HTML. Тогда помимо использования, order
как в ответе Michael_B, вы можете использовать flex-direction: row-reverse;
илиflex-direction: column-reverse;
зависимости от вашего макета.
Рабочий образец:
.flex {
display: flex;
flex-direction: row-reverse;
/* Align content at the "reversed" end i.e. beginning */
justify-content: flex-end;
}
/* On hover target its "previous" elements */
.flex-item:hover ~ .flex-item {
background-color: lime;
}
/* styles just for demo */
.flex-item {
background-color: orange;
color: white;
padding: 20px;
font-size: 3rem;
border-radius: 50%;
}
<div class="flex">
<div class="flex-item">5</div>
<div class="flex-item">4</div>
<div class="flex-item">3</div>
<div class="flex-item">2</div>
<div class="flex-item">1</div>
</div>
Официального способа сделать это в настоящее время не существует, но вы можете использовать небольшой трюк для достижения этой цели! Помните, что он экспериментальный и имеет некоторые ограничения ... (проверьте эту ссылку, если вы беспокоитесь о совместимости навигатора)
Что вы можете сделать, это использовать селектор 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(-n+4)
это псевдокласс, который нужно применить к селектору, чтобы он работал правильно. Если вы не уверены, попробуйте поэкспериментировать с вилкой моей скрипки, и вы увидите, что она не работает
*
селектор, но это ужасно плохая практика.
li#someListItem
и я хотел, чтобы узлы были перед ним (именно так я интерпретирую «предыдущий») - я не понимаю, как предоставленная вами информация может помочь мне выразить это через CSS. Вы просто выбираете первые n братьев и сестер и предполагаете, что я знаю n. Основываясь на этой логике, любой селектор может сделать свое дело и выбрать нужный мне элемент (ы) (например, not ()).
Если вы знаете точную позицию, :nth-child()
сработает исключение всех следующих братьев и сестер на основе.
ul li:not(:nth-child(n+3))
Который выбрал бы все li
s до 3-го (например, 1-го и 2-го). Но, на мой взгляд, это выглядит некрасиво и имеет очень узкий сценарий использования.
Вы также можете выбрать nth-child справа налево:
ul li:nth-child(-n+2)
Который делает то же самое.
Нет. Это невозможно через CSS. Он принимает "Каскад" близко к сердцу ;-).
Однако, если вы сможете добавить JavaScript на свою страницу, немного jQuery поможет вам достичь конечной цели.
Вы можете использовать jQuery find
для «предварительного просмотра» целевого элемента / класса / id, а затем вернуться назад, чтобы выбрать цель.
Затем вы используете jQuery, чтобы переписать DOM (CSS) для вашего элемента.
Основываясь на этом ответе Майка Бранта , может помочь следующий фрагмент jQuery.
$('p + ul').prev('p')
Сначала выбираются все <ul>
s, которые сразу же следуют за <p>
.
Затем он «возвращается», чтобы выбрать все предыдущие <p>
s из этого набора <ul>
s.
По сути, «предыдущий брат» был выбран с помощью jQuery.
Теперь используйте .css
функцию, чтобы передать новые значения CSS для этого элемента.
В моем случае я искал способ выбрать DIV с идентификатором #full-width
, но ТОЛЬКО если он имел (косвенный) потомок DIV с классом .companies
.
Я контролировал весь HTML-код .companies
, но не мог изменить ни один из HTML-кодов над ним.
И каскад идет только в 1 направлении: вниз.
Таким образом я мог выбрать ВСЕ #full-width
s.
Или я мог выбрать, .companies
что только следовал за #full-width
.
Но я не мог выбрать только #full-width
то, что продолжалось .companies
.
И, опять же, я не смог добавить .companies
выше в HTML. Эта часть HTML была написана внешне и обернула наш код.
Но с помощью jQuery я могу выбрать нужные #full-width
s, а затем назначить соответствующий стиль:
$("#full-width").find(".companies").parents("#full-width").css( "width", "300px" );
Он находит все #full-width .companies
и выбирает только те .companies
, которые похожи на то, как селекторы используются для нацеливания на определенные элементы в стандарте в CSS.
Затем он использует .parents
«backtrack» и выбирает ВСЕХ родителей .companies
,
но фильтрует эти результаты, чтобы сохранить только #fill-width
элементы, так что, в конце концов,
он выбирает #full-width
элемент, только если у него есть .companies
потомок класса.
Наконец, он присваивает новое значение CSS ( width
) результирующему элементу.
$(".parent").find(".change-parent").parents(".parent").css( "background-color", "darkred");
div {
background-color: lightblue;
width: 120px;
height: 40px;
border: 1px solid gray;
padding: 5px;
}
.wrapper {
background-color: blue;
width: 250px;
height: 165px;
}
.parent {
background-color: green;
width: 200px;
height: 70px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<div class="wrapper">
<div class="parent">
"parent" turns red
<div class="change-parent">
descendant: "change-parent"
</div>
</div>
<div class="parent">
"parent" stays green
<div class="nope">
descendant: "nope"
</div>
</div>
</div>
Target <b>"<span style="color:darkgreen">parent</span>"</b> to turn <span style="color:red">red</span>.<br>
<b>Only</b> if it <b>has</b> a descendant of "change-parent".<br>
<br>
(reverse cascade, look ahead, parent un-descendant)
</html>
Справочные документы jQuery : элемент
$ () или jQuery () : DOM.
, find : Получить потомков каждого элемента в текущем наборе соответствующих элементов, отфильтрованных селектором, объектом jQuery или элементом.
, родители : Получить непосредственно предшествующий брат каждого элемента в наборе соответствующих элементов. Если предоставляется селектор, он извлекает предыдущего родного брата, только если он соответствует этому селектору (фильтрует результаты, чтобы включить только перечисленные элементы / селекторы).
, css : установить одно или несколько свойств CSS для набора соответствующих элементов.
previousElementSibling
).
previousElementSibling()
для тех, кто более знаком с нативными функциями JS DOM, может быть предложен другой путь, отличный от CSS.
+
(несуществующий) селектор, который специально запрашивал OP. Считайте этот ответ JS "взломать". Это здесь, чтобы сэкономить время, которое я потратил, чтобы найти решение.
Там нет «предыдущий» селектор родственный , к сожалению, но вы можете , возможно , , до сих пор получить тот же эффект , с помощью определения местоположения (например , флоат право). Это зависит от того, что вы пытаетесь сделать.
В моем случае я хотел использовать 5-звездочную систему рейтинга CSS. Мне нужно покрасить (или поменять иконку) предыдущие звезды. Плавая каждый элемент вправо, я, по сути, получаю тот же эффект (таким образом, 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)
+
или ~
селекторы поражают меня как самая чистая работа вокруг.
В зависимости от вашей конкретной цели, есть способ достичь полезности родительского селектора без его использования (даже если бы он существовал) ...
Скажем, у нас есть:
<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.
Мне нужно решение, чтобы выбрать предыдущий родной брат tr. Я придумал это решение, используя компоненты React и Styled. Это не мое точное решение (это по памяти, часы спустя). Я знаю, что есть ошибка в функции setHighlighterRow.
OnMouseOver для строки установит индекс строки в состояние и повторно отобразит предыдущую строку с новым цветом фона
class ReactClass extends Component {
constructor() {
this.state = {
highlightRowIndex: null
}
}
setHighlightedRow = (index) => {
const highlightRowIndex = index === null ? null : index - 1;
this.setState({highlightRowIndex});
}
render() {
return (
<Table>
<Tbody>
{arr.map((row, index) => {
const isHighlighted = index === this.state.highlightRowIndex
return {
<Trow
isHighlighted={isHighlighted}
onMouseOver={() => this.setHighlightedRow(index)}
onMouseOut={() => this.setHighlightedRow(null)}
>
...
</Trow>
}
})}
</Tbody>
</Table>
)
}
}
const Trow = styled.tr`
& td {
background-color: ${p => p.isHighlighted ? 'red' : 'white'};
}
&:hover {
background-color: red;
}
`;
Нет и есть .
Если вы должны поместить метку перед входом, вместо этого поместите метку после ввода, сохраните и метку, и ввод внутри элемента div, и стилируйте элемент div следующим образом:
.input-box {
display: flex;
flex-direction: column-reverse;
}
<div class="input-box">
<input
id="email"
class="form-item"
/>
<label for="email" class="form-item-header">
E-Mail*
</label>
</div>
Теперь вы можете применить стандартные опции стилей для следующего брата, доступные в css, и вы увидите, что вы используете предыдущий стилевый стиль.
У меня была похожая проблема, и я обнаружил, что все проблемы такого рода можно решить следующим образом:
и таким образом вы сможете стилизовать ваши текущие, предыдущие элементы (все элементы, переопределенные текущими и последующими элементами) и ваши следующие элементы.
пример:
/* 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>
Надеюсь, это кому-нибудь поможет.