Css выбрать первый дочерний элемент. Дочерние селекторы. Добавление и удаление дочерних элементов

Css выбрать первый дочерний элемент. Дочерние селекторы. Добавление и удаление дочерних элементов

  • Выполняемая задача — выбор дочерних элементов.
  • Обозначение — цепочка: простой селектор родителя, комбинатор «>», простой селектор дочернего элемента.
  • Пример использования:

Зададим отступ слева для списка, непосредственно вложенного в элемент с классом content (на списки второго уровня вложенности эти правила не подействуют):

Content > ul { margin-left: 20px; }

Подробнее про селектор дочернего элемента

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

Div > span { color: #555; /* серый цвет */ }

…и такой код:

Этот текст будет черного цвета. А этот серого, ведь этот span — дочерний элемент для div.

Тут опять черный текст. И этот текст тоже черный, так как этот span не дочерний для div. Его непосредственный родитель — тег p.

Основная задача данного селектора следует из его названия и заключается в обращении к дочернему элементу. Выводится с помощью элементарного знака «>», который связывает дочерний элемент с элементом родителя. Также стоит отметить, что в обращении используется простые селекторы. В качестве примера рассмотрим следующую кодировку:

Element > ul { padding- top: 20px; }

Данная кодировка означает, что к списку, который вложен в element, будет применен внутренний отступ в 20 пикселей от верхнего края. Наличие в этой записи значка «>» показывает, что правило применится только к спискам первого уровня вложенности.

Подробный анализ работы селектора дочернего элемента

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

Более наглядно оценить работу оператора дочернего селектора поможет следующий пример:

Div > р { color: #ff0000; /* красный */ }

< div> Данная строка будет иметь по умолчанию черный текст. < span> Эта строка перекраситься в красный в следствие того, что р является дочерним тегом для дива. < p> Опять видим черные буквы. < span> Здесь мы видим тоже черные символы, так как для этого спана родителем является тег р.

Данный пример подтверждает работу оператора дочернего селектора согласно степени вложенности.

Ограничение для применения оператора дочернего селектора

Стоит отметить, что данная операция поддерживается всеми браузерами кроме легендарного Internet Explorer 6. Думаю, мало кто использует данный браузер, однако же если таковые уникумы имеются, то для них существует выход из ситуации, который будет описан в отдельной статье.

Зачем применяется

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

Также селектор элемента дочернего используется для присвоения уникальных стилей элементам, родители которых уже известны за ранее. Другими словами:

Main > header { /* оформление относится только к главному хедеру */ }

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

Подводя итоги

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

Дочерние элементы - это элементы, которые располагаются непосредственно внутри родительского элемента. Обратите внимание на слова: непосредственно внутри.

Давайте рассмотрим пример простого html-кода:

Дочерние элементы.

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

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

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

Теперь давайте к этому html-коду добавим CSS-стили с использованием дочерних селекторов.

Синтаксис дочерних селекторов:

Селектор 1 > Селектор 2 { Свойство: значение; }

Вот обновлённый код:

Дочерние элементы.

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

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

Итак, вспомним: дочерний элемент - это элемент вложенный непосредственно в родительский. То есть, дочерний элемент - это потомок первого уровня. Давайте обратим внимание на тег , в первом абзаце он вложен в тег

А во втором он вложен в тег , хотя также является потомком тега

Поэтому во втором абзаце CSS правило для дочернего селектора p>i { color : blue ; } не сработает - наклонный текст второго абзаца не будет отображён синим цветом.

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

Добраться к html-элементу второго абзаца можно используя CSS-правило: p>u>i { color : blue ; }.

Давайте при помощи такого правила зададим наклонному тексту второго абзаца жёлтый цвет.

Дочерние элементы.

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

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

Этот стиль сработает и наклонный текст во втором абзаце будет отображён жёлтым цветом.

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

Более сложный пример

У нас есть html-код:

Дочерние элементы.

По умолчанию он интерпритируется так:

Задача: при помощи CSS превратить этот список в горизонтальное меню.


Рисунок 3. Цель преобразований.

Вот решение этой задачи с использованием дочерних селекторов:

Дочерние элементы.

Для лучшего понимания этого примера читайте.

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

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

Подсчет дочерних узлов

Для демонстрации я буду использовать следующую разметку HTML, в течение статьи мы ее несколько раз изменим:

  • Example one
  • Example two
  • Example three
  • Example four
  • Example five
  • Example Six

Var myList = document.getElementById("myList"); console.log(myList.children.length); // 6 console.log(myList.childElementCount); // 6

Как видите, результаты одинаковые, хотя техники используются разные. В первом случае я использую свойство children . Это свойство только для чтения, оно возвращает коллекцию элементов HTML, находящихся внутри запрашиваемого элемента; для подсчета их количества я использую свойство length этой коллекции.

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

Я мог бы попытаться использовать childNodes.length (вместо children.length), но посмотрите на результат:

Var myList = document.getElementById("myList"); console.log(myList.childNodes.length); // 13

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

Проверка существования дочерних узлов

Для проверки наличия у элемента дочерних узлов я могу использовать метод hasChildNodes() . Метод возвращает логическое значение, сообщающие об их наличии или отсутствии:

Var myList = document.getElementById("myList"); console.log(myList.hasChildNodes()); // true

Я знаю, что в моем списке есть дочерние узлы, но я могу изменить HTML так, чтобы их не было; теперь разметка выглядит так:

И вот результат нового запуска hasChildNodes() :

Console.log(myList.hasChildNodes()); // true

Метод по прежнему возвращает true . Хотя список не содержит никаких элементов, в нем есть пробел, являющийся валидным типом узла. Данный метод учитывает все узлы, не только узлы-элементы. Чтобы hasChildNodes() вернул false нам надо еще раз изменить разметку:

И теперь в консоль выводится ожидаемый результат:

Console.log(myList.hasChildNodes()); // false

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

Добавление и удаление дочерних элементов

Есть техника, которые можно использовать для добавления и удаления элементов из DOM. Наиболее известная из них основана на сочетании методов createElement() и appendChild() .

Var myEl = document.createElement("div"); document.body.appendChild(myEl);

В данном случае я создаю

с помощью метода createElement() и затем добавляю его к body . Очень просто и вы наверняка использовали эту технику раньше.

Но вместо вставки специально создаваемого элемента, я также могу использовать appendChild() и просто переместить существующий элемент. Предположим, у нас следующая разметка:

  • Example one
  • Example two
  • Example three
  • Example four
  • Example five
  • Example Six

Example text

Я могу изменить место расположения списка с помощью следующего кода:

Var myList = document.getElementById("myList"), container = document.getElementById("c"); container.appendChild(myList);

Итоговый DOM будет выглядеть следующим образом:

Example text

  • Example one
  • Example two
  • Example three
  • Example four
  • Example five
  • Example Six

Обратите внимание, что весь список был удален со своего места (над параграфом) и затем вставлен после него перед закрывающим body . И хотя обычно метод appendChild() используется для добавления элементов созданных с помощью createElement() , он также может использоваться для перемещения существующих элементов.

Я также могу полностью удалить дочерний элемент из DOM с помощью removeChild() . Вот как удаляется наш список из предыдущего примера:

Var myList = document.getElementById("myList"), container = document.getElementById("c"); container.removeChild(myList);

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

Var myOldChild = document.body.removeChild(myList); document.body.appendChild(myOldChild);

Таке существует метод ChildNode.remove() , относительно недавно добавленный в спецификацию:

Var myList = document.getElementById("myList"); myList.remove();

Этот метод не возвращает удаленный объект и не работает в IE (только в Edge). И оба метода удаляют текстовые узлы точно так же, как и узлы-элементы.

Замена дочерних элементов

Я могу заменить существующий дочерний элемент новым, независимо от того, существует ли этот новый элемент или я создал его с нуля. Вот разметка:

Example Text

Var myPar = document.getElementById("par"), myDiv = document.createElement("div"); myDiv.className = "example"; myDiv.appendChild(document.createTextNode("New element text")); document.body.replaceChild(myDiv, myPar);

New element text

Как видите, метод replaceChild() принимает два аргумента: новый элемент и заменяемый им старый элемент.

Я также могу использовать это метод для перемещения существующего элемента. Взгляните на следующий HTML:

Example text 1

Example text 2

Example text 3

Я могу заменить третий параграф первым параграфом с помощью следующего кода:

Var myPar1 = document.getElementById("par1"), myPar3 = document.getElementById("par3"); document.body.replaceChild(myPar1, myPar3);

Теперь сгенерированный DOM выглядит так:

Example text 2

Example text 1

Выборка конкретных дочерних элементов

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

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

  • Example one
  • Example two
  • Example three
  • Example four
  • Example five
  • Example Six

Я могу выбрать первый и последний элементы с помощью этих свойств:

Var myList = document.getElementById("myList"); console.log(myList.firstElementChild.innerHTML); // "Example one" console.log(myList.lastElementChild.innerHTML); // "Example six"

Я также могу использовать свойства previousElementSibling и nextElementSibling , если я хочу выбрать дочерние элементы, отличные от первого или последнего. Это делается сочетанием свойств firstElementChild и lastElementChild:

Var myList = document.getElementById("myList"); console.log(myList.firstElementChild.nextElementSibling.innerHTML); // "Example two" console.log(myList.lastElementChild.previousElementSibling.innerHTML); // "Example five"

Также есть сходные свойства firstChild , lastChild , previousSibling , и nextSibling , но они учитывают все типы узлов, а не только элементы. Как правило, свойства, учитывающие только узлы-элементы полезнее тех, которые выбирают все узлы.

Вставка контента в DOM

Я уже рассматривал способы вставки элементов в DOM. Давайте перейдем к похожей теме и взглянем на новые возможности по вставке контента.

Во-первых, есть простой метод insertBefore() , он во многом похож на replaceChild() , принимает два аргумента и при этом работает как с новыми элементами, так и с существующими. Вот разметка:

  • Example one
  • Example two
  • Example three
  • Example four
  • Example five
  • Example Six

Example Paragraph

Обратите внимание на параграф, я собираюсь сначала убрать его, а затем вставить перед списком, все одним махом:

Var myList = document.getElementById("myList"), container = document.getElementBy("c"), myPar = document.getElementById("par"); container.insertBefore(myPar, myList);

В полученном HTML параграф будет перед списком и это еще один способ перенести элемент.

Example Paragraph

  • Example one
  • Example two
  • Example three
  • Example four
  • Example five
  • Example Six

Как и replaceChild() , insertBefore() принимает два аргумента: добавляемый элемент и элемент, перед которым мы хотим его вставить.

Этот метод прост. Попробуем теперь более мощный способ вставки: метод insertAdjacentHTML() .

Последнее обновление: 21.04.2016

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

    :first-child : представляет элемент, который является первым дочерним элементом

    :last-child : представляет элемент, который является последним дочерним элементом

    :only-child : представляет элемент, который является единственным дочерним элементом в каком-нибудь контейнере

    :only-of-type : выбирает элемент, который является единственным элементом определенного типа (тега) в каком-нибудь контейнере

    :nth-child(n) : представляет дочерний элемент, который имеет определенный номер n, например, второй дочерний элемент

    :nth-last-child(n) : представляет дочерний элемент, который имеет определенный номер n, начиная с конца

    :nth-of-type(n) : выбирает дочерний элемент определенного типа, который имеет определенный номер

    :nth-last-of-type(n) : выбирает дочерний элемент определенного типа, который имеет определенный номер, начиная с конца

Псевдокласс first-child

Используем псевдокласс first-child для выбора первых ссылок в блоках:

Селекторы в CSS3

Планшеты

Смартфоны

Топ-смартфоны 2016

Samsung Galaxy S7
Apple iPhone SE
Huawei P9

Стиль по селектору a:first-child применяется к ссылке, если она является первым дочерним элементом любого элемента.

А во втором блоке первым элементом является параграф, поэтому ни к одной ссылке не применяется стиль.

Псевдокласс last-child

Используем псевдокласс last-child:

Селекторы в CSS3

Смартфоны

Планшеты

Селектор a:last-child определяет стиль для ссылок, которые являются последними дочерними элементами.

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

Селектор only-child

Селектор :only-child выбирает элементы, которые являются единственными дочерними элементами в контейнерах:

Селекторы в CSS3

Заголовок

Текст1

Текст2

Текст3

Текст4

Параграфы с текстами "Текст1" и "Текст4" являются единственными дочерними элементами в своих внешних контейнерах, поэтому к ним применяется стиль - красный цвет шрифта.

Псевдокласс only-of-type

Псевдокласс only-of-type выбирает элемент, который является единственным элементом определенного типа в контейнере. Например, единственный элемент div, при этом элементов других типов в этом же контейнере может быть сколько угодно.

Селекторы в CSS3

Header

Единственный параграф и элемент спан

Footer

Хотя для элементов div определен стиль, он не будет применяться, так как в контейнере body находится два элемента div, а не один. Зато в body есть только один элемент p, поэтому он получит стилизацию. И также в контейнере p есть только один элемент span, поэтому он также будет стилизован.

Псевдокласс nth-child

Псевдокласс nth-child позволяет стилизовать каждый второй, третий элемент, только четные или только нечетные элементы и т.д.

Например, стилизуем четные и нечетные строки таблицы:

Селекторы в CSS3

Смартфоны

SamsungGalaxy S7 Edge60000
AppleiPhone SE39000
MicrosoftLumia 65013500
AlcatelIdol S430000
HuaweiP960000
HTCHTC 1050000
MeizuPro 640000
XiaomiMi535000

Чтобы определить стиль для нечетных элементов, в селектор передается значение "odd":

Tr:nth-child(odd){}

Для стилизации четных элементов в селектор передается значение "even":

Tr:nth-child(even){}

Также в этот селектор мы можем передать номер стилизуемого элемента:

Tr:nth-child(3) { background-color: #bbb; }

В данном случае стилизуется третья строка.

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

Tr:nth-child(2n+1) { background-color: #bbb; }

Здесь стиль применяется к каждой второй нечетной строке.

Число перед n (в данном случае 2) представляет тот дочерний элемент, который будет выделен следующим. Число, которое идет после знака плюс, показывают, с какого элемента нужно начинать выделение, то есть, +1 означает, что нужно начинать с первого дочернего элемента.

Таким образом, в данном случае выделение начинается с 1-го элемента, а следующим выделяется 2 * 1 + 1 = 3-й элемент, далее 2 * 2 + 1 = 5-й элемент и так далее.

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

Tr:nth-child(3n+2) { background-color: #bbb; }

Псевдокласс :nth-last-child по сути предоставляет ту же самую функциональность, только отсчет элементов идет не с начала, а с конца:

Tr:nth-last-child(2) { background-color: #bbb; /* 2 строка с конца, то есть предпоследняя */ } tr:nth-last-child(2n+1) { background-color: #eee; /* нечетные строки, начиная с конца */ }

Псевдокласс nth-of-type

Псевдокласс :nth-of-type позволяет выбрать дочерний элемент определенного типа по определенному номеру:

Tr:nth-of-type(2) { background-color: #bbb; }

Аналогично работает псевдокласс nth-last-of-type , только теперь отсчет элементов идет с конца:

Tr:nth-last-of-type(2n) { background-color: #bbb; }

просмотров