Соседние CSS селекторы, универсальный селектор и их применение. CSS - Селекторы отношений

28.05.2019

Селектор соседнего элемента выбирает элемент, расположенный в коде документа непосредственно за другим заданным элементом. Давайте для примера возьмём кусок html-кода.

Абзац и в нём жирный элемент, и вот наклонный элемент.

Тут три тега:

, и . Теги и вложены в контейнер

Они являются дочерними по отношению к нему. Но по отношению друг к другу они являются соседними.

Синтаксис соседнего селектора: селектор предыдущего элемента, знак "+" и за ним селектор выбираемого элемента. Давайте работу соседнего селектора:

Соседний селектор в CSS. b+i { color: red; }

Абзац и в нём жирный элемент, и вот наклонный элемент.

Тут жирный и подчёркнутый элементы, ещё наклонный.

В примере видно, что селектор соседнего элемента сработал в первом абзеце. Тут теги и идут друг за другом. А во втором абзаце между ними использован тег , теперь тут две другие соседние пары тегов: + и + .

Ошибкой в данном случае будет считать тег соседним по отношению к тегу

Тут тег является дочерним по отношению к тегу

А он, в свою очередь, является родителем .

Пример ниже не сработает:

Соседний селектор в CSS. p+b { color: red; } // В коде нет таких соседей.

Абзац и в нём жирный элемент, и вот наклонный элемент.

Тут жирный и подчёркнутый элементы, ещё наклонный.

Более реальный пример

Давайте рассмотрим работу соседнего селектора на более реальном примере. В больших статьях, содержащих несколько разделов обозначенных тегами , желательно увеличить верхний отступ (свойство margin-top ). Отступ в 30px будет придавать тексту читабельности. Но вот в случае, если тег идёт сразу после , а это может быть в начале статьи, вержний отступ над тегом будет лишним. Решить такую задачу можно при помощи селектора смежного элемента.

Вот html-код с примером работы селектора соседнего элемента.

Соседний селектор в CSS h1 { margin-bottom: 0px; } h2 { margin-top: 50px; } h1+h2 { margin-top: 0px; } Привет! Заголовок h2 Заголовок h2

Текст абзаца в про невероятные приключения.

Заголовок h2

Текст абзаца в про невероятные приключения.

Заголовок h2

Текст абзаца в про невероятные приключения.

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

Также стоит отметить что для уменьшения отступов удобно использовать отрицательные значения.

Соседний селектор в CSS h2 { margin-top: 50px; } h1+h2 { margin-top: -20px; } h2+p { margin-top: -1em; } Привет! Заголовок h2

Текст абзаца в про невероятные приключения.

Заголовок h2

Текст абзаца в про невероятные приключения.

Заголовок h2

Текст абзаца в про невероятные приключения.

Заголовок h2

Текст абзаца в про невероятные приключения.

Теперь пример того, как при помощи соседнего селектора выделить все элементы списка, кроме первого.

Соседний селектор в CSS li+li { color: red; }

  • Пункт списка №1.
  • Пункт списка №2.
  • Пункт списка №3.
  • Пункт списка №4.

Вот что получится в результате работы этого примера:

Рисунок 1. Работа примера №5.

Сохраните эту страницу для тестирования приведенных ниже примеров.

Выбранный набор элементов можно использовать в качестве отправной точки для перемещения к другим узлам DOM-дерева. При этом, по сути, один набор элементов используется для создания другого набора. Описанию и демонстрации применения методов jQuery, предназначенных для обхода структуры DOM, посвящены следующие разделы. В них рассматриваются различные типы отношений, которые могут существовать между содержащимися в документе элементами.

Каждый из описанных в последующих разделах методов возвращает объект jQuery. Этот объект может как содержать подходящие объекты, если таковые имеются, так и быть пустым в случае их отсутствия (свойство length таких объектов возвращает нулевое значение).

Перемещение вниз по дереву DOM

Процесс перемещения вниз по иерархической структуре DOM связан с выбором дочерних элементов (непосредственных потомков), а также всех остальных элементов, являющихся потомками элементов, содержащихся в объекте jQuery. Соответствующие методы jQuery и их краткое описание приведены в таблице ниже:

