Именование атрибутов класса и идентификатора HTML — дефисы и подчеркивания

<div id="example-value"> or <div id="example_value">?

Этот сайт и Twitter используют первый стиль. Facebook и Vimeo — второе.

Какой из них вы используете и почему?


person Emanuil Rusev    schedule 08.11.2009    source источник
comment
Обе эти ссылки сейчас не работают   -  person Steve    schedule 22.04.2013


Ответы (8)


Используйте дефисы, чтобы обеспечить изоляцию между вашим HTML и JavaScript.

Почему? увидеть ниже.

Дефисы допустимы для использования в CSS и HTML, но не для объектов JavaScript.

Многие браузеры регистрируют HTML-идентификаторы как глобальные объекты в объекте окна/документа, в больших проектах это может стать настоящей проблемой.

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

Рассмотрим следующее:

message.js

message = function(containerObject){
    this.htmlObject = containerObject;
};
message.prototype.write = function(text){
    this.htmlObject.innerHTML+=text;
};

html

<body>
    <span id='message'></span>
</body>
<script>
    var objectContainer = {};
    if(typeof message == 'undefined'){
        var asyncScript = document.createElement('script');
        asyncScript.onload = function(){
            objectContainer.messageClass = new message(document.getElementById('message'));
            objectContainer.messageClass.write('loaded');
        }
        asyncScript.src = 'message.js';
        document.appendChild(asyncScript);
    }else{
        objectContainer.messageClass = new message(document.getElementById('message'));
        objectContainer.messageClass.write('loaded');
    }
</script>

Если браузер регистрирует HTML-идентификаторы как глобальные объекты, описанное выше не удастся, потому что сообщение не является «неопределенным», и он попытается создать экземпляр объекта HTML. Убедитесь, что в имени HTML-идентификатора есть дефис, чтобы предотвратить конфликты, подобные приведенному ниже:

message.js

message = function(containerObject){
    this.htmlObject = containerObject;
};
message.prototype.write = function(text){
    this.htmlObject.innerHTML+=text;
};

html

<body>
    <span id='message-text'></span>
</body>
<script>
    var objectContainer = {};
    if(typeof message == 'undefined'){
        var asyncScript = document.createElement('script');
        asyncScript.onload = function(){
            objectContainer.messageClass = new message(document.getElementById('message-text'));
            objectContainer.messageClass.write('loaded');
        }
        asyncScript.src = 'message.js';
        document.appendChild(asyncScript);
    }else{
        objectContainer.messageClass = new message(document.getElementById('message-text'));
        objectContainer.messageClass.write('loaded');
    }
</script>

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

Одно замечание: вы все еще можете получить доступ к объектам HTML через (например) объект окна, используя window['message-text'];

person Raatje    schedule 02.05.2012
comment
Я что-то не понимаю в вашем сообщении здесь, возможно, вы можете пояснить. Итак, вы говорите, что некоторые браузеры регистрируют идентификатор html как глобальные объекты и что, если вы поместите дефис в идентификатор, вы гарантируете, что не будет конфликта между этими автоматически сгенерированными объектами и объектами, которые вы создаете, потому что дефисы не разрешены . Но как тогда браузер создает эти объекты с дефисом, если дефисы не разрешены? похоже, что ему придется их раздеть, что может привести к конфликту имен. - person Dallas Caley; 28.03.2016
comment
@DallasCaley, если вы не видели, этот ответ был обновлением, вызывающим window['message-text']; - person Chris Marisic; 02.06.2016
comment
Ах, я думаю, я понял. Странно, что javascript не позволяет создать объект с дефисом в имени как самостоятельный объект, но позволит создать объект с дефисом в имени, если он создается как свойство другого объекта у которого нет тире в имени. - person Dallas Caley; 03.06.2016
comment
Этот пост на самом деле заставил меня переосмыслить свою позицию и почти на 100% согласиться с вами с позиции нет, это глупо, моя единственная оговорка касается вашей позиции по этому вопросу. Кажется очевидным, что каждый идентификатор должен иметь - в нем, чтобы предотвратить такая же проблема, если вы специально не хотите, чтобы она работала для некоторых конкретных идентификаторов. - person user254694; 18.05.2018

Я бы рекомендовал Руководство по стилю Google HTML/CSS.

В нем конкретно указано:

Разделяйте слова в именах идентификаторов и классов дефисом. Не объединяйте слова и аббревиатуры в селекторах с помощью каких-либо символов (включая отсутствие вообще), кроме дефисов, чтобы улучшить понимание и удобство сканирования.

/* Not recommended: does not separate the words “demo” and “image” */
.demoimage {}

/* Not recommended: uses underscore instead of hyphen */
.error_status {}

/* Recommended */
#video-id {}
.ads-sample {}
person Klas Mellbourn    schedule 20.09.2012
comment
Как насчет нотации BEM? - person Iulian Onofrei; 30.07.2014
comment
@IulianOnofrei, вы, конечно, можете использовать БЭМ, но он явно не строго соответствует Руководству по стилю Google. - person Klas Mellbourn; 01.09.2015
comment
хм, очень странно. Фреймворк GWT от Google использует верблюжий регистр. Проверьте эту строку кода ‹h1 id=appTitle›‹/h1› в следующем документе. gwtproject.org/doc/latest/tutorial/i18n.html - person karlihnos; 22.02.2017
comment
Google != автоматически верно. Часто так и есть, но просто быть Google недостаточно для оправдания. - person Craig Brett; 01.09.2017
comment
Это действительно плохая идея. Рано или поздно вам захочется использовать свое имя в языке программирования, который не поддерживает дефисы в именах переменных (в основном во всех), и тогда БУМ! Идиотские правила переименования. - person Timmmm; 18.11.2019

Это действительно сводится к предпочтениям, но то, что повлияет на вас в определенном направлении, может быть редактором, в котором вы кодируете. Например, функция автозаполнения в TextMate останавливается на дефисе, но видит слова, разделенные знаком подчеркивания, как одно слово. Таким образом, имена классов и идентификаторы с the_post работают лучше, чем the-post, при использовании его функции автозаполнения (Esc).

person Doug Neiner    schedule 07.01.2010
comment
вы правы, но в окружающих джунглях html это будет казаться гораздо более грязным - person Kamil Tomšík; 25.01.2011

Я считаю, что это полностью зависит от программиста. Вы также можете использовать camelCase, если хотите (но я думаю, что это будет выглядеть неуклюже).

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

person adamse    schedule 08.11.2009
comment
этот вопрос аналогичен и проверяет этот ответ stackoverflow.com/questions/70579/ - person Matt Smith; 08.11.2009

Любой пример вполне допустим, вы даже можете добавить в смесь ":" или "." в качестве разделителей в соответствии с спецификацией w3c. Я лично использую «_», если это имя состоит из двух слов, только из-за его сходства с пространством.

person Myles    schedule 08.11.2009
comment
Да, вы можете использовать двоеточие и точки для идентификаторов, но это хороший способ заставить человека, пишущего файл CSS, ненавидеть вас. - person Dave Markle; 08.11.2009
comment
Идентификатор HTML ZZ:ZZ должен быть экранирован как ZZ\00003AZZ (CSS2 и выше). - person McDowell; 08.11.2009
comment
Я не сказал, что это хорошая практика, я сказал, что она действительна. - person Myles; 08.11.2009
comment
Звучит как забавный способ заставить jQuery взорваться - person Mike Robinson; 07.01.2010

Я использую первый (раз-два), потому что он более удобочитаем. Для изображений я предпочитаю подчеркивание (btn_more.png). Camel Case (oneTwo) — еще один вариант.

person eozzy    schedule 07.01.2010

На самом деле некоторые внешние фреймворки (javascript, php) имеют трудности (ошибки?) с использованием hypen в именах идентификаторов. Я использую подчеркивание (как и 960grid), и все отлично работает.

person DavidHavl    schedule 24.01.2011
comment
Какие? В любом случае, читабельность кода гораздо важнее. - person Kamil Tomšík; 25.01.2011

Я бы предложил подчеркивание в основном из-за побочного эффекта javascript, с которым я сталкиваюсь.

Если бы вы ввели приведенный ниже код в адресную строку, вы бы получили сообщение об ошибке: «example-value» не определено. Если бы div был назван символом подчеркивания, это сработало бы.

javascript:alert(example-value.currentStyle.hasLayout);
person jgreep    schedule 07.01.2010
comment
Это должен быть document.getElementById("example-value"), который будет работать нормально. - person Chuck; 07.01.2010
comment
У меня возникает аналогичная проблема с ASP.NET MVC при указании значения атрибута в параметре HtmlAttributes вспомогательных функций Html. - person Matthijs Wessels; 28.02.2011