Селекторы — это способ сказать браузеру, к каким именно элементам применить набор стилей. Самые простые из них знакомы почти сразу: селектор по тегу задаёт стиль всем элементам этого типа, селектор по классу — только тем, у кого этот класс указан в атрибуте, селектор по id — единственному элементу с этим идентификатором.
Дальше начинаются комбинированные селекторы, которые позволяют описывать более точные условия. Пробел между двумя селекторами означает потомка на любом уровне вложенности, символ больше — прямого потомка, а знак плюс — соседний элемент сразу после текущего. Каждый из этих операторов решает свою конкретную задачу верстки.
Селектор по атрибуту — ещё один полезный инструмент, который используют реже, чем стоило бы. Он позволяет выбрать, например, все ссылки, у которых атрибут href начинается с определённой части адреса, без добавления отдельного класса специально для этого случая.
Группировка селекторов через запятую экономит немало кода, когда несколько разных элементов должны выглядеть одинаково — вместо повторения одного и того же набора свойств для каждого селектора отдельно, их можно перечислить через запятую перед общим блоком стилей.
Есть и обратная сторона гибкости селекторов — слишком длинные и сложные цепочки вроде header nav ul li a становятся хрупкими: любое изменение структуры HTML ломает такой стиль. Более короткие селекторы, завязанные на понятные классы, обычно переживают изменения дизайна куда спокойнее.
Полный список типов селекторов с примерами разобран в справочнике по CSS-селекторам на MDN, там же можно посмотреть менее очевидные комбинаторы.
На практике удобное правило — начинать с самого простого селектора, который решает задачу, и усложнять только тогда, когда простого действительно не хватает. Соблазн сразу писать длинные точные цепочки понятен, но он почти всегда приводит к более хрупкому и труднее читаемому CSS в будущем.