Методы, используемые для перемещения вниз по иерархической структуре DOM Метод Описание
children() Выбирает дочерние элементы всех элементов, содержащихся в объекте jQuery
children(селектор) Выбирает все элементы, которые соответствуют указанному селектору и при этом являются непосредственными потомками элементов, содержащихся в объекте jQuery
contents() Возвращает дочерние элементы и текстовое содержимое всех элементов, содержащихся в объекте jQuery
find() Выбирает потомки элементов, содержащихся в объекте jQuery
find(селектор) Выбирает элементы, которые соответствуют указанному селектору и при этом являются потомками элементов, содержащихся в объекте jQuery
find(jQuery), find(HTMLElement),
find(HTMLElement)
Выбирает пересечение множества непосредственных потомков элементов, содержащихся в объекте jQuery, и множества элементов, содержащихся в объекте аргумента

Метод children() выбирает лишь те элементы, которые являются непосредственными потомками (дочерними элементами) элементов, содержащихся в объекте jQuery, и может принимать селектор в качестве необязательного аргумента, обеспечивающего дополнительную фильтрацию элементов. Метод find() предназначен для выбора всех потомков, а не только дочерних элементов. Метод contents() наряду с дочерними элементами возвращает также текстовое содержимое.

Пример использования методов children() и find() приведен ниже:

$(function() { var childCount = $("div.drow").children().each(function(index, elem) { console.log("Дочерний элемент: " + elem.tagName + " " + elem.className); }).length; console.log("Всего имеется " + childCount + " дочерних элементов"); var descCount = $("div.drow").find("img").each(function(index, elem) { console.log("Потомок: " + elem.tagName + " " + elem.src); }).length; console.log("Всего имеется " + descCount + " элементов-потомков img"); });

В этом примере метод children() используется без селектора, тогда как метод find() используется с одним селектором. Подробная информация о выбранных элементах выводится на консоль вместе с указанием их количества:

Среди приятных особенностей методов children() и find() можно отметить отсутствие дублирования элементов в выбранном наборе. Это подтверждает пример, приведенный ниже:

$(function() { $("div.drow").add("div.dcell").find("img").each(function(index, elem) { console.log("Потомок: " + elem.tagName + " " + elem.src); }); });

В этом примере мы начинаем с того, что создаем объект jQuery, который содержит все элементы div с классом drow и все элементы div с классом dcell. Ключевым моментом здесь является то, что все элементы, принадлежащие классу dcell, одновременно являются элементами класса drow. Это означает, что мы имеем дело с двумя перекрывающимися множествами элементов-потомков, и в случае использования метода find() с селектором img это могло бы привести к дублированию элементов в результирующем наборе, поскольку элементы img являются потомками элементов div обоих классов. Однако jQuery выручает нас и самостоятельно заботится о том, чтобы среди возвращаемых элементов дублирование отсутствовало, что подтверждается результатами, выводимыми на консоль:

Перемещение вверх по дереву DOM

Перемещению вверх по DOM-дереву соответствует поиск родителей и предков элементов, содержащихся в объекте jQuery. Методы, используемые для таких перемещений, приведены в таблице ниже:

Методы, используемые для перемещения вверх по иерархической структуре DOM Описание Метод
closest(селектор), closest(селектор, контекст) Выбор ближайшего предка, соответствующего указанному селектору, для каждого элемента, содержащегося в объекте jQuery
closest(jQuery), closest(HTMLElement) Выбор ближайшего предка для каждого элемента в объекте jQuery, совпадающего с одним из элементов, содержащихся в объекте аргумента
offsetParent() Нахождение ближайшего предка, значением CSS-свойства position которого является fixed, absolute или relative
parent(), parent(селектор) Выбор непосредственных предков для каждого элемента в объекте jQuery с возможностью их фильтрации с помощью селектора
parents(), parents(селектор) Выбор предков для каждого элемента в объекте jQuery с возможностью их фильтрации с помощью селектора
parentsUntil(селектор), parentsUntil(селектор, селектор) Выбор предков для каждого элемента в объекте jQuery до тех пор, пока не встретится элемент, соответствующий селектору. Результаты могут фильтроваться посредством второго селектора
parentsUntil(HTMLElement), parentsUntil(HTMLElement, селектор), parentsUntil(HTMLElement), parentsUntil(HTMLElement, селектор) Выбирает предков для каждого элемента в объекте jQuery до тех пор, пока не встретится один из указанных элементов. Результаты могут фильтроваться посредством второго селектора
Выбор родительских элементов

