Недопустимый селектор CSS заставляет исключить правило: что такое обоснование?

Я больше ищу ссылки на рассылку списков и т. Д., А не спекуляцию.

Может ли кто-нибудь помочь мне выяснить обоснование приведенных правил обработки ошибок из спецификации CSS Selectors Level 3 .

Пользовательские агенты должны соблюдать правила обработки ошибок синтаксического анализа:

  • недействителен простой селектор, содержащий незанятый префикс пространства имен
  • селектор, содержащий недопустимый простой селектор, недопустимый комбинатор или недопустимый токен.
  • группа селекторов, содержащих недопустимый селектор, недействительна.

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

У меня было следующее правило:

#menu li.last, #menu li:last-child { ... } 

Чтобы компенсировать отсутствие поддержки IE8 последнего поколения, я использовал class и подгонку JavaScript. Однако это не сработало, потому что IE8 соответствует спецификации CSS при обработке ошибок и отбрасывает все правило, потому что оно не распознает один селектор. Это можно устранить, разделив два селектора на отдельные правила.

Почему это желательно? Почему спецификация не позволяет просто отказаться от непризнанного селектора, но сохранить остальную часть правила?

Я хотел бы знать обоснование, поскольку правила в настоящее время кажутся противоречивыми.

Почему это желательно? Почему спецификация не позволяет просто отказаться от непризнанного селектора, но сохранить остальную часть правила?

Короткий ответ заключается в том, что для реализаций слишком сложно понять, что именно составляет «остальную часть правила» (или «остальную часть списка селекторов»), не получив его неправильно и непреднамеренно испортив макеты, а также для обеспечения согласованности в обработке ошибок и последующей совместимости с будущими спецификациями.


Я предоставлю свой длинный ответ ссылкой на другой ответ , касающийся обработки недействительных селекторов. Комментарий к этому ответу прямо указывает на раздел 4.1.7 спецификации CSS2.1 для обработки ошибок в селекторах в наборах правил, в которых упоминается запятая в селекторах. Я думаю, что это суммирует это довольно красиво:

CSS 2.1 дает особое значение для запятой (,) в селекторах. Однако, поскольку неизвестно, может ли запятая получить другие значения в будущих обновлениях CSS, весь оператор следует игнорировать, если в селекторе есть ошибка, хотя остальная часть селектора может выглядеть разумно в CSS 2.1.

Хотя сама запятая по-прежнему означает группировку двух или более селекторов в отношении селекторов, оказывается, что в селекторах 4 появляются новые функциональные псевдоclassы, которые принимают группы селектора (или списки выбора) в качестве аргументов, например :matches() (it даже изменения :not() поэтому он принимает список, что делает его похожим на :matches() , тогда как на уровне 3 он принимает только один простой селектор).

Это означает, что вы не только найдете разделенные запятыми группы селекторов, связанные с правилами, но и начнете их находить в функциональных псевдоclassах (обратите внимание, что это только в таблице стилей; вне CSS, селектора могут появляться в JavaScript-код, используемый библиотеками-селекторами и собственным API-интерфейсом Selectors ).

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

В качестве примера рассмотрим следующее правило, селектор которого действителен на уровне 4, но не на уровне 3, взятом из этого вопроса :

 #sectors > div:not(.alpha, .beta, .gamma) { color: #808080; background-color: #e9e9e9; opacity: 0.5; } 

Наивный парсер, который не понимает Selectors 4, может попытаться разделить его на три отдельных селектора, которые используют один и тот же блок объявлений, вместо одного селектора с псевдоclassом, который принимает список, на основе только запятых:

 #sectors > div:not(.alpha .beta .gamma) 

Если он просто отбрасывает первый и последний селектор, которые явно недействительны, оставляя второй селектор действительным, должен ли он попытаться применить правило к любым элементам с beta classа? Это явно не то, что автор намеревается сделать, поэтому, если браузер сделает это, он сделает что-то неожиданное для этого макета . Отбрасывая правило с помощью недействительного селектора, макет выглядит немного скромнее , но это более упрощенный пример; правила с стилями изменения макета могут вызвать еще большие проблемы при неправильном применении.

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

  • Не зная, где заканчивается сложный селектор
  • Не зная, где заканчивается список селекторов
  • Не зная, где начинается блок объявления
  • Комбинация вышеуказанного

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

В случае, казалось бы, хорошо сформированных селекторов, которые непризнаны, например :last-child как псевдоclass в вашем примере, спецификация не делает различий между непризнанными селекторами и селекторами, которые просто искажены. Оба результата приводят к ошибке синтаксического анализа. В том же разделе, на который вы ссылаетесь:

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

И, сделав это заявление о :last-child я предполагаю, что браузер способен анализировать один двоеточие, за которым следует произвольный идентификатор в качестве псевдо-classа; на самом деле вы не можете предположить, что реализация будет знать для синтаксического анализа :last-child как псевдоclass, или что-то вроде :lang() или :not() с функциональной нотацией, поскольку функциональные псевдоclassы не появлялись до CSS2.

Селекторы определяют определенный набор известных псевдоclassов и псевдоэлементов, имена которых, скорее всего, жестко запрограммированы в каждой реализации. Большинство наивных парсеров имеют всю нотацию для каждого псевдоclassа и псевдоэлемента, включая одиночный / двойной двоеточие (ы), жестко закодированные (я не удивлюсь, если основные браузеры действительно делают это с :before :after , :first-letter и :first-line в качестве специального случая ). Итак, что может показаться псевдоclassом для одной реализации, может быть очень хорошо сплетено к другому.

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


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

Я должен также упомянуть, что некоторые механизмы компоновки ведут себя по-разному, например, WebKit игнорируют селектора, отличные от WebKit-prefixed, в правиле, применяя свои собственные префиксы, в то время как другие браузеры полностью игнорируют это правило (вы можете найти больше примеров в Stack Overflow, вот немного другой ). В каком-то смысле вы можете сказать, что WebKit обходит правило так, как оно есть, хотя оно пытается рационально разделить группы селекторов, разделенных запятыми, несмотря на эти префиксы.

Я не думаю, что у рабочей группы есть веские причины изменить это поведение. На самом деле, во всяком случае, у них есть веская причина не менять его , и это потому, что сайты уже много лет полагаются на это поведение. Раньше у нас были селекторные хаки для фильтрации старых версий IE; сегодня у нас есть префиксы для фильтрации других браузеров. Эти хаки все полагаются на одно и то же поведение некоторых браузеров, отбрасывающих правила, которые они не распознают, с другими браузерами, применяющими их, если они считают, что они верны, например, распознавая префиксы (или бросая только нераспознанные из них, как это делает WebKit). Сайты могут ломаться в новых версиях этих браузеров, если это правило должно измениться, что абсолютно невозможно в такой разнообразной (читаемой: fragmentированной) Web, как наша.

По состоянию на апрель 2013 года в телеконференции было решено, что такое поведение остается неизменным по той причине, о которой я уже говорил выше:

    - ПОСТАНОВИЛИ: не принимать недействительность MQ-стиля для селекторов
                из-за проблем с Web-compat.

Недействительность в стиле запроса в отношении сообщений относится к недопустимым запросам мультимедиа в списке, разделенном запятыми, не нарушающем все правило @media .

Interesting Posts

Ограничить доступ для пользователей в Windows 7

Как автоматически заставить компьютер спать и просыпаться?

Почему все пользовательские агенты браузеров начинаются с «Mozilla /»?

Невозможно файлы TFTP clonezilla с TFTP-сервера WDS во время загрузки PXE

Свойство ошибок модели Ember Data (DS.Errors) не заполняется

Размер шрифта слишком большой, чтобы соответствовать кешу

Как сопоставить любой символ в нескольких строках в регулярном выражении?

Сравнение агрегации MongoDB: group (), $ group и MapReduce

Не удается установить гостевые дополнения с помощью VirtualBox, гостевой ОС Ubuntu, операционной системы Win7

Список доступных сетевых адаптеров в Linux

C # клавиша со стрелкой для консольного приложения

Вложенность в Parallel.ForEach

Запустить приложение, совместимое только с 32-разрядной на 64-разрядной машине

Java: получение текущей даты и времени с сервера не системные часы

В чем разница между Integer и int в Java?

Давайте будем гением компьютера.