Элементы CSS: селекторы и позиционирование c примерами

Не знаете, как работают элементы CSS? Пора освоить все виды селекторов и позиционирование на странице. Разбираем наглядные примеры.

Введение в CSS

CSS (аббревиатура от Cascading Style Sheets – каскадные таблицы стилей) – язык, который используем для оформления стиля HTML-файла и сообщения браузеру, как отображать элементы на странице.

Речь пойдёт исключительно о стилях документов HTML, хотя CSS применяют и для других XML-документов.

Файл CSS содержит правила CSS.

Каждое правило состоит из 2 частей:

  • селектор
  • блок объявлений

Селектор CSS – строка, которая идентифицирует элементы (один или несколько) на странице в соответствии со специальным синтаксисом, о котором скоро поговорим.

Блок объявлений содержит одно или несколько объявлений, которые состоят из свойства и значения.

Больше в CSS ничего нет.

Как выглядит CSS

Набор правил CSS состоит из cелектора и объявления.

Объявление содержит правила, каждое из которых состоит из свойства и значения.

В этом примере селектор p применяет одно правило, которое устанавливает значение 20px для свойства font-size:

p {
  font-size: 20px;
}

Правила следуют одно за другим:

p {
  font-size: 20px;
}
a {
  color: blue;
}

Селектор распространяется на один или больше элементов:

p, a {
  font-size: 20px;
}

и на теги HTML, как указано выше, или элементы HTML, которые содержат конкретный атрибут class.my-class, или элементы HTML с конкретным атрибутом id#my-id.

Продвинутые селекторы CSS выбирают элементы, атрибут которых соответствует конкретному значению, и элементы, которые отвечают псевдоклассам (подробнее об этом позже).

Точка с запятой

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

Добавление CSS на страницу HTML

CSS прикрепляется к HTML-странице тремя способами.

1: Использование тега link

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

Для использования этого метода добавляем тег link с атрибутом href, который указывает на нужный файл CSS. Делаем это внутри тега head, а не внутри тега body:

<link rel="stylesheet" type="text/css" href="myfile.css">

Атрибуты rel и type также обязательные, поскольку они сообщают браузеру, на какой тип файла ссылаться.

2: Использование тега style

Вместо того, чтобы использовать тег link для указания отдельной таблицы стилей, которая содержит наш CSS, добавляем CSS непосредственно внутри тега style. Синтаксис такой:

<style>
...наш CSS...
</style>

Когда используем этот метод, избегаем создания отдельного файла CSS. Это хороший способ поэкспериментировать перед «формализацией» CSS в отдельном файле.

3: Встроенные стили

Встроенные стили – третий способ добавления CSS на страницу. Добавляем атрибут style к любому тегу HTML и включаем в него CSS.

<div style="">...</div>

Пример:

<div style="background-color: yellow">...</div>

Селекторы

Селектор связывает одно и более объявлений с одним или несколькими элементами на странице.

Базовые селекторы

Предположим, отобразим слова в элементе p на странице жёлтым цветом.

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

p {
  color: yellow;
}

Каждому тегу HTML соответствует селектор, например: div, span, img.

Если селектор CSS соответствует нескольким элементам, изменение затронет все элементы на странице.

Для привязки стиля к необходимому элементу на странице используются два атрибута HTML-элементов: class и id.

Различие между ними состоит в том, что внутри HTML-документа одно и то же значение class используется для одного или нескольких элементов, а id только один раз. Как следствие, с использованием классов CSS выбираются элементы с двумя и более конкретными именами классов, что невозможно с помощью идентификаторов.

Классы обозначаются с помощью символа ., в то время как для идентификаторов используется символ #.

Пример использования класса:

<p class="dog-name">
  Роджер
</p>
.dog-name {
  color: yellow;
}

Пример использования идентификатора:

<p id="dog-name">
  Роджер
</p>
#dog-name {
  color: yellow;
}

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

Выбор элемента с помощью класса CSS или идентификатора

Выберем целевые элементы, к которым прикрепляется класс или идентификатор.

Пример использования класса:

<p class="dog-name">
  Роджер
</p>
p.dog-name {
  color: yellow;
}

Пример использования идентификатора:

<p id="dog-name">
  Роджер
