В чем разница между таргетингом на класс с помощью «.class» или «*[class ~=box]» в css?

#css #css-selectors

#css #css-селекторы

Вопрос:

Допустим, у меня есть html-элемент с классом box: <p class="box alert">Content here</p>

Недавно я узнал о способе таргетинга на элементы в CSS, поэтому, если я хочу выбрать любой элемент с классом box, я мог бы использовать это: *[class~=box] {border: 2px solid grey;}

И мне интересно, разве это буквально не то же самое, что просто таргетинг на элемент по имени класса? Или я неправильно понял? .box {border: 2px solid grey;}

Если это одно и то же, в каких ситуациях уместно использовать второй метод, а не первый?

Комментарии:

1. Оба эквивалентны, но . обозначение является распространенным способом сделать это. Пожалуйста, не используйте *[class~=box] 😉

2. Теперь я понимаю, вероятно, просто было не очень хорошей идеей использовать «class» здесь в качестве примера, вот что меня смутило. Это намного понятнее, например, с другими атрибутами. Спасибо за все ваши ответы!

Ответ №1:

Селектор атрибутов на самом деле не предназначен для классов, он предназначен, например, для других атрибутов в элементах a[href*="google"] , но да, вы можете стилизовать элементы подобным образом, и это определенно будет считаться антишаблоном.

Хотя .classname и [class~="classname"] оформляли бы одни и те же элементы, специфика CSS этих селекторов вычислялась бы по-разному — честно говоря, я не совсем уверен, но *[class~="classname"] могла бы выиграть с .classname , и это то, о чем должен знать человек, работающий со стилями, которые были написаны подобным образом.

Комментарии:

1. На случай, если вы хотите сравнить производительность . Partial attribute matching vs Single class — обязательно протестируйте это в нескольких браузерах. — С точки зрения стиля кода .classname всегда лучший выбор.

Ответ №2:

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

Практическое различие

С практической точки зрения, селектор классов гораздо более удобочитаем и понятен. Это также намного эффективнее, поскольку браузеры обрабатывают классы иначе, чем другие атрибуты, для запросов CSS и DOM. Селектор атрибута в целом имеет больше смысла для любого другого атрибута, который не является a class , когда вы хотите выбрать по одному значению из «списка слов, разделенных пробелами, одно из которых в точности соответствует значению» (спецификация MDN).

Например, если у вас есть data атрибут с несколькими возможными значениями на выбор, вот так:

 <div data-colors="blue">
<div data-colors="yellow blue">
<div data-colors="red blue green">
  

Селектор атрибута [data-colors~=blue] выбрал бы все три элемента, независимо от любых других значений в атрибуте.

Историческая разница

Исторически селектор класса .box является частью исходной спецификации CSS (.т.е. «CSS 1»). Это означает, что этот селектор поддерживается любым браузером прошлого и настоящего. С другой стороны, селектор атрибутов [class~=box] является лишь частью второй итерации спецификации CSS (т. Е. «CSS2») и поэтому поддерживается не всеми возможными браузерами; хотя вам пришлось бы вернуться к Internet Explorer 6, чтобы столкнуться с проблемами с этим селектором.

Ответ №3:

Одним из важных отличий является использование некоторых специальных имен с вашими классами.

Вот пример для иллюстрации:

 .box {
  height:50px;
  background:red;
  margin:5px;
}

.80% {
  width:80%;
}

.50% {
  width:50%;
}  
 <div class="box 80%"></div>
<div class="box 50%"></div>  

В приведенном выше примере ничего не произойдет, потому что нам нужно экранировать число и % внутри селектора, но с помощью селектора атрибутов это просто:

 .box {
  height:50px;
  background:red;
  margin:5px;
}

[class~="80%"] {
  width:80%;
}

[class~="50%"] {
  width:50%;
}  
 <div class="box 80%"></div>
<div class="box 50%"></div>  

Для первого вам нужно написать следующее, что не является тривиальным:

 .box {
  height:50px;
  background:red;
  margin:5px;
}

.38 0% {
  width:80%;
}

.35 0% {
  width:50%;
}  
 <div class="box 80%"></div>
<div class="box 50%"></div>  

Ответ №4:

Оба будут иметь точно такой же результат, так что *[class~="classname"] это эквивалентно .classname , только выбор производится с использованием class атрибута. Смотрите attribute selector, чтобы получить больше информации об этом синтаксисе.

 .classname {
  color: blue;
}

*[class~="classname"] {
  color: red;
}  
 <p class="classname">Content here</p>  

 *[class~="classname"] {
  color: red;
}

.classname {
  color: blue;
}  
 <p class="classname">Content here</p>