Могу ли я использовать несуществующие классы CSS?
У меня есть таблица, где я показываю / скрываю полный столбец с помощью jQuery через класс CSS, который не существует:
<table>
<thead>
<tr>
<th></th>
<th class="target"></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td class="target"></td>
<td></td>
</tr>
<tr>
<td></td>
<td class="target"></td>
<td></td>
</tr>
</tbody>
</table>
С помощью этого DOM я могу сделать это в одну строку через jQuery: $('.target').css('display','none');
Это прекрасно работает, но допустимо ли использовать классы CSS, которые не определены? Должен ли я создать пустой класс для него?
<style>.target{}</style>
Есть ли побочные эффекты или есть лучший способ сделать это?
13 ответов
"Класс CSS" - это неправильное название; class
является атрибутом (или свойством в терминах сценариев), который вы назначаете элементам HTML. Другими словами, вы объявляете классы в HTML, а не в CSS, поэтому в вашем случае "целевой" класс на самом деле существует для этих конкретных элементов, и ваша разметка совершенно верна.
Это не обязательно означает, что вам нужно объявить класс в HTML, прежде чем вы сможете использовать его в CSS. Смотрите комментарий Руаха. То, является ли селектор допустимым, полностью зависит от синтаксиса селектора, и CSS имеет свой собственный набор правил для обработки ошибок синтаксического анализа, ни одно из которых не касается разметки вообще. По сути, это означает, что HTML и CSS полностью независимы друг от друга в аспекте достоверности. 1
Как только вы поймете это, станет ясно, что нет побочного эффекта .target
правило в вашей таблице стилей. 2 Когда вы присваиваете классы своим элементам, вы можете ссылаться на эти элементы по этим классам либо в таблице стилей, либо в скрипте, либо в обоих. Ни один из них не зависит от другого. Вместо этого они оба ссылаются на разметку (или, точнее, ее представление DOM). Этот принцип применяется даже в том случае, если вы используете JavaScript для применения стилей, как вы делаете это в своей строчке jQuery.
Когда вы пишете правило CSS с помощью селектора классов, все, что вы говорите, это "Я хочу применить стили к элементам, которые принадлежат этому классу". Точно так же, когда вы пишете скрипт для извлечения элементов по определенному имени класса, вы говорите: "Я хочу делать вещи с элементами, которые принадлежат этому классу". Есть ли элементы, которые принадлежат к рассматриваемому классу, - это отдельная проблема.
1 По этой же причине селектор идентификатора CSS сопоставляет все элементы с заданным идентификатором независимо от того, появляется ли этот идентификатор ровно один раз или несколько раз (что приводит к несоответствующему документу HTML).
2 Единственная ситуация, в которой я знаю, где такое пустое правило CSS необходимо, - это когда некоторые браузеры отказываются применять некоторые другие правила должным образом в результате ошибки; создание пустого правила приведет к тому, что эти другие правила будут применены по какой-то причине. Посмотрите этот ответ для примера такой ошибки. Однако это на стороне CSS и, следовательно, не должно иметь ничего общего с разметкой.
Нет вредных эффектов при использовании классов, у которых нет стилей. На самом деле, часть полезности CSS в том, что он не связан с разметкой и может стилизовать или не стилизовать элементы / классы / и т. Д. по мере необходимости.
Не думайте о них как о "классах CSS". Думайте о них как о "классах", которые CSS также использует в случае необходимости.
Согласно спецификации HTML5:
Атрибут класса должен иметь значение, представляющее собой набор разделенных пробелами токенов, представляющих различные классы, к которым принадлежит элемент.... Нет никаких дополнительных ограничений на токены, которые авторы могут использовать в атрибуте класса, но авторам рекомендуется использовать значения, которые описывают природу контента, а не значения, которые описывают желаемое представление контента.
Также в версии 4:
Атрибут class имеет несколько ролей в HTML:
- В качестве селектора таблицы стилей (когда автор желает назначить информацию о стиле набору элементов).
- Для обработки общего назначения пользовательскими агентами.
Ваш вариант использования подпадает под второй сценарий, что делает его законным примером использования атрибута класса.
Вы можете использовать класс, который не имеет стилей, это полностью допустимый HTML.
Класс, на который есть ссылка в файле CSS, не является определением класса, он используется как правило селектора для целей стилизации.
Когда вы используете имя класса в JavaScript, он не смотрит на CSS, чтобы найти этот класс. Это выглядит прямо в коде HTML.
Все, что требуется, это чтобы имя класса было в HTML. Это не должно быть в CSS.
Фактически, многие люди думают, что на самом деле хорошая идея - использовать отдельные классы с CSS и Javascript, поскольку это позволяет вашим дизайнерам и программистам работать независимо друг от друга, не мешая друг другу, используя классы друг друга.
(обратите внимание, что приведенный выше абзац, очевидно, более применим для более крупных проектов, поэтому не думайте, что вам придется идти до такой крайности, если вы работаете самостоятельно; я упомянул это, чтобы подчеркнуть, что эти два понятия могут быть совершенно разными)
Вы можете использовать CSS- классы, не используя его, но я предлагаю, чтобы, если вы добавляете CSS-классы только для кода JavaScript/jQuery, используйте префикс js-YourClassName
поэтому разработчики внешнего интерфейса никогда не используют эти классы для стилизации элементов. Они должны понимать, что эти классы могут быть удалены в любое время.
Как только вы добавите класс в свой HTML, класс будет определен, так что ваше решение вполне подойдет
Нет необходимости определять классы CSS в вашей таблице стилей. Это должно работать просто отлично. Однако добавление этого не повредит.
Одна вещь, о которой никто здесь полностью не упомянул, - это то, что JavaScript (в данном случае с помощью jQuery) не может напрямую изменять каскадную таблицу стилей документа. JQuery-х css()
метод просто изменяет соответствующий набор элементов style
имущество. CSS и JavaScript совершенно не связаны в этом аспекте.
$('.target').css('display','none');
не меняет ваш .target { }
CSS декларация вообще. Вместо этого здесь произошло то, что любой элемент с class
из "цели" теперь выглядит примерно так:
<element class="target" style="display:none;"></element>
Есть ли побочные эффекты, вызванные отсутствием предварительного определения правила стиля CSS? Никак нет.
Есть лучший способ сделать это? По производительности, да, есть!
Как можно улучшить производительность?
Вместо того, чтобы напрямую изменять style
каждого элемента, вместо этого вы можете предварительно определить новый класс и добавить его в соответствующие элементы, используяaddClass()
(другой метод jQuery).
На основе этого уже существующего JSPerf, который сравнивает css()
с addClass()
, мы это видим addClass()
на самом деле намного быстрее:
Как мы можем реализовать это сами?
Во-первых, мы можем добавить в нашу новую декларацию CSS:
.hidden {
display: none;
}
Ваш HTML-код останется прежним, этот предопределенный класс просто используется для дальнейшего использования.
Теперь мы можем изменить JavaScript для использования addClass()
вместо:
$('.target').addClass('hidden');
При запуске этого кода, вместо непосредственного изменения style
свойство каждого из ваших соответствующих "целевых" элементов, теперь будет добавлен этот новый класс:
<element class="target hidden"></element>
С новым "скрытым" классом этот элемент будет наследовать стили, объявленные в вашем CSS, и ваш элемент больше не будет отображаться.
Как упоминалось многими другими, да, использование классов без назначенного CSS совершенно допустимо, и вместо того, чтобы думать о них как о "классах CSS", вы должны просто признать семантику класса и ID как группы и отдельные элементы соответственно.
Я хотел бы внести свой вклад, поскольку чувствовал, что важный момент не был поднят на примере. Если вам когда-либо нужно визуально манипулировать элементами переменной длины (в данном случае вы используете строки таблицы), то всегда имеет смысл признать, что затраты на это с помощью Javascript могут быть очень дорогими (например, если у вас есть тысячи строк).
В этой ситуации, скажем, мы знаем, что столбец 2 всегда может быть скрыт (это сознательная функция вашей таблицы), тогда имеет смысл разработать стиль CSS для обработки этого варианта использования.
table.target-hidden .target { display: none; }
Тогда вместо того, чтобы использовать JS для обхода DOM, находящего N элементов, нам просто нужно переключить класс на один (наша таблица).
$("table").addClass("target-hidden")
При назначении таблице идентификатора это будет еще быстрее, и вы можете просто обратиться к столбцу, используя :nth-child
селектор, который уменьшит вашу разметку, но я не могу комментировать эффективность. Еще одна причина, по которой я это делаю, заключается в том, что я ненавижу встроенное моделирование и сделаю все возможное, чтобы искоренить его!
Это не будет иметь эффекта, если вы примените класс к элементу HTML, и этот класс не определен в CSS. Это обычная практика, и, как сказал Аамир африди, если вы используете классы только для js-целей, то хорошей практикой является добавление к ним префиксов js- .
Это справедливо не только для calsses, но и для атрибута id элементов html.
Нет проблем с использованием классов для простого запроса элементов. Я имел обыкновение давать такие имена классов sys-
префикс (например, я назову ваш класс sys-target
) чтобы отличить их от классов, используемых для укладки. Это было соглашение, используемое некоторыми разработчиками Microsoft в прошлом. Я также заметил растущую практику использования js-
префикс для этого.
Если вам неудобно использовать классы для целей, отличных от стиля, я рекомендую использовать плагин jQuery Role.js, который позволяет вам достичь той же цели с помощью role
атрибут, так что вы можете написать свою разметку как <td role="target">
и запросить его, используя $("@target")
, Страница проекта имеет хорошее описание и примеры. Я использую этот плагин для больших проектов, потому что мне действительно нравится хранить классы только для стилизации.