Метод parent() позволяет выбрать родительский элемент для каждого из элементов, содержащихся в объекте jQuery. Если методу предоставляется селектор, то в результирующий набор будут включаться только те родительские элементы, которые соответствуют селектору. Пример использования метода parent() приведен ниже:

$(function() { $("div.dcell").parent().each(function(index, elem) { console.log("Элемент: " + elem.tagName + " " + elem.id); }); $("div.dcell").parent("#row1").each(function(index, elem) { console.log("Отфильтрованный элемент: " + elem.tagName + " " + elem.id); }); });

В этом сценарии сначала выбираются все элементы div, принадлежащие классу dcell, а затем вызывается метод parent(), выбирающий все родительские элементы. Здесь также демонстрируется использование метода parent() с селектором. Подробная информация о каждом выбранном родительском элементе выводится на консоль с использованием метода each:

Выбор предков

Метод parents() (обратите внимание на последнюю букву s в его названии) обеспечивает возможность выбора всех, а не только непосредственных предков (родителей) элементов, содержащихся в объекте jQuery. Как и в предыдущем случае, метод может принимать в качестве аргумента селектор для фильтрации результатов.

Пример использования метода parents() приведен ниже:

$(function() { $("img, img").parents().each(function(index, elem) { console.log("Элемент: " + elem.tagName + " " + elem.className + " " + elem.id); }); });

В этом примере метод parents() используется для выбора предков двух предварительно выбранных элементов img. Информация о каждом предке выводится на консоль:

Метод parentsUntil() является еще одной разновидностью методов, предназначенных для выбора предков элементов. Для каждого из элементов, содержащихся в объекте jQuery, метод parentsUntil() осуществляет перемещение вверх по иерархической структуре DOM, выбирая элементы-предки до тех пор, пока не встретится элемент, соответствующий селектору. Пример использования этого метода приведен ниже:

$(function() { $("img, img").parentsUntil("form") .each(function(index, elem) { console.log("Элемент: " + elem.tagName + " " + elem.className + " " + elem.id); }); });

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

Обратите внимание, что элементы, соответствующие селектору, исключаются из состава выбираемых предков. В данном случае это означает исключение элемента form. Набор предков можно подвергнуть дополнительной фильтрации, предоставив методу paraentsUntil() селектор в качестве второго аргумента, как показано в примере ниже:

$(function() { $("img, img").parentsUntil("form", ":not(.dcell)" ) .each(function(index, elem) { console.log("Элемент: " + elem.tagName + " " + elem.className + " " + elem.id); }); });

В этом примере добавлен селектор, который фильтрует элементы, принадлежащие классу dcell. На консоль выводится следующий результат:

Выбор первого подходящего предка

Метод closest() позволяет выбирать первого из предков, соответствующих селектору, для каждого элемента в объекте jQuery. Пример использования этого метода приведен ниже:

$(function() { $("img").closest(".drow").each(function(index, elem) { console.log("Элемент: " + elem.tagName + " " + elem.className + " " + elem.id); }); var contextElem = document.getElementById("row1"); $("img").closest(".drow", contextElem).each(function(index, elem) { console.log("Контекстный элемент: " + elem.tagName + " " + elem.className + " " + elem.id); }); });

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

Область выбора предков можно сузить, передав методу closest() объект HTMLElement() в качестве второго аргумента. Те предки, которые не являются контекстным объектом или его потомками, не включаются в выбранный набор. На консоль выводится следующий результат:

Методу closest() также можно передать в качестве аргумента объект jQuery, объект HTMLElement или массив объектов HTMLElement. В этом случае метод closest() будет продолжать процесс выбора предков для каждого из элементов, содержащихся в исходном объекте jQuery, до тех пор пока не встретится объект, переданный в качестве аргумента.

Метод offsetParent() представляет собой вариацию на тему метода closest() и предназначен для нахождения первого потомка, значение CSS-свойства position которого равно relative, absolute или fixed. Такие элементы называются позиционированными предками, и их поиск может оказаться полезным при работе с анимацией. Пример использования этого метода приведен ниже:

#row1 {position: fixed; top: 75px; left: 50px} #row2 {position: fixed; top: 150px; left: 50px} $(function() { $("img").offsetParent().css("background-color", "lightgrey"); });

