Перестанет быть первым дочерним тегом. В данном случае первым дочерним элементом будет h2 .
Всё то же самое происходит и с правилом p:last-child – стиль CSS будет применен к тегу
Любой другой тег отличного типа и вы увидите, что правило p:last-child перестанет применяться.
(об этом свидетельствует число 3 в скобках). Цвет шрифта для этого абзаца становится красным. Вы можете изменить число 3 (например, на 2) и посмотреть результат.
Правила tr:nth-child(odd) и tr:nth-child(even) работают для нечётных и чётных элементов tr соответственно. Вы можете увидеть результат на скриншоте, а также скопировать весь код и поэкспериментировать со стилями самостоятельно.
/* CSS */
p:first-of-type {
color: violet;
text-transform: uppercase;
}
p:last-of-type {
font-style: italic;
font-size: 0.8em;
}
p:nth-of-type(3) {
color: red;
}
p:nth-of-type(odd) {
background-color: #A2DED0;
}
p:nth-of-type(even) {
background-color: #C8F7C5;
}
h3:only-of-type {
text-decoration: underline;
}
Скриншот: применение:first-of-type, :last-of-type, :nth-of-type и:only-of-type
Первое правило CSS, которое вы видите – это p:first-of-type . Что оно делает? Оно выбирает дочерний элемент типа p , который первым
встречается у родителя. И не важно, на каком месте среди элементов других типов находится данный тег – на первом, втором или десятом. В этом и заключается отличие между псевдоклассами:first-child и:first-of-type .
Следующее правило – p:nth-of-type(3) – изменяет цвет шрифта на красный. Применяется этот стиль к тегу
. Но если не брать во внимание элементы других типов, то получается, что тег
С красным шрифтом находится на третьем месте (среди тегов своего типа). Таким образом работает данное правило.
Правила p:nth-of-type(even) и p:nth-of-type(odd) работают аналогично: поскольку перед двоеточием указано имя p , то выбираются четные и нечетные дочерние элементы типа p и окрашиваются в заданные цвета. Остальные элементы пропускаются.
Последнее правило – h3:only-of-type – применяется к содержимому тега
, делая текст подчеркнутым. Данный стиль работает лишь потому, что тег является единственным
дочерним элементом своего типа. Если в HTML-код добавить еще один тег , стиль не будет применён.
Выводы
Дочерний селектор CSS позволяет изменить стиль дочернего элемента HTML-документа, исходя из того, кто является его родителем.
С помощью дополнительных псевдоклассов:first-child, :last-child, :nth-child, :only-child можно стилизовать дочерние элементы HTML-документа, ориентируясь на их местоположение, нумерацию в дереве элементов.
Псевдоклассы:first-of-type, :last-of-type, :nth-of-type, :only-of-type позволяют применять стиль к дочерним элементам HTML-документа, ориентируясь на их тип, а также на нумерацию в дереве элементов.
Дочерние элементы - это элементы, которые располагаются непосредственно внутри родительского элемента. Обратите внимание на слова: непосредственно внутри.
Давайте рассмотрим пример простого 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() .
Приветствую Вас, уважаемые читатели. В предыдущих статьях мы изучали, в основном, атрибуты стилей CSS. Их очень много. Одни задают параметры шрифтов, другие параметры фона, третьи параметры отступов и рамок.
В этой статье мы поговорим о селекторах стилей. В одной из статье мы уже затрагивали . А сегодня рассмотрим еще несколько видов селекторов, которые не явно привязывают правило стиля к элементу веб-страницы. Это так называемые специальные селекторы. Их бывает несколько видов.
Комбинаторы в CSS (Соседний, дочерний и контекстный селекторы)
Комбинаторы
— это разновидность css селекторов, привязывающие правило стиля к элементу web-страницы на основании его местоположения относительно других элементов.
Первый комбинатор символ плюс
(+) или соседний селектор
. Плюс устанавливается между двумя селекторами:
<селектор 1> + <селектор 2> { <стиль> }
Стиль в этом случае применяется к селектору 2
, но только в том случае если он является соседним для селектора 1
и идет сразу после него. Рассмотрим пример:
strong + i {
}
...
Это обычный текст. Это жирный текст, обычный текст, красный текст
Это обычный текст. Это жирный текст, обычный текст, и это обычный текст.
Результат:
Стиль описанный в примере будет применен только к первому тексту заключенному в тег
, т.к. он следует сразу же после тега
.
Комбинатор тильда
(~) также применяется к соседним селекторам, но в этот раз между ними могут быть другие элементы. При этом оба селектора должны быть вложены в один и тот же родительский тег:
<селектор 1> ~ <селектор 2> { <стиль> }
Стиль будет применен к селектору 2
, который должен следовать за селектором 1
. Рассмотри пример:
strong ~ i {
color: red; /* Красный цвет текста */
}
...
Это обычный текст. Это жирный текст, обычный текст, красный текст к нему применилось правило соседних селекторов.
Это обычный текст. Это жирный текст, обычный текст, а это красный текст.
Результат:
Как видим, в этот раз правило стиля сработало для обоих текстов заключенных в тег
, несмотря на то, что во втором случае между тегом
и
стоит тег
.
Комбинатор >
относится к дочерним селекторам
. Позволяет привязать стиль CSS к элементу веб-страницы, непосредственно вложенному в другой элемент:
<селектор 1> > <селектор 2> { <стиль> }
Стиль
будет привязан к селектору 2
, который непосредственно вложен в селектор 1
.
div > strong {
}
...
Это обычный текст.
Это жирный курсивный текст .
Это обычный текст. А это обычный жирный текст.
И результат:
Как видно на рисунке, правило стиля подействовало только на первый тег
, который непосредственно вложен в тег
. А непосредственным родителем второго тега
является тег
, поэтому правило на него не действует.
Следующим рассмотрим контекстный селектор <пробел>
. Он позволяет привязать CSS стиль к элементу вложенному в другой элемент, причем может быть любой уровень вложенности:
<селектор 1> <селектор 2> { <стиль> }
Стиль будет применен к селектору 2
, если он так или иначе вложен в селектор 1
.
Рассмотрим предыдущий пример, только при описании CSS правила применим контекстный селектор:
div strong {
font-style: italic /* Курсив */
}
...
Это обычный текст.
Это жирный курсивный текст .
Это обычный текст. А это тоже курсивный жирный текст.
Обычный текст и просто жирный текст
Результат:
Как видим, на этот раз правило подействовало на оба тега
, даже на тот, который вложен и в контейнер
и в абзац
. На тег
, который просто вложен в абзац
правило css никак не действует.
Селекторы по атрибутам тега
Селекторы атрибутов — это специальные селекторы, которые привязывают стиль к элементу на основании, присутствует ли в нем определенный атрибут или имеет ли он определенное значение. Существует несколько вариантов применения таких селекторов.
1. Простой селектор атрибута
Имеет вид:
<селектор>[<имя атрибута тега>] { <стиль> }
И привязывает стиль к тем элементам, внутри которых добавлен указанный атрибут. Например:
strong{
color:red;
}
...
Автомобиль это механическое моторное безрельсовое транспортное средство">дорожное транспортное средство минимум с 4 колёсами.
Результат:
На рисунке можно заметить, что правило css (красный цвет текста) применяется к элементу strong
, к которому добавлен атрибут title
.
2. Селектор атрибута со значением
Синтаксис этого селектора следующий:
<селектор>[<имя атрибута тега>=<значение>] { <стиль> }
Привязывает стиль
к элементам, теги которых имеют атрибут с указанным именем
и значением
. Пример:
a{
color:red;
font-size:150%;
}
...
.ru" target="_blank">Ссылка в новом окне
Результат:
Как видим, оба элемента типа гиперссылка имеют атрибут target
, но правило css, которое увеличивает текст ссылки в полтора раза и изменяет его цвет в красный, применяется к тегу
у которого атрибут target
имеет значение «_blank»
.
3. Одно из нескольких значений атрибута
Некоторые значения атрибутов могут перечисляться через пробел, например имена классов. Чтобы задать правило стиля при наличии в списке значений атрибутов требуемого значения применяется следующий селектор:
[<имя атрибута тега>~=<значение>] { <стиль> }
<основной селектор>[<имя атрибута тега>~=<значение>] { <стиль> }
Стиль применяется в том случае, если у атрибута имеется требуемое значение или оно входит в список значений, разделенных пробелами. Например:
{
color:red;
font-size:150%;
}
...
Наш телефон: 777-77-77
Наш адрес: Москва ул. Советская 5
Получиться следующий результат:
Правило применяется к элементу, у которого среди значений атрибута class
имеется значение tel
.
4. Дефис в значении атрибута
В значениях идентификаторов и классов допускается использовать дефис. Для привязки стиля к элементам, значения атрибутов которых могут содержать дефис можно воспользоваться следующей конструкцией:
[атрибут|="значение"] { стиль }
Селектор[атрибут|="значение"] { стиль }
Стиль применяется к тем элементам, у которых значение атрибута начинается с указанного значения после, которого идет дефис. Например:
{
color:red;
font-size:150%;
}
...
Результат:
В примере правило стиля применяется только к тем элементам списка, у которых имя класса начинается со значения «menu- „
.
5. Значение атрибута начинается с определенного текста
Данный селектор устанавливает стиль для элемента, если значение атрибута тега начинается с определенного значения. Может быть два варианта:
[<имя атрибута тега>^=<подстрока>] { <стиль> }
<основной селектор>[<имя атрибута тега>^=<подстрока>] { <стиль> }
В первом случае стиль
применяется ко всем элементам, теги которых имеют атрибут с указанным именем
и значением, начинающимся с указанной подстроки
. Во втором случае тоже самое, только к определенным элементам указанным в основном селекторе
. Пример:
a{
color:green;
font-weight:bold;
}
...
Результат:
В примере показано, как по разному отобразить внешние ссылки и внутренние ссылки. Внешние ссылки всегда начинаются со строки «http://». Поэтому в селекторе указываем, что стиль применять только к ссылкам, у которых атрибут href
начинается со значения http://
.
6. Значение атрибута заканчивается определенным текстом
Привязывает стиль к элементам, у которых значение атрибута заканчивается указанным текстом. Имеет следующий синтаксис:
[<имя атрибута тега>$=<подстрока>] { <стиль> }
<основной селектор>[<имя атрибута тега>$=<подстрока>] { <стиль> }
В первом случае стиль
применяется ко всем элементам, у которых имеется атрибут
с указанным именем
и имеет значение оканчивающееся указанной подстрокой
. Во втором случае тоже самое, только к указанным селекторам
. Таким способом, например, можно по разному отображать различные форматы графических изображений. Например:
IMG {
border: 5px solid red;
}
...
Картинка формата gif
Картинка формата png
Результат:
В примере все картинки с расширением gif будут отображаться с красной рамкой толщиной пять пикселей.
7. Значение атрибута содержит указанную строку
Этот селектор привязывает стиль к тегам, значение атрибута которых содержат определенный текст. Синтаксис:
[<имя атрибута тега>*=<подстрока>] { <стиль> }
<основной селектор>[<имя атрибута тега>*=<подстрока>] { <стиль> }
Стиль
привязывается к элементам, у которых имеется атрибут
с указанным именем и его значение содержит указанную подстроку
. Например:
IMG {
border: 5px solid red;
}
...
Картинка из папки gallery
Картинка из другой папки
Результат:
В примере стиль применяется к картинкам, которые загружены из папки «gallery»
.
На этом об селекторах атрибутов все. Все перечисленные методы можно комбинировать между собой:
Селектор[атрибут1="значение1"][атрибут2="значение2"] { стиль }
Кроме того напомню о специальных селекторах CSS:
- с помощью символов «+» и «~» формируются ;
- символ «>» привязывает css стили к дочерним
тегам;
- символ <пробел> формирует контекстные селекторы.
В следующих статьях мы рассмотрим также псевдоэлементы и псевдоклассы, которые предоставляют мощный инструмент управления стилями.
На этом все, до новых встреч.
Я думаю, что многие знают о контекстных селекторах в CSS
. Они используются чаще всего, однако, опытные верстальщики прекрасно знают, что иногда контекстные селекторы вносят определённые проблемы. Это проблема связана с тем, что в структуре элемента может быть много одинаковых элементов, вложенных друг в друга. И необходимо применить стиль не для всех вложенных элементов, а только к непосредственно дочернему элементу. Вот для этого и используются дочерные селекторы в CSS
.
Чтобы проблема стала более понятной, давайте приведу небольшой пример. Пусть у нас есть такой HTML-код
:
И наша задача сделать красным только "Второй абзац
". Если мы напишем с использованием контекстного селектора:
Container p {
color: red;
}
То у нас станут красным оба абзаца, что нам совсем не нужно. Данная задача очень просто решается с помощью дочерних селекторов в CSS
:
Container > p {
color: red;
}
Всё, теперь красным у нас стал только "Второй абзац
". Поскольку именно данный абзац является непосредственно дочерним для .container
. А "Первый абзац
" является дочерним для внутреннего div
, таким образом, под действие дочернего селектора он не попадает.
Вот так легко решаются такие задачи, однако, есть один огромный минус дочерних селекторов в CSS
- они не работают в браузерах Internet Explorer
. По этой причине, их использование крайне нежелательно. Но если Вы вдруг где-нибудь встретите, то теперь Вы будете знать, что означает данный тип селекторов и что он делает.