Могу ли я использовать несуществующие классы CSS?

260

У меня есть таблица, где я показываю / скрываю полный столбец с помощью 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>

Есть ли побочные эффекты или есть лучший способ сделать это?

totymedli
источник
9
Я не вижу в этом ничего плохого, хотя я бы сделал это частью таблицы стилей, если бы вообще возможно, вместо того чтобы использовать .cssстили, установленные с помощью .css, очень трудно переопределить, не вызывая других проблем, поэтому я стараюсь их избегать.
Кевин Б.
8
как примечание, которое вы можете использовать .toggle(), оно немного короче в вашем коде.
Математический чиллер
4
В Visual Studio + ReSharper, если вы используете класс, который не определен, он выдаст вам предупреждение, что полезно, если у меня просто опечатка, но это раздражает в подобных ситуациях. В этом случае у вас есть выбор: добавить пустой стиль или отключить предупреждение (или просто игнорировать его) - лично я просто добавляю пустой стиль. Я не знаю, ведут ли себя другие IDE так же.
Джо Энос
8
Это не только возможно, но и явно рекомендуется некоторыми. Так как ваш targetдля целей JavaScript, в многих людей используют префикс js-для таких классов, то есть js-target. КСТАТИ: Цель является своего рода плохим именем;) Для дальнейшего чтения см .: philipwalton.com/articles/decoupling-html-css-and-javascript
k0pernikus
1
stackoverflow.com/questions/2832117/… является более или менее дубликатом этого, без заблуждения.
ничего1

Ответы:

491

«CSS класс» - это неправильное название; classявляется атрибутом (или свойством в терминах сценариев), который вы назначаете элементам HTML. Другими словами, вы объявляете классы в HTML, а не CSS, поэтому в вашем случае класс «мишень» делает на самом деле существует на тех конкретных элементов, и разметка вполне допустимо , как это.

Это не обязательно означает, что вам нужно объявить класс в HTML, прежде чем вы сможете использовать его в CSS. Смотрите комментарий Руаха. То, является ли селектор допустимым, полностью зависит от синтаксиса селектора , и CSS имеет свой собственный набор правил для обработки ошибок синтаксического анализа , ни одно из которых не касается разметки вообще. По сути, это означает, что HTML и CSS полностью независимы друг от друга в аспекте достоверности. 1

Как только вы это поймете, станет ясно, что нет побочного эффекта от не определения .targetправила в вашей таблице стилей. 2 Когда вы присваиваете классы своим элементам, вы можете ссылаться на эти элементы по этим классам либо в таблице стилей, либо в скрипте, либо в обоих. Ни один из них не зависит от другого. Вместо этого они оба ссылаются на разметку (или, точнее, ее представление DOM). Этот принцип применяется даже в том случае, если вы используете JavaScript для применения стилей, как вы делаете это в своей строчке jQuery.

Когда вы пишете правило CSS с помощью селектора классов, все, что вы говорите, это «Я хочу применить стили к элементам, которые принадлежат этому классу». Точно так же, когда вы пишете скрипт для извлечения элементов по определенному имени класса, вы говорите: «Я хочу делать вещи с элементами, которые принадлежат этому классу». Есть ли элементы, которые принадлежат к рассматриваемому классу, - это отдельная проблема.


1 Именно поэтому селектор CSS ID соответствует всем элементы с данным идентификатором, независимо от того, появляется ли идентификатор ровно один раз или несколько раз (что приводит к несоответствующему документу HTML).

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

