viernes, 8 de abril de 2011

DOCTYPE, quirk, strict y un poco más

Como lo prometido es deuda, hay va el primero de, espero, una serie de post relacionados con CSS.

Lo primero es tener la referencia a mano, así que dejo los enlaces a la especificación de w3c.

CSS 2.1 http://www.w3.org/TR/CSS2/
HTML 4.0.1 http://www.w3.org/TR/html401/
XHTML 1.1
http://www.w3.org/TR/xhtml-basic/


Todos los estándares disponibles los puedes encontrar en http://www.w3.org/TR/tr-technology-stds.

En la w3c, hasta se consigue un estándar o recomendación, cualquier documento tiene que pasar por una serie de estados previos:

·           WD (Working Draft)

·           CR (Candidate Recommendation)

·           PR (Proposed Recommendation)

·           REC (W3C Recommendation)

Es por ello que, en el momento de escribir este post, CSS3 aún no es una recomendación y por eso no lo veremos en esta serie de post. Cabe mencionar que aunque no sea una recomendación, ciertos navegadores ya implementan parte de su funcionalidad como signo diferenciador en la carrera comercial entre navegadores. Puedes ampliar más información en este otro post que habla sobre las extensiones específicas de vendedor.

En cualquier caso, recomiendo www.css3.info para estar al tanto de todo lo relacionado con CSS3.

Volviendo a los enlaces anteriores, con ellos puedes hacer 2 cosas. La primera es utilizarlos cada vez que necesites ayuda sobre HTML o CSS y asegurarte de este modo de que estás leyendo la fuente de conocimiento original y más confiable que existe, o bien pasar de ellos (que reconozco que al estar redactados en forma de especificación, al comienzo pueden ser un poco ariscos de leer) y escribir en google simplemente el nombre de la etiqueta o propiedad sobre la que quieres ayuda y finalmente navegar a cualquier página que, aunque con toda la buena intención del mundo, no será confiable 100% y quién sabe si tendrá algún error. Yo por mi parte lo tengo claro, voy a intentar vencer la inmediatez de google y confío en acceder siempre a la w3c, que para eso están… digo yo!. Además y por si se te ha pasado por alto, hay enlaces para su descarga en diversos formatos (pdf, etc.)

Por otro lado, sería muy interesante tener una lista de qué propiedades CSS soportan qué navegadores. El problema aquí es que no he terminado de encontrar una lista definitiva y que sea actualizada según aparecen nuevos navegadores o incluso nuevas versiones de los navegadores existentes. En cualquier caso, aquí van algunos enlaces:

http://www.webdevout.net/browser-support-css (el mejor enlace de todos)
http://westciv.com/wiki/CSS_Compatibility_Guide
http://www.evotech.net/blog/2009/02/css-browser-support/
http://www.quirksmode.org/css/contents.html

Aunque no lo he comentado antes, estos post no pretenden ser un tutorial de HTML+CSS desde cero. Asumo que el lector ya sabe HTML y CSS. También asumo que está en la misma posición que estoy yo, es decir, con ganas de aclarar una serie de conceptos y con ganas de terminar de afianzarlos para poder pasar página de una p*** vez y no preguntarse siempre ¿Por qué no estudié CSS?

Bueno, pues antes del CSS vamos a ver un poco de teoría sobre HTML, XHTML, DOCTYPE, etc, es aburrido, lo sé, pero…

DOCTYPE

Para hablar sobre la directiva DOCTYPE es importante conocer la diferencia entre el modo quirk o el modo strict (también llamado estándar) de un navegador.

El modo quirk (quirk significa singularidad, rareza) de un navegador entra en juego si la directiva DOCTYPE no es válida o no existe. En modo quirk, cada navegador aplicará unas reglas concretas y particulares al tratamiento de nuestro código HTML o XHTML.

Si lo que pretender es crear código cross-browser, este modo no es el más adecuado. Para que te hagas una idea, el modo quirk perseguía (gracias a dios hablo en pasado) atar a los internautas y desarrolladores a un explorador en concreto, ya que en este modo el navegador interpretaba el código siguiendo los bugs y errores de las antiguas versiones de sus navegadores, así que si querías ver la página de forma correcta sólo tenías la opción de utilizar el navegador adecuado.

Por ejemplo, si entramos en modo quirk en IE, el ancho y alto de un elemento incluye el borde y el relleno (border y padding), mientras que la w3c dice que ni el borde ni el relleno debe intervenir en este cálculo.

Lo cierto es que hay cientos de diferencias entre modo quirk y strict, pero no merece la pena escribir sobre ello, porque está claro que nosotros nunca permitiremos que nuestras páginas entren en este odioso modo quirk.

Si queremos saber en qué modo está trabajando nuestro navegador, puedes agregar un bookmarklet a tus favoritos con el siguiente código:

 

javascript:m=(document.compatMode=='CSS1Compat')?'Standards':'Quirks';

window.alert('You%20are%20in%20'%20+%20m%20+%20'%20mode.');

 