В этой версии документа сначала с помощью CSS устанавливается значение свойства position элементов с атрибутом id равным row1 и row2. Далее в документе выбирается один из элементов img и с помощью метода offsetParent() находится ближайший позиционированный потомок выбранного элемента. После этого с помощью метода css() для свойства background-color выбранного элемента устанавливается значение lightgrey. Вид результирующей страницы в окне браузера представлен на рисунке:

Перемещение по дереву DOM в пределах одного иерархического уровня

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

Методы, используемые для перемещения между узлами DOM-дерева в пределах одного иерархического уровня Метод Описание
next(), next(селектор) Выбирает сестринские элементы, непосредственно следующие за каждым из элементов, содержащихся в объекте jQuery. Имеется дополнительная возможность фильтрации результатов с использованием селектора
nextAll(), nextAll(селектор) Выбирает все последующие сестринские элементы для каждого из элементов, содержащихся в объекте jQuery. Имеется дополнительная возможность фильтрации результатов с использованием селектора
nextUntil(селектор), nextUntil(селектор, селектор), nextUntil(jQuery), nextUntil(jQuery, селектор), nextUntil(HTMLElement), nextUntil(HTMLElement, селектор) Выбирает для каждого элемента последующие сестринские элементы вплоть до элемента (но не включая его), соответствующего селектору или содержащегося в объекте jQuery или массиве HTMLElement. Имеется дополнительная возможность фильтрации результатов с использованием селектора
prev(), prev(селектор) Выбирает сестринские элементы, непосредственно предшествующие каждому из элементов, содержащихся в объекте jQuery. Имеется дополнительная возможность фильтрации результатов с использованием селектора
prevAll(), prevAll(селектор) Выбирает все предшествующие сестринские элементы для каждого из элементов, содержащихся в объекте jQuery. Имеется дополнительная возможность фильтрации результатов с использованием селектора, передаваемого методу в качестве второго аргумента
prevUntil(селектор), prevUntil(селектор, селектор), prevUntil(jQuery), prevUntil(jQuery, селектор), prevUntil(HTMLElement), prevUntil(HTMLElement, селектор) Выбирает для каждого элемента предшествующие сестринские элементы вплоть до элемента (но не включая его), соответствующего селектору или содержащегося в объекте jQuery или массиве HTMLElement. Имеется дополнительная возможность фильтрации результатов с использованием селектора, передаваемого методу в качестве второго аргумента
siblings(), siblings(селектор) Выбирает все сестринские элементы для каждого из элементов, содержащихся в объекте jQuery. Имеется дополнительная возможность фильтрации результатов с использованием селектора
Выбор всех сестринских элементов

Метод siblings() обеспечивает возможность выбора всех сестринских элементов для всех элементов, содержащихся в объекте jQuery. Пример использования этого метода приведен ниже.

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

Виды отношений между элементами

Каждый элемент на веб-странице может быть связан с другим элементом с помощью одного из следующих отношений:

  • родительский элемент, прямой предок - элемент который содержит один или несколько вложенных в него элементов. По отношению к этим вложенным в него элементам он является для них родителем;
  • дочерний элемент, прямой потомок, ребёнок, дитя - элемент, который вложен в родительский элемент и по отношению к нему является дочерним элементом, т.е. его ребёнком;
  • соседний элемент, сиблинг (брат или сестра) – элементы, у которых один общий родитель. Такие элементы по отношению друг к другу являются сиблингами (соседями).

Рассмотрим следующий пример:

Данный код можно представить в виде следующей схемы:

В вышеприведённом примере выберем элемент p и рассмотрим, как он связан с другими элементами в коде:

  • Родительский элемент – div ;
  • Соседний элемент – h1 ;
  • Прямые потомки, дети – элементы strong , em .
Элемент1 Элемент2

В этом селекторе элемент1 и элемент2 связаны между собой отношением "предок потомок". Т.е. он используется для выбора элементов2 , которые расположены внутри элемента1 в HTML документе. Другими словами, он выбирает все элементы2 , которые являются потомками элемента1 .

Например выбрать и установит стиль каждому элементу p , который является потомком элемента div:

Div p { color:red; }

Текст 1

Текст 2

Текст 4

текст 5

Элемент1 > Элемент2