</p>
p#dog-name {
  color: yellow;
}

Ориентация на составные классы

Уже в курсе, как выбрать целевой элемент с помощью конкретного класса с использованием .class-name. Теперь отметим элемент с двумя или более классами: объединим имена классов и разделим точкой, без пробелов.

Пример:

<p class="dog-name roger">
  Роджер
</p>
.dog-name.roger {
  color: yellow;
}

Объединение классов и идентификаторов

Таким же образом объединяем класс и идентификатор.

Пример:

<p class="dog-name" id="roger">
  Роджер
</p>
.dog-name#roger {
  color: yellow;
}

Группировка селекторов

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

Пример:

<p>
  Мою собаку зовут:
</p>
<span class="dog-name">
  Роджер 
</span>
p, .dog-name {
  color: yellow;
}

Добавим отступы в этих объявлениях для понятности:

p,
.dog-name {
  color: yellow;
}

Следование по дереву документа с помощью селекторов

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

<span>
  Здравствуйте!
</span>
<p>
  Мою собаку зовут:
  <span class="dog-name">
    Роджер 
  </span>
</p>
p span {
  color: yellow;
}

Посмотрите, как использовали пробел между двумя токенами p и span.

Это работает даже при многоуровневой вложенности элемента справа.

Для определения зависимости первого уровня используем символ > между двумя токенами:

p > span {
  color: yellow;
}

В этом случае, если span не первый потомок элемента p, новый цвет не применяется. Стиль будет применяться к прямым потомкам:

<p>
  <span>
    Это жёлтый
  </span>
  <strong>
    <span>
      Это не жёлтый
    </span>
  </strong>
</p>

Одноуровневые селекторы стилизуют элемент, только если ему предшествует конкретный элемент. Делаем это с помощью оператора +.

Пример:

p + span {
  color: yellow;
}

Это назначит жёлтый цвет элементам span, которым предшествует элемент p:

<p>Это абзац</p>
<span>Это жёлтый промежуток</span>

Селекторы атрибутов

В этом разделе проанализируем селекторы атрибутов. Поговорим о селекторах  псевдоклассов и селекторах псевдоэлементов в следующих двух разделах.

Селектор присутствия атрибута

Первый тип селектора – атрибут присутствия атрибута.

Проверим, содержит ли элемент атрибут, используя синтаксис []. p[id] выберет все теги p на странице, которые имеют атрибут id, независимо от значения:

p[id] {
  /* ... */
}

Точные селекторы значений атрибутов

Внутри скобок проверяем значение атрибута с помощью =, и CSS будет применяться только в том случае, если атрибут соответствует указанному значению:

p[id="my-id"] {
  /* ... */
}

Соответствие части значения атрибута

Хотя = проверяет точное значение, существуют другие операторы для проверки:

  • *= содержит ли атрибут часть
  • ^= начинается ли атрибут с части
  • $= заканчивается ли атрибут частью
  • |= начинается ли атрибут с части и после него идёт тире (например, в классах) или просто содержит часть
  • ~= содержится ли часть в атрибуте, но отделена пробелами от остальных

Все упомянутые проверки чувствительны к регистру.

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

Псевдоклассы

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

Начинаются с одного двоеточия :.

Используются как часть селектора, и полезны для стилизации активных или посещённых ссылок. Например, для изменения стиля при наведении, фокусе или выборе первого потомка или нечётных строк.

Рассмотрим рядовой пример. Вы хотите стилизовать ссылку, поэтому создаёте правило CSS для элемента a:

a {
  color: yellow;
}

Это, кажется, работает, пока не нажмёте одну ссылку. Ссылка возвращается к предопределенному цвету (синему) при нажатии на неё. Затем, когда открываете ссылку и возвращаетесь на страницу, ссылка синего цвета.

Почему это происходит?

Потому что ссылка при нажатии изменяет состояние: переходит в состояние :active. И когда ссылку посетили, она становится :visited. Навсегда, пока пользователь не очистит историю просмотров.

Итак, чтобы правильно сделать ссылку жёлтой во всех состояниях, напишем

a,
a:visited,
a:active {
  color: yellow;
}

:nth-child() заслуживает отдельного упоминания. Применяется для обозначения нечётных или чётных потомков: :nth-child(odd) и :nth-child(even).