BoltClock
источник
5
Мне понадобилось много времени, чтобы понять, что классы не имеют ничего общего с CSS. Но примерно в то же время все осознали, и микроформаты пришли вместе.
Конрад Рудольф
13
+1, хотя этот ответ может быть ошибочно принят за то, что CSS может ссылаться только на классы, которые на самом деле встречаются в HTML. На самом деле довольно часто сайт использует CSS на всех страницах, хотя некоторые классы, на которые он ссылается, появляются не на каждой странице. (Например, сайт может иметь собственный стиль для внешних ссылок a.extlinkили еще что-то, даже если некоторые страницы не содержат внешних ссылок.)
ruakh
1
@ruakh: Отлично, спасибо. Я не мог найти способ вписать его в свой первоначальный краткий ответ, не отклоняясь от темы, но я вижу, как использование термина «зависимость» могло создать такое впечатление, поэтому я немного его изменил. Тем не менее, я добавил сноску, ссылающуюся на ваш комментарий, а также уточняю дальше.
BoltClock
66

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

Не думайте о них как о «классах CSS». Думайте о них как о «классах», которые CSS также использует, если это необходимо.

Дэвид
источник
11
+1 за «Не думайте о них как о« классах CSS ». Думайте о них как о «классах», которые CSS также использует, если это необходимо »
laike9m
48

Согласно спецификации HTML5 :

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

Также в версии 4 :

Атрибут class имеет несколько ролей в HTML:

  • В качестве селектора таблицы стилей (когда автор желает назначить информацию о стиле набору элементов).
  • Для обработки общего назначения пользовательскими агентами.

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

Виталий Федоренко
источник
13
+1 за цитирование соответствующих спецификаций. Я забыл сделать это много.
BoltClock
40

Вы можете использовать класс без стилей, это полностью допустимый HTML.

Класс, на который есть ссылка в файле CSS, не является определением класса, он используется в качестве правила селектора в целях стилизации.

односложный
источник
25

Когда вы используете имя класса в JavaScript, он не смотрит на CSS, чтобы найти этот класс. Это выглядит прямо в коде HTML.

Все, что требуется, это чтобы имя класса было в HTML. Это не должно быть в CSS.

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

(обратите внимание, что приведенный выше абзац, очевидно, более применим к более крупным проектам, поэтому не думайте, что вам придется идти до такой степени, если вы работаете самостоятельно; я упомянул это, чтобы подчеркнуть, что эти два аспекта могут быть совершенно разными )

Spudley
источник
13

Вы можете использовать CSS- классы, не используя их, но я предлагаю, чтобы, если вы добавляете CSS-классы только для кода JavaScript / jQuery, используйте префикс, js-YourClassNameчтобы разработчики внешнего интерфейса никогда не использовали эти классы для стилизации элементов. Они должны понимать, что эти классы могут быть удалены в любое время.

Аамир Африди
источник
10

В тот момент, когда вы добавите класс в свой HTML, класс будет определен, так что ваше решение вполне подойдет

koningdavid
источник
7
Использование класса в HTML не определяет его. Скорее, определение не имеет значения: штраф за использование неопределенных классов отсутствует.
JAL
10

Нет необходимости определять классы CSS в вашей таблице стилей. Это должно работать просто отлично. Однако добавление этого не повредит.

Rameez
источник
Я не говорю, чтобы добавить эти стили, это до него, если он хочет, если он планирует поддержать эти стили, то почему бы и нет? В любом случае спасибо за ненужное голосование вниз
Rameez
Вы сказали "это ... не навредит", но в конечном итоге это будет.
Павло
да, это не повредит. если у него есть чувства, чтобы добавить эти пустые стили, то, очевидно, у него будут чувства, чтобы управлять ими. Очевидно, что я не буду добавлять .. ни я не советую добавлять.
Rameez
8

Одна вещь, о которой никто здесь полностью не упомянул, - это то, что JavaScript (в данном случае с помощью jQuery) не может напрямую изменять каскадную таблицу стилей документа. css()Метод jQuery просто изменяет соответствующий набор элементовstyle свойство . CSS и JavaScript совершенно не связаны в этом аспекте.

$('.target').css('display','none');не меняет ваше .target { }объявление CSS вообще. Вместо этого здесь произошло то, что любой элемент с class«target» теперь выглядит примерно так:

<element class="target" style="display:none;"></element>

Есть ли побочные эффекты, вызванные отсутствием предварительного определения стиля CSS? Никак нет.