В этом селекторе элемент1 и элемент2 связаны между собой отношением "родитель > ребёнок". Т.е. он используется для выбора элементов2 , которые являются детьми элемента1 . Другими словами, он выбирает все элементы2 , которые имеют в качестве непосредственного родителя элемент1 .

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

Div > p { color:red; }

Текст 1

Текст 2

текст 5

Элемент1 + Элемент2

Селектор Элемент1 + Элемент2 предназначен для выбора элементов2 , которые расположены сразу же после элемента1 , и являются они по отношению друг к другу соседями. Другими словами, данный селектор используется для выбора элемента2 , который расположен сразу же после элемента1 , и при этом они должны иметь одного и того же родителя в HTML документе.

Например выбрать и установит стиль каждому элементу p , который расположен сразу же после элемента div . Причём выбрать нужно только те элементы p , которые находятся на том же уровне вложенности, что и элементы div , т.е. они должны являться по отношению друг к другу соседями:

Div + p { color:red; }

Текст 1

Текст 2

Текст 3

Элемент1 ~ Элемент2

Селектор Элемент1 ~ Элемент2 предназначен для выбора элементов2 , которые расположены после элемента1 , и являются они по отношению друг к другу соседями. Другими словами, данный селектор используется для выбора элементов2 , которые расположены после элемента1 , и при этом они должны иметь одного и того же родителя в HTML документе.

Например выбрать и установит стиль каждому элементу p , который расположен после элемента div . Причём выбрать нужно только те элементы p , которые находятся на том же уровне вложенности, что и элементы div , т.е. они должны являться по отношению друг к другу соседями:

Div ~ p { color:red; }

Текст 1

Текст 2

Текст 3-1

12 июля 2011 в 13:14 Семантика для CSS селекторов и комбинаторов
  • CSS
  • Перевод

Синтаксис CSS несложен, и для понимания его совсем не нужно иметь степень доктора в области IT. Однако, это один из немногих популярных языков, который не является логичным в самом прямом смысле этого слова. В отличие от других языков веб-программирования, таких как JavaScript и PHP, в CSS проблемы не решаются с помощью обычной логики. Алгоритмы типа «если X, то сделать Y, в противном случае сделать Z» или «выбрать все Y, затем сделать с ними X» не могут быть осуществлены в таком языке, как CSS. Проще говоря, это язык, созданный для оформления, язык для дизайнеров, а не девелоперов. Некоторые из опытных программистов, с которыми я работал, именно по этой причине тратили много усилий на то, чтобы освоить CSS.

Обучение CSS начинается с классов и ID, а также с использования. и # для непосредственного обозначения элементов. Этого достаточно чтобы построить полнофункциональный веб-сайт, но это не достаточно гибкое решение в случае полной смены дизайна. Давайте взглянем на альтернативный подход к управлению такими труднодоступными элементами.

Соседний родственный комбинатор Начнём с селектора, который удобен в сложных ситуациях, - с соседнего родственного комбинатора. Соседний родственный комбинатор обозначается соединением двух элементов с помощью знака +:

H1 + p
Это выделяет следующий p-элемент, расположенный сразу после h1-элемента в DOM. Типографическая теория предполагает, что мы должны использовать отступы в параграфах текста, но только если они следуют за другим параграфом. На практике это может быть использовано, чтобы сделать отступы во всех параграфах, кроме первого:
p + p { text-indent: 1em; }
Это гораздо удобней, чем выделять первый параграф с помощью class=«first». Три строки, никаких классов и полная поддержка браузеров. Если вы располагаете тэги img, относящиеся к наполнению сайта, внутри тэгов p (как, собственно, и следует делать), можно просто отодвинуть их левые поля обратно с помощью негативного значения -1em:
p + p img { margin-left: -1em; }
Довольно просто, правда? А что, если нам захочется выделить первую строку всех параграфов, которые стоят сразу после заголовков, не изменяя всех остальных параграфов? Опять-таки мы можем использовать класс представления. Простой селектор, сделанный из соседнего составного комбинатора, и псевдо-элемент справятся с задачей:
h1 + p::first-line { font-variant: small-caps; }
Примечание: псевдо-элемент:first-line принят в CSS 2.1, в CSS 3 используется запись::, с целью установить различие между псевдо-классами и псевдо-элементами.

Наследственный комбинатор Обычный протокол разметки – это помещение разделов в как-либо названном элементе в #page или #wrap: