Todo el mundo sabe que en general, los navegadores son muy tolerantes a errores en el marcado y por eso muchos programadores / diseñadores no prestan una adecuada atención a las estructuras HTML que producen. Os voy a poner un caso que me ha ocurrido hoy para no olvidar que aunque se toleren los fallos, siempre es mejor no cometerlos:
Teníamos esta estructura:
<button> <span> Test </span> </button>
En un momento dado, la expandíamos añadiendo cierto marcado al interior del botón:
<button> <span> <button><span>Test 1</span></button> <button><span>Test 2</span></button> <button><span>Test 3</span></button> </span> </button>
Pues bien, en Firefox, los botones internos jamás recibían ningún evento. ¿Por qué? Pues porque la especificación dice del contenido de un elemento button, lo siguiente:
Content model:
Phrasing content, but there must be no interactive content descendant.Modelo del contenido:
Contenido en forma de sentencia, mas no debe haber ningún descendiente con contenido interactivo.
¿Quiere esto explícitamente decir que los eventos que reciba el primer button no se propagarán hacia los botones contenidos en él? No, o la menos yo no he encontrado esa negación explícita. Se trata sencillamente de un comportamiento indefinido y no se puede confiar en los comportamientos indefinidos. No hay duda de que son útiles para la optimización y en este caso, Firefox no propaga eventos de interacción dentro de un elemento que no debería tener contenido interactivo.