Селектор — это способ сказать браузеру: «применяй эти стили вот к этим элементам». Без селекторов CSS не знал бы, к чему применять оформление. Это как адрес на конверте: письмо (стиль) должно знать, кому доставить.
Применяет стили ко всем элементам с данным тегом.
p { color: #333; } /* Все параграфы */
button { cursor: pointer; } /* Все кнопки */
h1 { font-size: 32px; } /* Все заголовки h1 */Удобно для базовых стилей, но слишком грубо для сложных интерфейсов.
Самый используемый в реальных проектах. Точка перед именем — признак класса.
.card { border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
.btn-primary { background: #7b2ff7; color: white; }
.active { border: 2px solid blue; }Один элемент может иметь несколько классов: <div class="card active featured">
Применяется к единственному элементу с данным id. Решётка перед именем.
#header { position: fixed; top: 0; width: 100%; }
#cart-count { background: red; color: white; border-radius: 50%; }ID должны быть уникальны на странице. В CSS их стараются избегать из-за высокой специфичности (об этом в следующем уроке).
.card p { color: #666; } /* Все p внутри .card */
nav a { text-decoration: none; } /* Все ссылки в навигации */.menu > li { display: inline-block; } /* Только li, прямые дети .menu */h1, h2, h3 { font-family: 'Georgia', serif; }
.btn-primary, .btn-secondary { padding: 10px 20px; border-radius: 6px; }h2 + p { margin-top: 0; } /* p сразу после h2 */
h2 ~ p { color: #444; } /* все p после h2 в том же родителе */input[type="text"] { border: 1px solid #ccc; }
input[type="checkbox"] { width: 16px; }
a[href^="https"] { color: green; } /* ссылки, начинающиеся с https */
a[href$=".pdf"] { color: red; } /* ссылки, заканчивающиеся на .pdf */
[data-theme="dark"] { background: #1a1a1a; } /* по data-атрибуту */* { box-sizing: border-box; margin: 0; padding: 0; }Часто используется для глобального сброса стилей в начале CSS-файла.
Ошибка 1: Пробел между тегом и классом
div .card { } /* Ищет .card ВНУТРИ div — не то же самое! */
div.card { } /* Div с классом card — правильно */Ошибка 2: Слишком длинные цепочки
/* Плохо — хрупко и трудно читать */
.page .section .container .row .col .card .card-body p { }
/* Хорошо — короткие, конкретные */
.card-body p { }Ошибка 3: Злоупотребление ID
#submit-button { } /* Плохо — невозможно переиспользовать */
.btn-submit { } /* Хорошо — класс можно применить к нескольким кнопкам */В React-проектах с CSS Modules имена классов автоматически генерируются уникальными: .card__title превращается в .Card_title__x7k2f. В Tailwind CSS ты вообще не пишешь селекторы — используешь готовые классы-утилиты. Но под капотом всё равно работают те же механизмы выбора элементов.
BEM-методология называет классы по схеме блок__элемент--модификатор: .card__title--large. Это самое популярное соглашение об именах в больших CSS-проектах.
Работа с классами и селекторами через JavaScript DOM API
// Создаём структуру: карточка с заголовком и описанием
const styleTag = document.createElement('style')
styleTag.textContent = `
.card { border: 1px solid #ddd; border-radius: 12px; padding: 16px; margin: 8px; }
.card.featured { border-color: #7b2ff7; box-shadow: 0 2px 12px rgba(123,47,247,0.2); }
.card__title { font-size: 18px; font-weight: bold; color: #111; }
.card__title--sale { color: #e53e3e; }
.card p { color: #666; font-size: 14px; }
`
document.head.appendChild(styleTag)
// Обычная карточка
const card1 = document.createElement('div')
card1.className = 'card'
const title1 = document.createElement('h3')
title1.className = 'card__title'
title1.textContent = 'Кроссовки Nike'
const desc1 = document.createElement('p')
desc1.textContent = 'Размер 42, белые'
card1.appendChild(title1)
card1.appendChild(desc1)
document.body.appendChild(card1)
// Карточка со скидкой (featured + sale)
const card2 = document.createElement('div')
card2.className = 'card featured' // несколько классов
const title2 = document.createElement('h3')
title2.className = 'card__title card__title--sale' // BEM модификатор
title2.textContent = 'Кроссовки Adidas -30%'
card2.appendChild(title2)
document.body.appendChild(card2)
// Проверяем классы через classList API
console.log('card1 классы:', card1.className)
console.log('card2 классы:', card2.className)
console.log('card2 — featured?', card2.classList.contains('featured')) // true
console.log('card1 — featured?', card1.classList.contains('featured')) // false
// Динамически добавляем/удаляем класс
card1.classList.add('featured')
console.log('После добавления featured:', card1.classList.contains('featured')) // true
card1.classList.remove('featured')
card1.classList.toggle('featured') // добавит, если нет
console.log('После toggle:', card1.classList.contains('featured')) // true
// querySelector использует те же селекторы что и CSS
const allCards = document.querySelectorAll('.card')
console.log('Количество карточек:', allCards.length) // 2
const featuredCard = document.querySelector('.card.featured')
console.log('Есть featured карточка:', featuredCard !== null) // trueСелектор — это способ сказать браузеру: «применяй эти стили вот к этим элементам». Без селекторов CSS не знал бы, к чему применять оформление. Это как адрес на конверте: письмо (стиль) должно знать, кому доставить.
Применяет стили ко всем элементам с данным тегом.
p { color: #333; } /* Все параграфы */
button { cursor: pointer; } /* Все кнопки */
h1 { font-size: 32px; } /* Все заголовки h1 */Удобно для базовых стилей, но слишком грубо для сложных интерфейсов.
Самый используемый в реальных проектах. Точка перед именем — признак класса.
.card { border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
.btn-primary { background: #7b2ff7; color: white; }
.active { border: 2px solid blue; }Один элемент может иметь несколько классов: <div class="card active featured">
Применяется к единственному элементу с данным id. Решётка перед именем.
#header { position: fixed; top: 0; width: 100%; }
#cart-count { background: red; color: white; border-radius: 50%; }ID должны быть уникальны на странице. В CSS их стараются избегать из-за высокой специфичности (об этом в следующем уроке).
.card p { color: #666; } /* Все p внутри .card */
nav a { text-decoration: none; } /* Все ссылки в навигации */.menu > li { display: inline-block; } /* Только li, прямые дети .menu */h1, h2, h3 { font-family: 'Georgia', serif; }
.btn-primary, .btn-secondary { padding: 10px 20px; border-radius: 6px; }h2 + p { margin-top: 0; } /* p сразу после h2 */
h2 ~ p { color: #444; } /* все p после h2 в том же родителе */input[type="text"] { border: 1px solid #ccc; }
input[type="checkbox"] { width: 16px; }
a[href^="https"] { color: green; } /* ссылки, начинающиеся с https */
a[href$=".pdf"] { color: red; } /* ссылки, заканчивающиеся на .pdf */
[data-theme="dark"] { background: #1a1a1a; } /* по data-атрибуту */* { box-sizing: border-box; margin: 0; padding: 0; }Часто используется для глобального сброса стилей в начале CSS-файла.
Ошибка 1: Пробел между тегом и классом
div .card { } /* Ищет .card ВНУТРИ div — не то же самое! */
div.card { } /* Div с классом card — правильно */Ошибка 2: Слишком длинные цепочки
/* Плохо — хрупко и трудно читать */
.page .section .container .row .col .card .card-body p { }
/* Хорошо — короткие, конкретные */
.card-body p { }Ошибка 3: Злоупотребление ID
#submit-button { } /* Плохо — невозможно переиспользовать */
.btn-submit { } /* Хорошо — класс можно применить к нескольким кнопкам */В React-проектах с CSS Modules имена классов автоматически генерируются уникальными: .card__title превращается в .Card_title__x7k2f. В Tailwind CSS ты вообще не пишешь селекторы — используешь готовые классы-утилиты. Но под капотом всё равно работают те же механизмы выбора элементов.
BEM-методология называет классы по схеме блок__элемент--модификатор: .card__title--large. Это самое популярное соглашение об именах в больших CSS-проектах.
Работа с классами и селекторами через JavaScript DOM API
// Создаём структуру: карточка с заголовком и описанием
const styleTag = document.createElement('style')
styleTag.textContent = `
.card { border: 1px solid #ddd; border-radius: 12px; padding: 16px; margin: 8px; }
.card.featured { border-color: #7b2ff7; box-shadow: 0 2px 12px rgba(123,47,247,0.2); }
.card__title { font-size: 18px; font-weight: bold; color: #111; }
.card__title--sale { color: #e53e3e; }
.card p { color: #666; font-size: 14px; }
`
document.head.appendChild(styleTag)
// Обычная карточка
const card1 = document.createElement('div')
card1.className = 'card'
const title1 = document.createElement('h3')
title1.className = 'card__title'
title1.textContent = 'Кроссовки Nike'
const desc1 = document.createElement('p')
desc1.textContent = 'Размер 42, белые'
card1.appendChild(title1)
card1.appendChild(desc1)
document.body.appendChild(card1)
// Карточка со скидкой (featured + sale)
const card2 = document.createElement('div')
card2.className = 'card featured' // несколько классов
const title2 = document.createElement('h3')
title2.className = 'card__title card__title--sale' // BEM модификатор
title2.textContent = 'Кроссовки Adidas -30%'
card2.appendChild(title2)
document.body.appendChild(card2)
// Проверяем классы через classList API
console.log('card1 классы:', card1.className)
console.log('card2 классы:', card2.className)
console.log('card2 — featured?', card2.classList.contains('featured')) // true
console.log('card1 — featured?', card1.classList.contains('featured')) // false
// Динамически добавляем/удаляем класс
card1.classList.add('featured')
console.log('После добавления featured:', card1.classList.contains('featured')) // true
card1.classList.remove('featured')
card1.classList.toggle('featured') // добавит, если нет
console.log('После toggle:', card1.classList.contains('featured')) // true
// querySelector использует те же селекторы что и CSS
const allCards = document.querySelectorAll('.card')
console.log('Количество карточек:', allCards.length) // 2
const featuredCard = document.querySelector('.card.featured')
console.log('Есть featured карточка:', featuredCard !== null) // trueНапиши HTML-страницу с тремя div-элементами. Первый — только класс item, второй — классы item и active (зелёный фон), третий — классы item и disabled (полупрозрачный). Используй разные типы CSS-селекторов: тег div, класс .item, комбинацию .item.active.
.item.active (без пробела) — оба класса на одном элементе. class="item active" — задаёт два класса. opacity: 0.5 делает элемент полупрозрачным. background: green или #38a169 для зелёного фона.