Я читаю спецификацию в селектора атрибутов, но я не могу найти ничего, что говорит о разрешении пробела. Я предполагаю, что это разрешено в начале, до и после оператора, и в конце. Правильно ли это?
Каковы правила вокруг пробелов в селекторах атрибутов?
Ответ 1
Правила пробелов в селекторах атрибутов указаны в грамматике. Здесь Selectors 3 для селекторов атрибутов (некоторые токены, заменяемые их эквивалентами строк для иллюстрации; S*
представляет 0 или более пробельных символов):
attrib
: '[' S* [ namespace_prefix ]? IDENT S*
[ [ '^=' |
'$=' |
'*=' |
'=' |
'~=' |
'|=' ] S* [ IDENT | STRING ] S*
]? ']'
;
Конечно, грамматика не очень полезна для тех, кто хочет понять, как писать селектор атрибутов, поскольку он предназначен для тех, кто внедряет механизм селектора.
Здесь приведено простое английское объяснение:
Пробел перед селектором атрибутов
Это не рассматривается в вышеприведенной постановке, но первое очевидное правило заключается в том, что если вы прикрепляете селектор атрибутов к другому простому селектору или псевдоэлементу, не используйте пространство:
a[href]::after
Если вы это сделаете, пространство рассматривается как компилятор потомков, а универсальный селектор подразумевает селектор атрибутов и все, что может следуйте за ним. Другими словами, эти селекторы эквивалентны друг другу, но отличаются от вышеперечисленных:
a [href] ::after
a *[href] *::after
Пробел внутри селектора атрибутов
Если у вас есть пробелы в скобках и вокруг оператора сравнения, это не имеет значения; Я считаю, что браузеры, похоже, относятся к ним так, как будто их там не было (но я не тестировал их широко). Все они действительны в соответствии с грамматикой и, насколько я знаю, работают во всех современных браузерах:
a[href]
a[ href ]
a[ href="#" onclick="location.href='http://stackoverflow.com'; return false;" ]
a[href ^= "http://"]
a[ href ^= "http://" ]
(Очевидно, что нарушение ^
и =
с пробелом неверно.)
Если IE7 и IE8 правильно реализуют грамматику, они также смогут обрабатывать их все.
Если используется префикс пространства имен, между префиксом и именем атрибута не допускается пробел.
Это неверно:
unit[sh| quantity]
unit[ sh| quantity="200" ]
unit[sh| quantity = "200"]
Это верно:
unit[sh|quantity]
unit[ sh|quantity="200" ]
unit[sh|quantity = "200"]
Пробел внутри значения атрибута
Но обратите внимание на цитаты вокруг значений атрибутов выше; если вы их оставите, и вы попытаетесь выбрать что-то, чей атрибут имеет пробелы в своем значении, у вас есть синтаксическая ошибка.
Это неверно:
div[class=one two]
Это правильно:
div[class="one two"]
Это связано с тем, что значение некотируемого атрибута рассматривается как идентификатор, который не включает пробелы (по понятным причинам), тогда как цитируемое значение рассматривается как строка. Подробнее см. эту спецификацию.
Чтобы предотвратить такие ошибки, я настоятельно рекомендую всегда указывать значения атрибутов, будь то в HTML, XHTML (обязательно), XML (обязательно), CSS или jQuery (как только требуется).
Пробел после значения атрибута
Как и для селекторов 4, селектора атрибутов могут принимать флаги в форме идентификатора, появляющегося после значения атрибута. Пока что для чувствительность к регистру (а точнее, нечувствительность к регистру) был определен один флаг:
div[data-foo="bar" i]
Грамматика была обновлена таким образом:
attrib
: '[' S* attrib_name ']'
| '[' S* attrib_name attrib_match [ IDENT | STRING ] S* attrib_flags? ']'
;
attrib_name
: wqname_prefix? IDENT S*
attrib_match
: [ '=' |
PREFIX-MATCH |
SUFFIX-MATCH |
SUBSTRING-MATCH |
INCLUDE-MATCH |
DASH-MATCH
] S*
attrib_flags
: IDENT S*
На простом английском языке: если значение атрибута не цитируется (т.е. оно является идентификатором), требуется пробел между ним и attrib_flags
; в противном случае, если значение атрибута указано, то пробел является необязательным, но настоятельно рекомендуется для удобства чтения. Пробелы между attrib_flags
и закрывающей скобой необязательны, как всегда.