, ( ) , ( ) , TeX, Microsoft Word . : ", ".
— , 1994
Cuando Tim Berners-Lee anunció la creación de HTML en 1991, no había forma de diseñar páginas. La forma en que se procesan las etiquetas HTML fue determinada por el navegador y estuvo significativamente influenciada por las preferencias del usuario. Sin embargo, me pareció una buena idea crear una herramienta estándar que permita a las páginas "dar pistas" sobre su interpretación estilística preferida.
Pero antes de la llegada de CSS, todavía faltaban cinco años y otros diez años antes de que se implementara por completo. Fue un período de arduo trabajo e innovación que llevó a la creación de muchas estilizaciones en competencia que bien podrían convertirse en estándar.
Si bien estos lenguajes obviamente no se usan mucho en la actualidad, me interesa reflexionar sobre cómo podría ser el mundo. Aún más sorprendente, muchos de estos lenguajes tienen características que los desarrolladores usarían felizmente en CSS incluso hoy.
Primer candidato
A principios de 1993, el navegador Mosaic ni siquiera llegó a la versión 1.0, y todos los navegadores existentes solo funcionaban con HTML. No había forma de especificar el estilo HTML, por lo que vio la etiqueta de
<h1>
la forma en que el navegador decidió mostrarla.
En junio del mismo año, Robert Reisch presentó una propuesta a la lista de correo www-talk para crear un "formato fácil de analizar para transmitir información estilística junto con documentos web", al que llamó RRP.
@BODY fo(fa=he,si=18)
Es bastante perdonable si no comprende lo que hace este código. En la era anterior a gzip, cuando las velocidades de conexión eran normalmente inferiores a 14,4 kbps, era lógico mantener el contenido de este nuevo formato lo más compacto posible. Específicamente, esta regla selecciona
fa
Helvetica ( he
) como la familia de fuentes ( ) y establece el tamaño de fuente ( si
) en 18 puntos.
Curiosamente, la propuesta de Reisch carecía de unidades de medida, todos los números se interpretaban en función del contexto (por ejemplo, todos los tamaños de fuente se daban en puntos). Esto se debe a que RRP se diseñó más como un "conjunto de consejos y trucos para el renderizador" que como una especificación. Esto se consideró necesario porque se suponía que la misma hoja de estilo funcionaba en navegadores normales en modo texto (comoLynx ) y en los navegadores gráficos cada vez más populares.
Captura de pantalla del navegador Lynx
Curiosamente, RRP incluye una forma de especificar el diseño en columnas; esto no fue posible en CSS hasta 2011. Por ejemplo, tres columnas, cada una de 80 unidades de ancho, se verían así:
@P co(nu=3,wi=80)
Es un poco complicado de analizar, pero probablemente no mucho más difícil que
white-space: nowrap
.
Vale la pena señalar que RRP no admitía ninguna de las "cascada" con las que asociamos las hojas de estilo en la actualidad. Cualquier documento no puede tener más de una hoja de estilo activa a la vez, lo cual es bastante lógico en el caso de los documentos de estilo, aunque es inusual para nosotros hoy.
Marc Andreessen (creador de Mosaic, que finalmente se convirtió en el navegador más popular) conocía la propuesta de RRP, pero nunca la implementó en Mosaic. En cambio, Mosaic tomó casi inmediatamente el camino de usar etiquetas HTML para diseñar (lo cual es bastante trágico), agregando etiquetas como
<FONT>
y <CENTER>
.
Viola y las guerras de Proto Browser
“Entonces, ¿por qué no implementar una de las muchas propuestas de hojas de estilo que existen? Con la estructura adecuada, esto resolvería casi por completo el problema ".
Entonces tendría que decirle a la gente: "Está bien, es necesario aprender este idioma para escribir un documento y luego aprender otro idioma para que el documento se vea como lo desea". Oh, simplemente les encantaría.
- Mark Andreessen, 1994
Contrariamente a la creencia popular, Mosaic no fue el primer navegador gráfico. Fue precedido por ViolaWWW , un navegador gráfico originalmente escrito por Pei-Yuan Wei en solo cuatro días.
Captura de pantalla de Viola Browser
Pei-Yuan creó un lenguaje de hoja de estilo que admite el tipo de estructura jerárquica que se usa en CSS hoy:
(BODY fontSize=normal
BGColor=white
FGColor=black
(H1 fontSize=largest
BGColor=red
FGColor=white)
)
En este caso, estamos aplicando colores al cuerpo del documento (body) y, en particular, estamos aplicando estilos
H1
que están dentro del cuerpo. En lugar de repetir selectores para controlar este anidamiento, PWP usó el sistema de paréntesis, lo que nos hace pensar en los sistemas de sangría usados en lenguajes como Stylus y SASS, que algunos desarrolladores todavía prefieren sobre CSS hoy en día. Esto potencialmente hace que la sintaxis de PWP sea mejor en al menos un aspecto que CSS, que ha evolucionado con el tiempo hasta convertirse en el lenguaje universal de la web.
PWP también se destaca por el hecho de que tiene una forma de referirse a hojas de estilo externas, que todavía usamos hoy:
<LINK REL="STYLE" HREF="URL_to_a_stylesheet">
Desafortunadamente, ViolaWWW se escribió principalmente para trabajar con el sistema X Window , que solo era popular en sistemas Unix. Cuando Mosaic se transfirió a Windows, rápidamente convirtió a Viola en polvo.
Hojas de estilo antes de la web
HTML es el tipo de cosas de las que solo un científico informático puede enamorarse. Sí, expresa la estructura interna de un documento, pero los documentos no son solo bases de datos de texto estructurado; tienen un impacto visual. HTML destruye por completo cualquier creatividad gráfica que pueda tener un desarrollador de documentos.
- Roy Smith, 1993
La necesidad de un lenguaje capaz de expresar el estilo de los documentos es mucho más antigua que la propia Internet.
Como probablemente sepa, el HTML que conocemos se basó originalmente en un lenguaje anterior a Internet llamado SGML. En 1987, el Departamento de Defensa de EE. UU. Decidió probar si SGML se podía utilizar para simplificar el almacenamiento y la transferencia de sus enormes volúmenes de documentación. Como cualquier buen proyecto de gobierno, lo primero que hicieron fue inventar un nombre. Inicialmente, el equipo se denominó equipo de soporte logístico asistido por computadora, luego equipo de soporte logístico y adquisiciones asistido por computadora y, finalmente, la iniciativa de soporte continuo de adquisición y ciclo de vida. En cualquier caso, las iniciales eran CALS.
El equipo de CALS creó un lenguaje para diseñar documentos SGML llamado FOSI. Ella publicóuna especificación de lenguaje que es tan detallada como incomprensible. Incluía mi favorito de las infografías más insignificantes que jamás hayan existido en la web.
Una regla de Internet que no tiene excepciones es que siempre puedes hacer más si puedes demostrar que alguien está equivocado en el proceso. En 1993, solo cuatro días después de la propuesta de Pei-Yuan, Stephen Heaney propuso que en lugar de reinventar la rueda, sería mejor usar la versión FOSI de diseñar la web.
El documento FOSI en sí está escrito en SGML, lo cual es un movimiento bastante lógico dada la familiaridad de los desarrolladores web con una versión de SGML llamada HTML. Un documento de ejemplo se ve así:
<outspec>
<docdesc>
<charlist>
<font size="12pt" bckcol="white" fontcol="black">
</charlist>
</docdesc>
<e-i-c gi="h1"><font size="24pt" bckcol="red", fontcol="white"></e-i-c>
<e-i-c gi="h2"><font size="20pt" bckcol="red", fgcol="white"></e-i-c>
<e-i-c gi="a"><font fgcol="red"></e-i-c>
<e-i-c gi="cmd kbd screen listing example"><font style="monoser"></e-i-c>
</outspec>
Quizás no comprenda lo que es
docdesc
o charlist
, al igual que los miembros, no lo entendieron www-talk
. La única información contextual es lo que significa e-i-c
"elemento en contexto". Sin embargo, FOSI es notable por primera vez que introdujo la unidad de medida em
, que ahora se ha convertido en la forma preferida de dimensionamiento en CSS.
El conflicto lingüístico resultante era de hecho tan antiguo como la programación misma. Fue una batalla entre la sintaxis funcional estilo lisp y la sintaxis en lenguajes más declarativos. El mismo Pei-Yuan describió su sintaxis como "similar a LISP", pero era solo cuestión de tiempo antes de que la verdadera versión de LISP apareciera en escena.
Hoja de estilo completa de Turing
A pesar de su complejidad, FOSI se percibió en realidad como una solución intermedia al problema del formato de los documentos. El plan a largo plazo era crear un lenguaje basado en el lenguaje de programación funcional Scheme, capaz de implementar las transformaciones de documentos más poderosas imaginables. Este idioma se denominó DSSSL. Demos la palabra a uno de los desarrolladores del lenguaje, John Bosak:
No confunda DSSSL con un lenguaje de programación. Sí, DSSSL es Turing completo; sí, es un lenguaje de programación. Pero el lenguaje de la escritura (al menos en mi interpretación del término) es procedimental; y DSSSL definitivamente no lo es. DSSSL es completamente funcional y está completamente libre de efectos secundarios. Nunca sucede nada en la hoja de estilo DSSSL. Una hoja de estilo es una función enorme, cuyo valor es una descripción abstracta, independiente del dispositivo y no procedimental de un documento formateado, como una especificación (una declaración, si lo desea) de las regiones que se van a representar, pasadas a los renderizadores subyacentes.
En su forma más simple, DSSSL es de hecho un lenguaje de estilo bastante lógico:
(element H1
(make paragraph
font-size: 14pt
font-weight: 'bold))
Como era un lenguaje de programación, incluso se podían definir funciones en él:
(define (create-heading heading-font-size)
(make paragraph
font-size: heading-font-size
font-weight: 'bold))
(element h1 (create-heading 24pt))
(element h2 (create-heading 18pt))
Y use construcciones matemáticas al diseñar, por ejemplo, para hacer rayas en las filas de la tabla:
(element TR
(if (= (modulo (child-number) 2)
0)
... ;even-row
...)) ;odd-row
Para ponerte aún más celoso, digamos que DSSSL podría tratar los valores heredados como variables y realizar operaciones matemáticas con ellos:
(element H1
(make paragraph
font-size: (+ 4pt (inherited-font-size))))
Desafortunadamente, DSSSL tenía un defecto fatal común a todos los lenguajes de estilo Scheme: demasiados paréntesis. Además, su especificación estaba demasiado completa en el momento del lanzamiento final, lo que intimidó a los desarrolladores de navegadores. La especificación DSSSL incluyó más de 210 propiedades de estilo individual.
El trabajo de desarrollo adicional condujo a la creación de XSL , un lenguaje de transformación de documentos igualmente complicado, pero mucho más popular.
Por que ganó la hoja de estilo
CSS no tiene selectores de padres (una forma de diseñar un padre según los elementos secundarios que contiene). Este hecho ha estado plagando a los usuarios de Stack Overflow durante mucho tiempo , pero resulta que hay una muy buena razón para su ausencia. En los primeros días de Internet, se consideraba fundamental que una página se pudiera representar antes de que el documento estuviera completamente cargado. En otras palabras, era necesario poder representar el HTML de la parte superior de la página antes de que se cargara por completo el HTML del final de la página.
Tener un selector principal significaría que los estilos deben actualizarse a medida que se carga el documento HTML. Se descartaron completamente lenguajes como DSSSL, porque pueden realizar operaciones en el documento en sí, que no está completamente disponible en el momento de la renderización. Bert Bose fue el
primero en plantear este problema en marzo de 1995 y en proponer un lenguaje de trabajo para solucionarlo. Su propuesta también contiene una versión temprana del emoticono "smiley" :-).
El lenguaje en sí estaba bastante "orientado a objetos" en la sintaxis:
*LI.prebreak: 0.5
*LI.postbreak: 0.5
*OL.LI.label: 1
*OL*OL.LI.label: A
El símbolo
.
denotaba a los niños más cercanos y a los *
antepasados.
El lenguaje de Bose tenía otra propiedad interesante: se podía especificar cómo funcionan elementos como los enlaces en la propia hoja de estilo:
*A.anchor: !HREF
En el ejemplo anterior, especificamos que la dirección de navegación del elemento de enlace es el valor de su atributo
HREF
. Esta idea de que se debe controlar el comportamiento de elementos como los enlaces ha sido popular en muchas otras propuestas. En la era anterior a JavaScript, no había forma de controlar tales aspectos, por lo que parecía lógico incluirlos en estas propuestas.
En un borrador de un lenguaje funcional, propuesto en 1994 por un caballero llamado S.M. Sperberg-McQueen, el mismo comportamiento se implementa funcionalmente:
(style a
(block #f) ; format as inline phrase
(color blue) ; in blue if you’ve got it
(click (follow (attval 'href))) ; and on click, follow url
Su lenguaje también introdujo la palabra clave
content
como una forma de manipular el contenido de un elemento HTML de una hoja de estilo. Este concepto se añadió posteriormente en CSS 2.1.
¿Qué podría ser la web?
Antes de hablar sobre el lenguaje que realmente se convirtió en CSS, vale la pena mencionar una propuesta de lenguaje más, aunque solo sea por el hecho de que, en cierto sentido, fue el sueño de los primeros desarrolladores web.
PSL96 fue, como su nombre indica, la versión de 1996 del lenguaje de especificación de presentación. En esencia, PSL se parece a CSS:
H1 {
fontSize: 20;
}
Sin embargo, las cosas rápidamente se vuelven mucho más interesantes. Por ejemplo, fue posible expresar la posición de un elemento no solo dependiendo del tamaño (
Width
) que se le dio , sino también del Actual Width
tamaño verdadero ( ) en el que se representa en el navegador:
LI {
VertPos: Top = LeftSib . Actual Bottom;
}
Puede ver en el ejemplo que también puede usar el hermano izquierdo como restricción.
También se pueden agregar expresiones booleanas a los estilos. A continuación, se muestra un ejemplo de cómo aplicar estilo solo a elementos de anclaje que tienen
href
:
A {
if (getAttribute(self, "href") != "") then
fgColor = "blue";
underlineNumber = 1;
endif
}
Este estilo podría extenderse a todo tipo de aspectos, para cuya implementación usamos hoy clases:
LI {
if (ChildNum(Self) == round(NumChildren(Parent) / 2 + 1)) then
VertPos: Top = Parent.Top;
HorizPos: Left = LeftSib.Left + Self.Width;
else
VertPos: Top = LeftSib.Actual Bottom;
HorizPos: Left = LeftSib.Left;
endif
}
Apoyar esta funcionalidad probablemente haría posible finalmente realizar el sueño de separar el contenido del estilo. Desafortunadamente, este lenguaje es demasiado extensible, es decir, existía una alta probabilidad de que su implementación fuera muy diferente en diferentes navegadores. Además, se publicó en una serie de artículos en el mundo científico, y no en la lista de correo de www-talk, donde tuvo lugar la mayor parte del trabajo constructivo. Nunca se ha integrado en ningún navegador popular.
Fantasma del pasado CSS
El lenguaje que podría conducir directamente a la creación de CSS (al menos como sugiere el nombre) fue CHSS (Cascading HTML Style Sheets). Fue propuesto en 1994 por Håkon W Lie.
Como la mayoría de las buenas ideas, la propuesta inicial fue bastante loca.
h1.font.size = 24pt 100%
h2.font.size = 20pt 40%
Preste atención a los porcentajes al final de las reglas. Este porcentaje significa cuánta "propiedad" tiene la hoja de estilo actual sobre ese valor. Por ejemplo, si la hoja de estilo anterior
h2
tenía un tamaño de fuente especificado 30pt
para 60%
"propiedad" y esa hoja de estilo h2
especificó un estilo para 20px 40%
, entonces los dos valores se pueden combinar según su porcentaje de propiedad para producir un valor de aproximadamente 26pt
.
Es bastante comprensible por qué se hizo una propuesta de este tipo en la era de las páginas HTML documentales: tal diseño basado en compensaciones no se entendería en nuestro mundo orientado a las aplicaciones. Sea como fuere, se le ocurrió una idea fundamental sobre la necesidad de una estructura de hoja de estilo en cascada. En otras palabras, la idea de que se necesitan varias hojas de estilo en la misma página.
En su formulación original, esta idea fue generalmente reconocida como importante porque le dio al usuario final control sobre lo que veía. La página original podría tener una hoja de estilo, y el usuario web podría tener su propia hoja de estilo y podrían combinarse para representar la página. La compatibilidad con varias hojas de estilo se vio como una forma de preservar la libertad personal en la web, no como una forma de apoyar a los desarrolladores (que todavía codificaban a mano cada página HTML).
El usuario podría incluso controlar el grado de control que le dio a las recomendaciones del autor de la página; dicho control en una oración de lenguaje fue descrito por un esquema ASCII:
User Author
Font o-----x--------------o 64%
Color o-x------------------o 90%
Margin o-------------x------o 37%
Volume o---------x----------o 50%
Como muchas de estas suposiciones, este proyecto contenía características que aparecieron en CSS solo décadas después, si es que no lo hicieron. Por ejemplo, tenía la capacidad de escribir expresiones lógicas basadas en el entorno del usuario:
AGE > 3d ? background.color = pale_yellow : background.color = white
DISPLAY_HEIGHT > 30cm ? http://NYT.com/style : http://LeMonde.fr/style
En una visión de ciencia ficción bastante optimista del futuro, se asumió que el navegador sabría qué tan relevante es cada contenido para el usuario, permitiendo que se muestre en un tamaño mayor:
RELEVANCE > 80 ? h1.font.size *= 1.5
Todos sabemos lo que pasó después
Microsoft está totalmente comprometido con los estándares abiertos, especialmente en Internet.
- John Ludeman, 1994
Haakon Lee continuó trabajando para simplificar su propuesta y, junto con Bert Bose, publicó la primera versión de la especificación CSS en diciembre de 1996. Terminó escribiendo su tesis doctoral sobre la creación de CSS y este documento me ayudó enormemente a escribir este artículo.
En comparación con muchas otras propuestas, el aspecto notable de CSS fue su simplicidad. Es fácil de analizar, fácil de escribir y fácil de leer. Como ha sucedido a menudo en la historia de Internet, el ganador es la tecnología que es más fácil de dominar para un principiante, y no la que resultó ser la más poderosa para los especialistas.
Esto en sí mismo es un recordatorio de lo que puede ser la innovación aleatoria. Por ejemplo, soporte para selectores contextuales (
body ol li
) solo se agregó porque Netscape ya tenía una forma de eliminar los bordes de las imágenes que eran hipervínculos, y parecía necesario hacer todo lo que el popular navegador podía hacer. La funcionalidad en sí causó un retraso significativo en la implementación de CSS, porque en ese momento la mayoría de los navegadores no almacenaban una "pila" de etiquetas al analizar HTML. Esto significó que los analizadores debían ser rediseñados para admitir completamente CSS.
Debido a estos problemas (y al uso generalizado de etiquetas HTML no estándar para el diseño), CSS no se pudo utilizar hasta 1997 y no fue totalmente compatible con ningún navegador hasta marzo de 2000. Como cualquier desarrollador le dirá, la compatibilidad con navegadores estaba muy lejos de ser compatible con los estándares y eso cambió hace solo unos años, quince años después del lanzamiento de CSS.
Netscape 4 CSS,<body>
, , IE4<body>
, , CSS ? CSS. , IE4 , Netscape 4.
—
Internet Explorer 3 es famoso por ser lanzado con soporte CSS (bastante terrible). Se decidió que para poder competir en Netscape 4, este lenguaje también debe ser compatible. Sin embargo, en lugar de redoblar los esfuerzos para implementar este tercer lenguaje (después de HTML y JavaScript), se decidió que debería implementarse transformando CSS en JavaScript y luego ejecutándolo. Peor aún, se decidió que esta hoja de estilo JavaScript intermedia debería estar disponible para los desarrolladores web .
La sintaxis era JavaScript simple con la API de estilo agregada:
tags.H1.color = "blue";
tags.p.fontSize = "14pt";
with (tags.H3) {
color = "green";
}
classes.punk.all.color = "#00FF00"
ids.z098y.letterSpacing = "0.3em"
Incluso fue posible definir funciones cuyos valores se calcularon al encontrar cada aparición de una etiqueta :
evaluate_style() {
if (color == "red"){
fontStyle = "italic";
} else {
fontWeight = "bold";
}
}
tag.UL.apply = evaluate_style();
La idea de simplificar la línea divisoria entre estilos y scripts es bastante razonable, y hoy incluso está renaciendo en la comunidad React .
JavaScript en sí era un lenguaje muy joven en ese momento, pero gracias a la ingeniería inversa, se agregó soporte en IE3 (en forma de JScript). Un problema mucho mayor fue que la comunidad ya se estaba reuniendo en torno a CSS en ese momento, y Netscape era visto como un delincuente por la mayoría de la comunidad de estándares en ese momento . Cuando Netscape ofreció JSSS al comité de estándares, hizo oídos sordos. Tres años más tarde, Netscape 6 abandonó el soporte para JSSS y murió gradualmente.
Que nos puede esperar
Gracias a la censura pública del W3C, Internet Explorer 5.5 se lanzó con compatibilidad casi total con CSS1 en 2000. Por supuesto, como sabemos ahora, las implementaciones de CSS en los navegadores han tenido muchos errores y ha sido difícil trabajar con ellas durante al menos otra década. Afortunadamente, hoy la situación ha mejorado significativamente, lo que finalmente hizo posible hacer realidad el sueño de los desarrolladores de que se puede escribir código una vez y funcionará (casi) igual en diferentes navegadores.
Personalmente, extraje de todo esto cuán arbitrarias y contextuales eran las decisiones que gobiernan nuestras herramientas modernas. Si CSS fue diseñado para ser compatible con las restricciones de 1996, entonces tal vez veinte años después eso nos da permiso para hacer las cosas de manera un poco diferente.