Часто это используется в списках для отличия нечётных линий от чётных:

ul:nth-child(odd) {
  color: white;
    background-color: black;
}

Псевдоэлементы CSS

Псевдоэлементы используются для стилизации определённой части элемента.

Начинаются с двойного двоеточия ::.

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

::before и ::after, вероятно, самые используемые псевдоэлементы.

Применяются для добавления содержимого до или после элемента, например, иконки.

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

p::first-line {
  font-size: 2rem;
}

Или, может быть, хотим, чтобы первая буква была жирнее:

p::first-letter {
  font-weight: bolder;
}

::after и ::before менее интуитивны. Указываем свойство content для вставки содержимого любого типа после или перед элементом:

p::before {
  content: url(/myimage.png);
}
.myElement::before {
    content: "Эй, эй!";
}

Позиционирование

Позиционирование – это то, с помощью чего в CSS мы определяем, где элементы появляются на экране и как они появляются.

Статическое позиционирование

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

Относительное позиционирование

Если установите position: relative для элемента, то сможете изменить его расположение со смещением, используя свойства

  • top
  • right
  • bottom
  • left

которые называются свойствами смещения. Принимают значение длины или процент.

Смотрите пример на Codepen. Создали родительский контейнер, дочерний контейнер и внутреннее поле с текстом:

<div class="parent">
  <div class="child">
    <div class="box">
      <p>Test</p>
    </div>
  </div>
</div>

и CSS, который добавляет цвета и поля, но не затрагивает позиционирование:

.parent {
  background-color: #af47ff;
  padding: 30px;
  width: 300px;
}
.child {
  background-color: #ff4797;
  padding: 30px;
}
.box {
  background-color: #f3ff47;
  padding: 30px;
  border: 2px solid #333;
  border-style: dotted;
  font-family: courier;
  text-align: center;
  font-size: 2rem;
}

вот результат:

элементы css

Попробуйте добавить любое из свойств, которые упоминали раньше (top, right, bottom, left), в .box, и ничего не произойдёт. Положение static.

Теперь, если установим position: relative в блок, сначала кажется, что ничего не изменилось. Но теперь элемент перемещается с использованием свойств top, right, bottom, left. И теперь положение изменяется относительно элемента, содержащего его.

Например:

.box {
  /* ... */
  position: relative;
  top: -60px;
}

элементы css

Отрицательное значение для top заставит блок двигаться вверх относительно контейнера.

Или же

.box {
  /* ... */
  position: relative;
  top: -60px;
  left: 180px;
}

элементы css

Обратите внимание, как пространство, которое занимает блок, сохраняется в контейнере, как будто ещё на месте.

Ещё одно свойство, которое теперь работает, это z-index, и изменяет размещение по оси z.

Абсолютное позиционирование

Установка position: absolute для элемента удалит его из потока документа.

Помните наблюдение при относительном позиционировании, что пространство, первоначально занимаемое элементом, сохраняется даже при перемещении элемента?

При абсолютном позиционировании как только устанавливаем position: absolute в .box, его исходное пространство теперь разрушено, и только исходная точка (координаты x, y) остаётся прежней.

.box {
  /* ... */
  position: absolute;
}

элементы css

Теперь перемещаем блок по своему усмотрению, используя свойства top, right, bottom, left:

.box {
  /* ... */
  position: absolute;
  top: 0px;
  left: 0px;
}

элементы css

или

.box {
  /* ... */
  position: absolute;
  top: 140px;
  left: 50px;
}

элементы css

Координаты указаны относительно ближайшего контейнера, который не static.

Это означает, что если добавим position: relative для элемента .child и установим top и left в 0, блок появится не в верхней левой границе окна, а на координатах 0, 0 элемента .child:

.child {
  /* ... */
  position: relative;
}
.box {
  /* ... */
  position: absolute;
  top: 0px;
  left: 0px;
}

элементы css

Как уже видели, .child статический по умолчанию:

.child {
  /* ... */
  position: static;
}
.box {
  /* ... */
  position: absolute;
  top: 0px;
  left: 0px;
}

элементы css

Как и для относительного позиционирования, используется z-index, чтобы изменить положение по оси z.