Este código comprueba si la propiedad document.compatMode es igual a “CSS1Compat”. Si la comparación es cierta estamos en modo estándar, sino estamos en modo quirk.

 

Más información sobre esta técnica aquí.


Ahora que ya sabemos que no podemos prescindir jamás de la directiva DOCTYPE porque si no el navegador entraría en modo quirk, queda decir que esta directiva sirve al propósito de instruir al navegador sobre cómo debe interpretar el código HTML o XHTML que contiene nuestra página. Es decir, con DOCTYPE estamos en modo strict (muerte al modo quirk!) y además le estamos quitando la responsabilidad al navegador de decidir cómo interpretar y mostrar los elementos de nuestra página (y por ende estamos favoreciendo también el uso de estándares y de código cross-browser). Le estamos especificando un DTD sobre el que poder validar nuestro código y también desde donde poder obtener información precisa sobre cómo trabajar con nuestro documento. De hecho, DOCTYPE es la abreviatura de DOCUMENT TYPE DEFINITION, es decir, DTD. Al final está claro que lo que queremos es concretar de forma exacta de qué tipo de documento estamos hablando y de cómo debería interpretarse (sin ambigüedades ni decisiones “personales” del navegador).

¿Y entonces qué tipos de DOCTYPE tenemos disponibles?

Pues ahora mismo (seguro que cambiará con el tiempo) hay 8:

·           3 para HTML

·           4 para XHTML

·           1 para HTML5

A grandes rasgos hay 3 bloques de tipos de DOCTYPE (excepto para HTML5):

·           Estricto (strict)

·           Transaccional (transactional)

·           Marcos (frameset)

El modo estricto no permite propiedades de formato para los elementos. Es decir, propiedades como backgroundcolor en la etiqueta body no están permitidos, ya que para esta tarea está CSS.

El modo transaccional es un puente para llegar al estricto, esto es que aún permite el uso de ciertos elementos y propiedades en desuso por la w3c como “puente” hacía el modo estricto.

Y por último (y además el menos deseable) tenemos los marcos por si aún utilizamos las etiquetas frame y frameset.

Finalmente tenemos el DOCTYPE XHTML 1.1 y HTML (que directamente no tiene diferencias entre estricto, transaccional y marcos).

DOCTYPE

Declaración

HTML 4.01 Strict

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

HTML 4.01 Transactional

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

HTML 4.01 Frameset

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">

XHTML 1.0 Strict

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

XHTML 1.0 Transactional

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

XHTML 1.0 Frameset

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">

XHTML 1.1

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

HTML5

<!DOCTYPE HTML>


Si por ejemplo estamos trabajando con Visual Studio, podemos ver como cualquier página .aspx incluye automáticamente la siguiente instrucción DOCTYPE

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

De hecho y si eres un curioso, prueba a navegar a la url que especifica el DTD y verás cómo carga y contiene la especificación de este tipo de documento. En el fondo está claro, el navegador tiene que acceder a esta dirección para validar e interpretar nuestro documento! (un repositorio común que mantiene exclusivamente la w3c).

Esto es cierto para todos los DOCTYPE menos para el que especifica HTML5 (que no tiene DTD, ni url, ni distintos tipos…)

Por otro lado, utilizar un editor como Visual Studio significa que ya durante la elaboración de nuestra página, el editor nos sugiere sólo los elementos y propiedades válidos según el DOCTYPE seleccionado (imagino que otros como dreamweaver también lo harán).

Bueno, en realidad en Visual Studio funciona un poco raro porque la instrucción DOCTYPE de la página .aspx no se tiene en cuenta para el intellisense, lo que se tiene en cuenta es el valor seleccionado en la barra de herramientas “Edición de código fuente HTML”.

clip_image001

Es decir, de inicio tendremos la instrucción DOCTYPE XHTML 1.0 Transitional (la que se creó automáticamente al crear la página .aspx) y también tendremos seleccionada la opción “XHTML 1.0 Transaction” en la barra “Edición de código fuente HTML”. De este modo, tendremos el siguiente intellisense:

clip_image002

Si cambiamos la instrucción DOCTYPE de la página no resultará en ningún cambio en el intellisense, pero sin embargo, si seleccionamos HTML5 en la barra de edición, ahora si aparecerán distintas opciones en intellisense.

clip_image003

clip_image004

Cuando estamos seleccionando elementos en la barra de “Edición de código fuente HTML”, lo que estamos haciendo realmente es cambiar el esquema de destino para la validación. Es decir, el mismo resultado lo obtenemos si vamos a Herramientas > Opciones > Editor de texto > HTML > Validación.

clip_image005

A mí personalmente, el tratamiento que hace Visual Studio de la directiva DOCTYPE y el intellisense y validación me deja un poco frio, porque realmente la directiva DOCTYPE va por un lado y la selección del esquema destino de validación va por otro.

Lo que sí es una gran característica a tomar en cuenta es que, además del intellisense para elementos y sus propiedades, este intellisense también funciona a la hora de insertar nuevos elementos en el documento respecto a otros elementos. Por ejemplo, si pretendemos anidar un elemento p dentro de un elemento span:

1. Visual Studio “no” los sugiere con el intellisense.

2. Si somos muy cabezones y aun así metemos la p, nos da un warning la validación.

clip_image006

En este momento quiero aprovechar para contarte que no todos los elementos pueden anidarse dentro de todos los elementos. Aunque hay ciertas normas generales (como que un elemento en línea no puede contener elementos de bloque), también hay normas particulares por cada elemento. Por ejemplo, el elemento P es un elemento de bloque y aun así no puede contener otros elementos de bloque (ni siquiera otro elemento P). El cómo Visual Studio es capaz de avisarnos de estas situaciones es porque durante la edición valida nuestro código contra el esquema de validación seleccionado y su DTD.

Para terminar con DOCTYPE (que ya se está haciendo largo), hay un issue/bug/problema/comportamiento (como verás no sé cómo llamarlo) que consiste en que “aunque creas que estás utilizando XHTML, probablemente estés utilizando HTML”.

Es un poco lioso de explicar pero, básicamente XHTML dice es su especificación que si el documento contiene algún error directamente debería mostrar un error al usuario y no seguir procesando el documento. Como puedes imaginar, son pocos los que hoy en día pueden hacer páginas sin un solo error (sobre todo porque hay controles de terceros, los propios controles ASP.NET, etc.). Este tipo de comportamiento propuesto por XHTML es lo que se llama “manejo de errores draconiano”. Para solucionar esto y no romper la web (imagínate páginas a medio-renderizar y usuarios con cara de asombro…), si se sirve un documento XHTML con la cabecera content-type: text/html (en vez de content-type: application/xhtml+xml que sería la correcta) lo que hace el navegador es tratar el documento como HTML en vez de como XHTML. Es decir, los navegadores de hoy en día toman como primera referencia para determinar el tipo de documento, la cabecera content-type devuelta por el servidor antes que la directiva DOCTYPE del propio documento. De todas formas, te dejo algunos enlaces que hablan sobre ello y que sepas que hasta a la w3c le pasa esto!

Aquí descubrí que pasaba esto http://geeks.ms/blogs/mposadas/archive/2011/04/01/191-algui-233-n-me-puede-explicar-qu-233-verdad-hay-en-233-sta-afirmaci-243-n-anti-ie.aspx

http://diveinfohtml5.org/past.html y aquí lo explica perfectamente en el punto “Everything you know about XHTML is wrong”.

http://hsivonen.iki.fi/doctype/ este enlace es la repera y es para dejar claro cuándo y en qué circunstancias entre en modo quirk un navegador.

Además, si hay necesidad de ajustar el código que generan los controles de servidor de ASP.NET (que en principio generan XHTML 1.0 Transactional), hay cierto margen de configuración con el elemento xhtmlConformance del fichero web.config. http://msdn.microsoft.com/es-es/library/ms228268(v=vs.80).aspx

XHTML

Durante todo el documento hemos mencionado XHTML, pero ahora ha llegado el momento de ver brevemente cuáles son sus normas y el “aparente” porqué de XHTML. (Entrecomillo “aparente” porque la verdad es que ahora mismo tengo ya más dudas que certezas y lo servir XHTML como HTML me ha matado…). Al final tengo la sensación de que da igual todo la buena intención que ponga uno como desarrollador, que siempre tendremos que terminar probando nuestras páginas en todos los navegadores habidos y por haber y resolver problemas puntuales de renderización y tratamiento por parte del navegador de turno.

XHTML es en lenguaje llano “HTML combinado con la sintaxis estricta de XML”.

·           Nombres de etiquetas y propiedades en minúsculas.

·           Código bien formado. Esto es que la estructura de aperturas y cierres de etiquetas tiene que ser correcta.

·           Todos los elementos necesitan un cierre. Por ejemplo, etiquetas como br se tiene que escribir <br />.

·           Todos los atributos tiene que tener un valor. Por ejemplo no es correcto checked, es correcto checked=”checked”.

VALIDAR

Otro concepto que hemos trabajado en este post y que merece su propio punto es la validación.

Validar es asegurarse que el código que estamos escribiendo es conforme a la especificación sobre la que hemos trabajado y en caso contrario obtener una lista de errores o warnings para poder solucionarlo.

Aunque Visual Studio nos facilita la validación en vivo con los warnings según el esquema de validación activo, la forma más habitual de validar es a través de la w3c.

Para validar nuestro documento (HTML o XHTML), el enlace es el siguiente http://validator.w3.org/

Si por otro lado, queremos validar CSS http://jigsaw.w3.org/css-validator/

Yo personalmente recomiendo usar estos validadores (que me ayudan a complementar la validación de Visual Studio), pero la verdad es que hay otros muchos atajos como utilizar la IE Developer Toolbar (herramientas del desarrollador en IE) y su menú Validar, o utilizar alguno de los miles de complementos disponibles en Firefox, etc.

Un saludo!

1 comentario: