El selector CSS no válido hace que la regla se elimine: ¿ Cuál es la razón?


Estoy buscando más enlaces a discusiones de listas de correo, etc. en lugar de especulaciones.

¿Alguien puede ayudarme a averiguar la razón detrás de las reglas de manejo de errores citadas de la especificación CSS Selectores Nivel 3.

Los agentes de usuario deben observar las reglas para manejar los errores de análisis:

  • un selector simple que contiene un prefijo de espacio de nombres no declarado no es válido
  • un selector que contiene un selector simple inválido, un combinador inválido o un token no válido no es válido.
  • un grupo de selectores que contiene un selector no válido no es válido.

Especificaciones la reutilización de selectores debe definir cómo manejar los errores de análisis. (En el caso de CSS, se elimina toda la regla en la que se utiliza el selector.)

Tenía la siguiente regla:

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

Para compensar la falta de IE8 de manutención del último hijo, utilicé una clase y una cuña JavaScript. Sin embargo, esto no funcionó porque IE8 cumple con el CSS spec en el manejo de errores, y descarta toda la regla porque no reconoce un selector. Esto se puede arreglar separando los dos selectores en reglas individuales.

¿Por qué es deseable? ¿Por qué la especificación no sugiere simplemente descartar el selector no reconocido, pero mantener el resto de la regla?

Me gustaría conocer la razón, ya que las reglas actualmente parecen contra-intuitivas.

Author: canon, 2012-12-11

1 answers

¿Por qué es deseable? ¿Por qué la especificación no sugiere simplemente descartar el selector no reconocido, pero mantener el resto de la regla?

La respuesta corta es porque sería demasiado difícil para las implementaciones averiguar qué constituye exactamente "el resto de la regla "(o" el resto de la lista de selectores " para el caso) sin equivocarse y desordenar inadvertidamente los diseños, así como para la coherencia en el manejo de errores, y compatibilidad con especificaciones futuras.


Prepararé mi respuesta larga con un enlace a otra respuesta mía, sobre el manejo de selectores no válidos. Un comentario sobre esa respuesta apunta directamente a la sección 4.1.7 de la especificación CSS2.1 sobre el tratamiento de errores en selectores dentro de conjuntos de reglas, que menciona comas en selectores como ejemplo. Creo que lo resume bastante bien:

CSS 2.1 le da un significado especial a la coma (,) en los selectores. Obstante, dado que no se sabe si la coma puede adquirir otros significados en futuras actualizaciones de CSS, toda la instrucción debe ignorarse si hay un error en cualquier lugar del selector, aunque el resto del selector puede parecer razonable en CSS 2.1.

Mientras que la coma en sí misma todavía significa agrupar dos o más selectores en lo que respecta a los selectores, resulta que Selectores 4 introduce nuevas pseudo-clases funcionales que aceptan grupos selectores (o listas selectoras) como argumentos, tales como :matches() (incluso cambia :not() así que acepta una lista, haciéndola similar a :matches(), mientras que en el nivel 3 solo acepta un selector simple).

Esto significa que no solo encontrará grupos de selectores separados por comas asociados con reglas, sino que también comenzará a encontrarlos dentro de pseudo-clases funcionales (tenga en cuenta que esto solo está dentro de una hoja de estilos; fuera de CSS, los selectores pueden aparecer en código JavaScript, utilizado por las bibliotecas de selectores y Selectores API ).

Aunque no es la única razón, esto por sí solo es suficiente para complicar potencialmente las reglas de manejo de errores de un analizador con un gran riesgo de romper el selector, el conjunto de reglas o incluso el diseño. En el caso de un error de análisis con una coma, el analizador tendrá problemas para determinar si este grupo selector corresponde a un conjunto de reglas completo, o parte de otro grupo selector, y cómo manejar el resto del selector y su conjunto de reglas asociado consecuentemente. En lugar de intentar adivinar, arriesgarse a adivinar incorrectamente y romper la regla de alguna manera (por ejemplo, haciendo coincidir y estilizando todos los elementos incorrectos), la apuesta más segura es descartar la regla y seguir adelante.

Como ejemplo, considere la siguiente regla, cuyo selector es válido en el nivel 4 pero no en el nivel 3, tomada de esta pregunta mía :

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

Un analizador ingenuo que no entiende Selectores 4 puede intentar dividir esto en tres selectores distintos que comparten el mismo bloque de declaración, en lugar de un solo selector con una pseudo-clase que acepta una lista, basado solo en las comas:

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

Si simplemente descarta el primer y el último selector que obviamente no son válidos, dejando el segundo selector que es válido, ¿debería intentar aplicar la regla a cualquier elemento con clase beta? Claramente no es lo que el autor pretende hacer, así que si un navegador hace eso, va a hacer algo inesperado a este diseño. Descartando el regla con el selector no válido, el diseño parece un poco más sano, pero ese es un ejemplo demasiado simplificado; las reglas con estilos que alteran el diseño pueden causar problemas aún mayores si se aplican incorrectamente.

Por supuesto, otras ambigüedades en el análisis del selector también pueden ocurrir, lo que puede conducir a las siguientes situaciones:

  • No saber dónde termina el selector complejo
  • No saber dónde termina la lista de selectores
  • No saber dónde se bloquea la declaración comienza
  • Una combinación de lo anterior

Todos los cuales, de nuevo, se resuelven más fácilmente descartando el conjunto de reglas en lugar de jugar el juego de adivinanzas.

En el caso de selectores aparentemente bien formados que no son reconocidos, como :last-child como una pseudo-clase en su ejemplo, la especificación no hace distinción entre selectores no reconocidos y selectores que son simplemente malformados. Ambos resultan en un error de análisis. Desde la misma sección que enlazas a:

La invalidez es causada por un error de análisis, por ejemplo, un token no reconocido o un token que no está permitido en el punto de análisis actual.

Y al hacer esa declaración sobre :last-child Estoy asumiendo que el navegador es capaz de analizar un solo dos puntos seguido de un identificador arbitrario como una pseudo-clase en primer lugar; en realidad no se puede suponer que una implementación sabrá analizar :last-child como una pseudo-clase correctamente, o algo como :lang() o :not() con una notación funcional ya que las pseudo-clases funcionales no aparecieron hasta CSS2.

Selectors define un conjunto específico de pseudo-clases y pseudo-elementos conocidos, cuyos nombres son muy probablemente codificados en cada implementación. Los analizadores más ingenuos tienen la notación completa para cada pseudo-clase y pseudo-elemento, incluyendo los dos puntos simples / dobles, codificados (no me sorprendería si los principales navegadores realmente hacen esto con :before, :after, :first-letter y :first-line como a caso especial ). Así que lo que puede parecer una pseudo-clase para una implementación podría muy bien ser gobbledygook para otra.

Dado que hay tantas maneras de que las implementaciones fallen, la especificación no hace distinción, haciendo que el manejo de errores sea mucho más predecible. Si un selector no es reconocido, no importa si es porque no es compatible o está mal formado, la regla se descarta. Simple, directo, y lo suficientemente fácil para conseguir su cabeza alrededor.


Todo lo que dijo, hay al menos una discusión en la lista de correo pública de estilo www sugiriendo que se cambie la especificación porque puede que no sea tan difícil implementar el manejo de errores dividiendo selectores después de todo.

También debo mencionar que algunos motores de diseño se comportan de manera diferente, como WebKit ignorando selectores no prefijados por WebKit en una regla, aplicando sus propios prefijos, mientras que otros navegadores ignoran la regla por completo( puede encontrar más ejemplos en Stack Overflow; aquí un poco diferente ). De alguna manera se podría decir que WebKit está eludiendo la regla tal como está, aunque intenta analizar grupos de selectores separados por comas de manera inteligente a pesar de esos selectores prefijados.

No creo que el grupo de trabajo tenga una razón convincente para cambiar este comportamiento todavía. De hecho, en todo caso, tienen una razón convincente para no cambiarlo, y eso es porque los sitios han estado confiando en este comportamiento durante muchos años. En el pasado, teníamos hacks selectores para filtrar versiones anteriores de IE; hoy en día, hemos prefijado selectores para filtrar otros navegadores. Estos hacks se basan en el mismo comportamiento de ciertos navegadores descartando reglas que no reconocen, con otros navegadores aplicándolos si piensan que son correctos, por ejemplo, reconociendo prefijos (o lanzando solo los no reconocidos, como lo hace WebKit). Los sitios podrían romper en las versiones más recientes de los navegadores si esta regla fuera a cambiar, lo que absolutamente no puede suceder en una tan diversificada (léase: fragmentado) Web como nuestra.

A partir de Abril de 2013 , se decidió en un telecon que este comportamiento permanece sin cambios por la razón que he postulado anteriormente:

   - RESOLVED: Do not adopt MQ-style invalidation for Selectors
               due to Web-compat concerns.

La invalidación de estilo de consulta de medios se refiere a consultas de medios no válidas en una lista separada por comas no rompiendo toda la regla @media.

 36
Author: BoltClock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:17:00