Есть лучший способ сделать это? По производительности, да, есть!

Как можно улучшить производительность?

Вместо непосредственного изменения styleкаждого элемента, вместо этого вы можете предварительно определить новый класс и добавить его в соответствующие элементы, используяaddClass() (другой метод jQuery).

На основе этого ранее существующего JSPerf который сравнивается css()с addClass(), мы видим, что addClass()на самом деле он намного быстрее:

css () против addClass ()

Как мы можем реализовать это сами?

Во-первых, мы можем добавить в нашу новую декларацию CSS:

.hidden {
    display: none;
}

Ваш HTML-код останется прежним, этот предопределенный класс просто используется для дальнейшего использования.

Теперь мы можем изменить JavaScript для использования addClass() вместо:

$('.target').addClass('hidden');

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

<element class="target hidden"></element>

С новым «скрытым» классом этот элемент унаследует стили, объявленные в вашем CSS, и ваш элемент больше не будет отображаться.

Джеймс Доннелли
источник
Хороший совет. Существует редко веская причина использовать .css()вместо переключения классов IMO.
BoltClock
6

Как уже упоминалось многими другими, да, использование классов без назначенного CSS совершенно допустимо, и вместо того, чтобы думать о них как о «классах CSS», вы должны просто признать семантику класса и ID как группы и отдельные элементы соответственно.

Я хотел внести свой вклад, поскольку чувствовал, что важный момент не был поднят на примере. Если вам когда-либо нужно визуально манипулировать элементами переменной длины (в данном случае вы используете строки таблицы), то всегда имеет смысл признать, что затраты на это с помощью Javascript могут быть очень дорогими (например, если у вас есть тысячи строк).

В этой ситуации предположим, что мы знаем, что столбец 2 всегда может быть скрыт (это сознательная функция вашей таблицы), тогда имеет смысл разработать стиль CSS для обработки этого варианта использования.

table.target-hidden .target { display: none; }

Тогда вместо того, чтобы использовать JS для обхода DOM, находящего N элементов, нам просто нужно переключить класс на один (наша таблица).

$("table").addClass("target-hidden")

При назначении таблице идентификатора это будет еще быстрее, и вы даже можете просто обратиться к столбцу, используя :nth-childселектор, который еще больше уменьшит вашу разметку, но я не могу комментировать эффективность. Еще одна причина для этого заключается в том, что я ненавижу встроенное моделирование и сделаю все возможное, чтобы искоренить его!

Ян Кларк
источник
1
+1 за «группы и отдельные элементы» и за эффективное использование структуры документа
deltab
5

Это не будет иметь эффекта, если вы примените класс к элементу HTML, и этот класс не определен в CSS. Это обычная практика, и, как сказал Аамир африди, если вы используете классы исключительно для js, то хорошей практикой будет ставить перед ними префикс js-.

Это справедливо не только для calsses, но и для атрибута id элементов html.

Альтаф Хуссейн
источник
4

Нет никаких проблем с использованием классов для простого запроса элементов. Я имел обыкновение давать таким именам классов sys-префикс (например, я назову ваш класс sys-target), чтобы отличать их от классов, используемых для стилизации. Это было соглашение, используемое некоторыми разработчиками Microsoft в прошлом. Я также заметил растущую практику использования js-префикса для этой цели.

Если вам неудобно использовать классы для целей, отличных от стиля, я рекомендую использовать плагин jQuery Role.js, который позволяет вам достичь той же цели, используяrole атрибута, поэтому вы можете написать свою разметку как <td role="target">и запросить ее, используя $("@target"). Страница проекта имеет хорошее описание и примеры. Я использую этот плагин для больших проектов, потому что мне действительно нравится хранить классы только для стилизации.

Ашраф Сабри
источник
3

Обратитесь к движку проверки jQuery . Даже там мы также используем несуществующие классы, чтобы добавить правила проверки к атрибутам HTML . Так что нет ничего плохого в использовании классов, которые на самом деле не объявлены в таблице стилей.

dhruvin
источник