Фиксированное позиционирование

Как и в случае абсолютного позиционирования, когда элементу назначается position: fixed, он удаляется из потока страницы.

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

.box {
  /* ... */
  position: fixed;
}

элементы css

.box {
  /* ... */
  position: fixed;
  top: 0;
  left: 0;
}

элементы css

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

Липкое позиционирование

Несмотря на то, что предыдущие значения вводили уже давно, это добавили недавно. И оно по-прежнему относительно не поддерживается (смотрите caniuse.com).

Компонент iOS UITableView – то, что приходит на ум, когда думаешь о position: sticky. Знаете, когда прокручиваешь список контактов, и первая буква закреплена сверху, чтобы знать, что просматриваешь контакты на эту конкретную букву?

Раньше использовали JavaScript для подобной имитации, а теперь этот подход поддерживается в CSS нативно.

Обтекание и его отмена

Обтекание было важной темой в прошлом.

Использовалось в куче хаков и творческих приёмов, потому что этот способ, вместе с таблицами, на самом деле давал реализовать некоторые макеты. Раньше использовали обтекание боковой панели слева, например, чтобы показывать её в левой части экрана. И добавляли отступы к основному контенту.

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

Свойство float поддерживает три значения:

  • left
  • right
  • none (по умолчанию)

Скажем, блок содержит абзац с некоторым текстом, а абзац также содержит изображение.

Вот код:

<div class="parent">
  <div class="child">
    <div class="box">
      <p>This is some random paragraph and an image. <img 
src="https://via.placeholder.com/100x100" /> The image is in the 
middle of the text. The image is in the middle of the text. The
image is in the middle of the text. The image is in the middle of 
the text. The image is in the middle of the text. The image is in 
the middle of the text. The image is in the middle of the text. The 
image is in the middle of the text. The image is in the middle of 
the text.
      </p>
    </div>
  </div>
</div>
.parent {
  background-color: #af47ff;
  padding: 30px;
  width: 500px;
}
.child {
  background-color: #ff4797;
  padding: 30px;
}
.box {
  background-color: #f3ff47;
  padding: 30px;
  border: 2px solid #333;
  border-style: dotted;
  font-family: courier;
  text-align: justify;
  font-size: 1rem;
}

и внешний вид:

элементы css

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

Если добавим float: left к изображению и некоторые поля:

img {
  float: left;
  padding: 20px 20px 0px 0px;
}

результат такой:

элементы css

а это то, что получаем, когда применяем float: right и соответственно корректируем поля:

img {
  float: right;
  padding: 20px 0px 20px 20px;
}

элементы css

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

Смотрите пример на Codepen

Не ограничиваемся плавающими изображениями. Здесь заменим изображение на элемент span:

<div class="parent">
  <div class="child">
    <div class="box">
      <p>This is some random paragraph and an image. <span>Some text 
to float</span> The image is in the middle of the text. The image is 
in the middle of the text. The image is in the middle of the text. 
The image is in the middle of the text. The image is in the middle 
of the text. The image is in the middle of the text. The image is in 
the middle of the text. The image is in the middle of the text. The 
image is in the middle of the text.
      </p>
    </div>
  </div>
</div>
span {
  float: right;
  margin: 20px 0px 20px 20px;
  padding: 10px;
  border: 1px solid black
}

и вот результат:

элементы css

Отмена обтекания

Что происходит, когда плавающий элемент не один?

Если сталкиваются два плавающих изображения, по умолчанию они складываются одно за другим, горизонтально. Пока не закончится место, и они начнут укладываться на новую линию.

Скажем, было три встроенных изображения внутри тега p:

элементы css

Если добавим float: left к этим изображениям:

img {
  float: left;
  padding: 20px 20px 0px 0px;
}

вот что будет:

элементы css

если добавите clear: left к изображениям, они разместятся вертикально, а не горизонтально:

элементы css

Это перевод части справочника CSS.

Продолжаем осваивать элементы CSS:

МЕРОПРИЯТИЯ

Комментарии

ВАКАНСИИ

Добавить вакансию
ML- инженер
Москва, по итогам собеседования
Fullstack разработчик .NET
по итогам собеседования
Разработчик на Go в Еду
Москва, по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