Все предыдущие элементы css

Смежные селекторы предшествующих элементов CSS и способы их имитации

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

Но у нас нет способа выбрать те, которые расположены раньше. Либо родительские селекторы, либо предыдущие селекторные одного уровня — такого просто нет.

Я знаю, что вы этого хотите, вы знаете, что я этого хочу, но суровая правда в том, что они не существуют (и, вероятно, никогда не будут). Есть миллион сообщений «Почему?». Есть даже предложения о том, как их реализовать. Но мы застреваем на однонаправленной обработке правил CSS — это делается, скорее всего, чтобы защитить нас от «плохого опыта», связанного с неправильным течением потока обработки или даже бесконечными циклами.

К счастью, как и в случае большинства ограничений CSS, мы можем имитировать это. Первое, что нужно учитывать — это то, для чего нам нужны предыдущие одноуровневые элементы. Существуют два случая:

Нам нужно выбрать все элементы одного уровня с элементом, а комбинатор ~ выбирает только те, которые расположены после.

Онлайн курс по JavaScript

Научитесь создавать приложения со сложными интерфейсами

Это основной язык для современной веб-разработки — почти 100% сайтов работает на JavaScript. Освойте его с нуля всего за 4 месяца, и вы сможете зарабатывать от 70 000 рублей.

Нам нужно выбрать только элементы одного уровня, которые расположены раньше

1. Выбор всех элементов одного уровня

Иногда нам нужно выбрать как предыдущие, так и последующие элементы одного уровня. Для этого мы можем выбрать родительский элемент и использовать некоторые хитрости.

Например, чтобы выбрать все span в следующей структуре, когда мы наводим указатель мыши на любой из них, мы могли бы просто использовать селектор дочерних элементов для родителя. Нам нужно переключить pointer-events с родителя на дочерние элементы. Таким образом, любое действие, которое мы хотим осуществить, будет срабатывать только при вводе для дочернего элемента, а не самого родителя.

/*или что угодно, что вы хотите сделать с со всеми элементами одного уровня, когда вы наводите мышь на один из них */

Если вам нужно выбрать все элементы одного уровня, кроме того, на который был наведен курсор, вы можете совместить предыдущий метод с селектором :not, чтобы исключить его. Стандартным примером для этого является меню:

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

Кроме того, вы можете использовать селекторы type и nth, чтобы дополнительно отфильтровать нужные элементы. Задав определенные стили, мы можем получить следующее:

Обратите внимание: если вы хотите использовать подход pointer-events:none, помните, что это может нарушить порядок стекирования (возможно, вы выберете элементы, которые «ниже» в порядке стекирования). Это также не будет работать в IE10 и ниже, если только вам не нужны указатели события для чего-то другого. Поэтому будьте очень осторожны при использовании.

2. Выбор предыдущих элементов

Для этого варианта использования мы можем изменить в обратном направлении порядок сортировки в HTML, а затем отсортировать элементы обратно в CSS и использовать селекторы ~ и +. Таким образом, мы будем выбирать следующие элементы, но самом деле это будут предыдущие.

Существует несколько способов сделать это. Самый простой и, вероятно, самый старый — это изменение направления написания нашего контейнера:

Если ваши элементы должны отображать фактический текст, вы всегда можете отменить это обратно:

Но во многих случаях это может быть неудобно. К счастью, современный инструментарий CSS позволяет сделать это намного проще и безопаснее. Мы можем просто использовать для контейнера Flexbox и изменить порядок с помощью flex-direction: row-reverse:

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

Использование «предыдущих элементов одного уровня» для создания системы звезд-рейтингов на чистом CSS

Семантически, рейтинговую систему можно рассматривать как простой список радио-кнопок с соответствующими метками. Это позволит нам использовать проверенный псевдо-селектор :checked для изменения элементов одного уровня. Итак, давайте начнем с этого:

Как мы рассматривали ранее, элементы находятся в обратном порядке тому, который позволяет нам применить селектор «предыдущий элемент одного уровня». Обратите внимание, что мы используем для представления пустых звезд символ юникода “white star” (U + 2606).

Давайте отобразим их рядом друг с другом, в правильном (обратном) порядке:

Теперь скроем сами переключатели, никому не нужно их видеть:

И применим некоторые стили к символам звездочек:

Единственная действительно важная строка — это position: relative. Это позволит нам по абсолютно позиционировать псевдо-элемент с закрашенной звездой (U + 2605), который будет изначально скрыт.

Когда мы наводим указатель на звездочку, псевдо-элемент закрашенной звездный должен стать видимым для нее и всех предыдущих одноуровневых элементов.

То же делается для выбранного рейтинга, через сопоставление всех меток, которые находятся перед выбранной радио-кнопкой:

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

И последнее, но не менее важное: нам нужно «запомнить» текущий рейтинг, на случай, если пользователь захочет его изменить. Например, если он выбрал пять звезд и по какой-либо причине хочет изменить их на четыре, мы должны отображать звезды с 1 по 4, как заполненные, а пятую — полупрозрачной при наведении указателя на четвертую.

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

Вот для чего нам нужно pacity:1 !important в начальном объявлении наведения. В противном случае это последнее правило переопределило бы другие в соответствии со специфичностью и применило полупрозрачную заливку ко всему.

И там у нас есть это, кроссбраузерная, полностью функциональная система звезд-рейтингов с использованием только селекторов «предыдущие элементы одного уровня».

Как вы можете видеть, просто потому, что «это невозможно» не означает, что вы не должны пытаться. Программирование — это раздвижение границ. Поэтому каждый раз, когда вы упираетесь в стену, просто попробуйте надавить немного сильнее. Или лучшей аналогией, я думаю, будет — найдите свой обходной путь? … в любом случае, вы понимаете, что я имею в виду. Продолжайте взламывать!

Замечания относительно доступности

Предыдущий фрагмент — это упрощение для лучшего понимания. Это не то, что я бы рекомендовал использовать в реальной среде из-за многих ограничений доступности.

Чтобы сделать сниппет немного более доступным, первым делом нужно было бы скрыть радио-кнопки с помощью другого способа, а не display: none, чтобы сделать их фокусируемыми. Мы также должны добавить кольцо фокусировки на весь фрагмент звёзд, когда любой элемент внутри выделен фокусом, это делается через псевдо-селектор :focus-in.

Метки «звезды» не имеют смысла для экранных дикторов, поэтому наилучшим подходом будет наличие внутри метки span с текстом «n Stars», который будет скрыт от видящих пользователей.

Кроме того, подход с обратным порядком в HTML-источнике + display:row-reverse делает клавиатуру неудобной для выставления рейтингов. Доступность Flexbox и клавиатуры — довольно сложная тема, но ближе всего к решению подход, когда для каждого элемента добавляется тег aria-flowtotag, что, по крайней мере, устраняет проблему для некоторых экранных дикторов + комбинации браузеров.

Более доступный сниппет (использующий альтернативную технику изменения следующих элементов одного уровня, которые выглядят пустыми) вы можете найти у Патрика Коула, как описано в комментариях ниже.

Автор: Facundo Corradini

Онлайн курс по JavaScript

Научитесь создавать приложения со сложными интерфейсами

Это основной язык для современной веб-разработки — почти 100% сайтов работает на JavaScript. Освойте его с нуля всего за 4 месяца, и вы сможете зарабатывать от 70 000 рублей.

Редакция: Команда webformyself.

Источник

CSS Select previous element

There could be cases when you want to apply a certain styling for the previous element in CSS. But can that be achieved? I’ll try to break it down in this article.

The previous element selector or the previous sibling selector is not available in the CSS (see list of all available selectors). However a possible workaround exists, and you can imitate such behavior using the flex property.

The most common example could be a label with an input . On input :hover or :focus state, we would like to highlight the label as well, which in this case is comes before the input .

 class="field">  class="label" for="email">E-mail:  class="input" type="email" id="email">  

To implement a workaround we’ll need to change HTML a bit. We’ll switch input and label places. That way we can target the label element via the sibling selector ( + ).

 class="field">  class="input" type="email" id="email">  class="label" for="email">E-mail:  

As for styling, we can set the visual order of label and input with flex-direction: row-reverse rule.

.field  display: flex; flex-direction: row-reverse; justify-content: flex-end; /* to pull content to the left */ > .input:focus + .label  color: #5a6cce; > 

In case there are more than two elements in the container you can set the order property to each one to visually allocate them one after another. In this case, don’t forget to remove the flex-direction: reverse on the container element.

.label  order: 1; > .input  order: 2 > 

The last tip, if you’re operating with inputs and :focus state, you can utilize the :focus-within pseudo-class to select the desired element. In this case, you can leave the HTML as is:

 class="field">  class="label" for="email">E-mail:  class="input" type="email" id="email">  
.field:focus-within .label  color: #5a6cce; > 

However, if you’re going beyond just :hover and/or :focus states the flex-direction and order properties are your main way to go to select the previous sibling element.

This work is licensed under a CC BY 4.0 License.
The code in this work is licensed under an MIT License.

Источник

Selecting previous siblings with CSS :has()

One of the more maddening limitations of CSS was for long its inability to select elements based on their children or preceding siblings. This made it impossible to construct CSS selectors that could target previous siblings of an element, but the has:() pseudo-class (along with :not() , :where() , and :is() from Selectors Level 4) has thrown out the old limitations and opened up a new world of possibilities when working with selectors.

As of this writing, :has() is supported by 84.68% of all major browsers (including Chrome and Safari), with Firefox being the notable exception. Experimental support for Firefox launched in July 2022 and can be enabled through the flag layout.css.has-selector.enabled —you can track the progress through this Bugzilla issue. Until that ships, you can use the :has() pseudo-class if you’re not targeting or supporting Firefox, or if you use a polyfill.

Selecting the previous sibling

Imagine that we have a series of elements, like this:

 class="box">
class="box">
class="box">
class="circle">
class="box">

…and we want to select and style the element that comes before the circle. The adjacent sibling combinator ( + ) can select an element that immediately follows another element, and we can combine it with :has() that to select only the .box that’s immediately followed by a .circle (or from the circle’s perspective, its previous sibling):

.box:has(+ .circle)  width: 40px; height: 40px; > 

You can think of this selector as first 1) selecting all boxes, and then 2) filtering the elements to only those that match the pattern “box + circle”, which will only return the circle’s previous sibling.

Selecting the nth previous sibling

It’s possible to use the adjacent sibling combinator to select any specific element that preceds another. We can select the 2nd previous sibling by using two adjacent sibling combinators:

.box:has(+ * + .circle)  width: 40px; height: 40px; > 

If you want to, you can equally scope the selector to a class (rather than the catch-all * ). In this instance .box siblings:

.box:has(+ .box + .circle)  width: 40px; height: 40px; > 

This selector can be difficult to grok and parse. It might help to think of it as selecting all boxes ( .box ), and then filtering those elements so that the remaining .box is the one that matches the pattern “self + box + circle”, which will only be the 2nd previous sibling.

If you want to select the 3rd previous sibling, you can use three adjacent sibling combinators…

.box:has(+ * + * + .circle)  width: 40px; height: 40px; > 

Источник

Читайте также:  Caused by java lang illegalstateexception entitymanagerfactory is closed
Оцените статью