Linguagens que quase se tornaram CSS

Olá, Habr! Chamo a atenção para a tradução de As Línguas que Quase se Tornaram CSS, de Zack Bloom, sobre linguagens que poderiam ter se tornado CSS, se a história fosse um pouco diferente.





, ( ) , ( ) , TeX, Microsoft Word . : ", ".



— , 1994


Quando Tim Berners-Lee anunciou a criação do HTML em 1991, não havia como estilizar as páginas. A maneira como as tags HTML foram renderizadas foi determinada pelo navegador e foi significativamente influenciada pelas preferências do usuário. No entanto, parecia uma boa ideia criar uma ferramenta padrão que permitisse às páginas "dar dicas" sobre sua renderização estilística preferida.



Mas antes do advento do CSS, ainda faltavam cinco anos, e outros dez anos antes de ser totalmente implementado. Foi um período de muito trabalho e inovação que levou à criação de muitas estilizações concorrentes que poderiam se tornar padrão.



Embora essas línguas obviamente não sejam amplamente utilizadas hoje, é interessante para mim refletir sobre como o mundo pode ser. Ainda mais surpreendente, muitas dessas linguagens têm recursos que os desenvolvedores usariam com prazer em CSS até hoje.



Primeiro candidato



No início de 1993, o navegador Mosaic nem chegou à versão 1.0 e todos os navegadores existentes funcionavam apenas com HTML. Não havia como especificar o estilo HTML, então você viu a tag <h1>da maneira que o navegador decidiu mostrá-la.



Em junho do mesmo ano, Robert Reisch apresentou uma proposta à lista de discussão www-talk para criar um “formato de fácil análise para transmitir informações estilísticas junto com documentos da web”, que ele chamou de RRP.



@BODY fo(fa=he,si=18)


É perfeitamente perdoável se você não entender o que esse código faz. Na era pré-gzip, quando as velocidades de conexão eram normalmente inferiores a 14,4 kbps, era lógico manter o conteúdo desse novo formato o mais compacto possível. Especificamente, esta regra seleciona faHelvetica ( he) como a família da fonte ( ) e define o tamanho da fonte ( si) para 18 pontos.



Curiosamente, a proposta de Reisch carecia de unidades, todos os números eram interpretados com base no contexto (por exemplo, todos os tamanhos de fonte estavam em pontos). Isso ocorre porque o RRP foi projetado mais como um “conjunto de dicas e truques para o renderizador” do que como uma especificação. Isso foi considerado necessário porque a mesma folha de estilo funcionaria em navegadores de modo de texto normais (comoLynx ), e nos navegadores gráficos cada vez mais populares.





Captura de tela do navegador Lynx



Curiosamente, o RRP inclui uma maneira de especificar o layout colunar - isso não era possível no CSS até 2011. Por exemplo, três colunas, cada uma com 80 unidades de largura, teriam a seguinte aparência:



@P co(nu=3,wi=80)


É um pouco complicado de analisar, mas provavelmente não muito mais difícil do que white-space: nowrap.



É importante notar que o RRP não suportava nenhuma das "cascatas" que associamos às folhas de estilo hoje. Qualquer documento não poderia ter mais do que uma folha de estilo ativa por vez, o que é bastante lógico no caso de estilizar documentos, embora seja incomum para nós hoje.



Mark Andreessen (o criador do Mosaic, que eventualmente se tornou o navegador mais popular) sabia sobre a proposta do RRP, mas nunca a implementou no Mosaic. Em vez disso, o Mosaic quase imediatamente escolheu o caminho de usar tags HTML para estilização (o que é bastante trágico), adicionando tags como <FONT>e <CENTER>.



Viola e as Guerras dos Navegadores Proto



“Então por que não implementar apenas uma das muitas propostas de folhas de estilo que existem. Com a estrutura certa, isso resolveria quase completamente o problema. "


Então, eu teria que dizer às pessoas: "Tudo bem, você precisa aprender esta linguagem para escrever um documento e, em seguida, aprender outra linguagem para fazer com que o documento tenha a aparência que você deseja." Oh, eles simplesmente adorariam.



- Mark Andreessen, 1994


Ao contrário da crença popular, o Mosaic não foi o primeiro navegador gráfico. Ele foi precedido pelo ViolaWWW , um navegador gráfico originalmente escrito por Pei-Yuan Wei em apenas quatro dias.





Captura de tela do Viola Browser



Pei-Yuan criou uma linguagem de folha de estilo que suporta o tipo de estrutura hierárquica usada em CSS hoje:



(BODY fontSize=normal
      BGColor=white
      FGColor=black
  (H1   fontSize=largest
        BGColor=red
        FGColor=white)
)


Neste caso, estamos aplicando cores ao corpo do documento (corpo) e, em particular, estamos estilizando H1que estão dentro do corpo. Em vez de repetir seletores para controlar esse aninhamento, o PWP usou o sistema de parênteses, o que nos faz pensar nos sistemas de indentação usados ​​em linguagens como Stylus e SASS, que alguns desenvolvedores ainda preferem ao CSS hoje. Isso potencialmente torna a sintaxe PWP melhor em pelo menos um aspecto do que CSS, que evoluiu com o tempo para a linguagem universal da web.



O PWP também é notável pelo fato de ter uma maneira de se referir a folhas de estilo externas, que ainda usamos hoje:



<LINK REL="STYLE" HREF="URL_to_a_stylesheet">


Infelizmente, ViolaWWW foi escrito principalmente para funcionar com o X Window System , que era popular apenas em sistemas Unix. Quando o Mosaic foi adaptado para o Windows, rapidamente trouxe Viola ao pó.



Folhas de estilo antes da web



HTML é o tipo de coisa pela qual apenas um cientista da computação pode se apaixonar. Sim, expressa a estrutura interna de um documento, mas os documentos não são apenas bancos de dados de texto estruturados; eles têm um impacto visual. O HTML destrói completamente qualquer criatividade gráfica que um desenvolvedor de documentos possa ter.



- Roy Smith, 1993


A necessidade de uma linguagem capaz de expressar o estilo dos documentos é muito mais antiga do que a própria Internet.



Como você provavelmente sabe, o HTML que conhecemos foi originalmente baseado em uma linguagem pré-Internet chamada SGML. Em 1987, o Departamento de Defesa dos Estados Unidos decidiu testar se SGML poderia ser usado para simplificar o armazenamento e a transferência de seus enormes volumes de documentação. Como qualquer bom projeto de governo, a primeira coisa que fizeram foi inventar um nome. A equipa foi inicialmente designada por equipa de Apoio Logístico Assistido por Computador, depois equipa de Aquisição Assistida por Computador e Apoio Logístico e, por fim, por iniciativa de Aquisição Contínua e Apoio ao Ciclo de Vida. Em qualquer caso, as iniciais eram CALS.



A equipe do CALS criou uma linguagem para estilizar documentos SGML chamada FOSI. Ela publicouuma especificação de linguagem que é tão detalhada quanto incompreensível. Incluía meu favorito dos infográficos mais sem sentido que já existiram na web.



Uma regra da Internet que não tem exceções é que você sempre fará mais se puder provar que alguém está errado no processo. Em 1993, apenas quatro dias após a proposta de Pei-Yuan, Stephen Heaney propôs que, em vez de reinventar a roda, seria melhor usar a versão FOSI de estilizar a web.



O próprio documento FOSI é escrito em SGML, o que é uma jogada bastante lógica, dada a familiaridade dos desenvolvedores da web com uma versão de SGML chamada HTML. Um exemplo de documento se parece com este:



<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>


Talvez você não entenda o que é docdescou charlist, assim como os membros não entendiam www-talk. A única informação contextual é o que significa e-i-c"elemento no contexto". No entanto, o FOSI é notável pela primeira vez que introduziu a unidade de medida em, que agora se tornou a forma preferida de dimensionamento em CSS.



O conflito de linguagens resultante era, na verdade, tão antigo quanto a própria programação. Foi uma batalha entre a sintaxe do estilo lisp funcional e a sintaxe em linguagens mais declarativas. O próprio Pei-Yuan descreveu sua sintaxe como "semelhante ao LISP", mas foi apenas uma questão de tempo antes que a verdadeira versão do LISP aparecesse em cena.



Folha de estilo Turing-complete



Apesar de sua complexidade, o FOSI foi percebido como uma solução intermediária para o problema de formatação de documentos. O plano de longo prazo era criar uma linguagem baseada na linguagem de programação funcional Scheme, capaz de implementar as mais poderosas transformações de documentos imagináveis. Esse idioma foi denominado DSSSL. Vamos passar a palavra a um dos desenvolvedores da linguagem, John Bosak:



Não confunda DSSSL com uma linguagem de script. Sim, DSSSL é Turing completo; sim, é uma linguagem de programação. Mas a linguagem de script (pelo menos em minha interpretação do termo) é procedimental; e DSSSL definitivamente não é. DSSSL é totalmente funcional e totalmente livre de efeitos colaterais. Nada nunca acontece na folha de estilo DSSSL. Uma folha de estilo é uma função enorme, cujo valor é uma descrição abstrata, independente de dispositivo e não procedimental de um documento formatado, como uma especificação (uma declaração, se desejar) das regiões a serem renderizadas, passada para os renderizadores downstream.


Em sua forma mais simples, DSSSL é de fato uma linguagem de estilo bastante lógica:



(element H1
  (make paragraph
    font-size: 14pt
    font-weight: 'bold))


Por ser uma linguagem de programação, você pode até definir funções nela:



(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))


E use construções matemáticas ao estilizar, por exemplo, para fazer listras nas linhas da tabela:



(element TR
  (if (= (modulo (child-number) 2)
        0)
    ...   ;even-row
    ...)) ;odd-row


Para deixar você ainda mais ciumento, digamos que DSSSL pudesse tratar valores herdados como variáveis ​​e realizar operações matemáticas neles:



(element H1
  (make paragraph
    font-size: (+ 4pt (inherited-font-size))))


Infelizmente, DSSSL tinha uma falha fatal comum a todas as linguagens de estilo Scheme: muitos parênteses. Além disso, sua especificação estava excessivamente completa na época do lançamento final, o que intimidou os desenvolvedores de navegadores. A especificação DSSSL incluiu mais de 210 propriedades de estilo individuais.



O trabalho de desenvolvimento posterior levou à criação de XSL - uma linguagem de transformação de documentos igualmente complicada, mas muito mais popular.



Por que a folha de estilo ganhou



CSS não tem seletores de pai (uma maneira de estilizar um pai com base nos filhos que ele contém). Esse fato tem atormentado os usuários do Stack Overflow por um longo tempo , mas parece que há um bom motivo para sua ausência. Nos primórdios da Internet, era considerado crítico que uma página pudesse ser renderizada antes que o documento fosse totalmente carregado. Em outras palavras, era necessário ser capaz de renderizar o HTML do topo da página antes que o HTML do final da página fosse totalmente carregado.



Ter um seletor pai significaria que os estilos precisam ser atualizados conforme o documento HTML é carregado. Linguagens como DSSSL foram completamente excluídas porque podiam executar operações no próprio documento, que não estava totalmente disponível no momento da renderização. Bert Bose foi o



primeiro a abordar esse problema em março de 1995 e a propor uma linguagem de trabalho para resolvê-lo. Sua proposta também contém uma versão inicial do emoticon "smiley" :-).



A linguagem em si era bastante "orientada a objetos" na sintaxe:



*LI.prebreak: 0.5
*LI.postbreak: 0.5
*OL.LI.label: 1
*OL*OL.LI.label: A


O símbolo .denotou os filhos mais próximos e os *ancestrais.



A linguagem de Bose tinha outra propriedade interessante: você poderia especificar como elementos como links funcionam na própria folha de estilo:



*A.anchor: !HREF


No exemplo acima, especificamos que o endereço de navegação do elemento de link é o valor em seu atributo HREF. Essa ideia de que o comportamento de elementos como links devem ser controlados tem sido popular em muitas outras propostas. Na era pré-JavaScript, não havia como controlar esses aspectos, então parecia lógico incluí-los nessas propostas.



Em um rascunho de uma linguagem funcional, proposta em 1994 por um senhor chamado S.M. Sperberg-McQueen, o mesmo comportamento é implementado funcionalmente:



(style a
  (block #f)     ; format as inline phrase
  (color blue)   ; in blue if youve got it
  (click (follow (attval 'href)))  ; and on click, follow url


Sua linguagem também introduziu a palavra-chave contentcomo uma forma de manipular o conteúdo de um elemento HTML de uma folha de estilo. Este conceito foi adicionado posteriormente no CSS 2.1.



O que a web poderia ser



Antes de falar sobre a linguagem que realmente se tornou CSS, vale a pena mencionar mais uma proposta de linguagem, pelo menos pelo fato de que, em certo sentido, era o sonho dos primeiros desenvolvedores web.



PSL96 foi, como o nome sugere, a versão de 1996 da Presentation Specification Language. Basicamente, o PSL se parece com CSS:



H1 {
  fontSize: 20;
}


No entanto, as coisas rapidamente ficam muito mais interessantes. Por exemplo, era possível expressar a posição de um elemento não apenas dependendo do tamanho ( Width) dado a ele , mas também pelo Actual Widthtamanho true ( ) em que ele é renderizado no navegador:



LI {
  VertPos: Top = LeftSib . Actual Bottom;
}


Você pode ver no exemplo que também pode usar o irmão esquerdo como uma restrição.



Expressões booleanas também podem ser adicionadas a estilos. Aqui está um exemplo de estilização apenas de elementos âncora que possuem href:



A {
  if (getAttribute(self, "href") != "") then
    fgColor = "blue";
    underlineNumber = 1;
  endif
}


Esse estilo poderia ser estendido a todos os tipos de aspectos, para os quais usamos classes hoje:



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
}


O suporte a essa funcionalidade provavelmente permitiria que o sonho de separar o conteúdo do estilo finalmente se tornasse realidade. Infelizmente, essa linguagem é muito extensível, ou seja, havia uma grande probabilidade de que sua implementação fosse muito diferente em navegadores diferentes. Além disso, foi publicado em uma série de artigos no mundo científico, e não na lista de discussão www-talk, onde ocorreu a maior parte do trabalho construtivo. Ele nunca foi integrado a nenhum navegador popular.



CSS fantasma do passado



A linguagem que poderia levar diretamente à criação de CSS (pelo menos como o nome sugere) era CHSS (Cascading HTML Style Sheets). Foi proposto em 1994 por Håkon W Lie.



Como a maioria das boas ideias, a proposta inicial era bem maluca.



h1.font.size = 24pt 100%
h2.font.size = 20pt 40%


Preste atenção aos percentuais no final das regras. Essa porcentagem significa quanta "propriedade" a folha de estilo atual tem sobre esse valor. Por exemplo, se a folha de estilo anterior h2tinha um tamanho de fonte especificado 30ptpara 60%"propriedade" e essa folha de estilo h2especificou um estilo para 20px 40%, os dois valores podem ser combinados com base em sua porcentagem de propriedade para produzir um valor de aproximadamente 26pt.



É bastante compreensível por que tal proposta foi feita na era das páginas HTML de documentário: tal design baseado em trade-offs não seria compreendido em nosso mundo orientado a aplicativos. Seja como for, surgiu com a ideia fundamental da necessidade de uma estrutura de folha de estilo em cascata. Em outras palavras, a ideia de que várias folhas de estilo são necessárias na mesma página.



Em sua formulação original, essa ideia foi geralmente reconhecida como importante porque dava ao usuário final o controle sobre o que via. A página original pode ter uma folha de estilo e o usuário da web pode ter sua própria folha de estilo e eles podem ser combinados para renderizar a página. O suporte a várias folhas de estilo era visto como uma forma de preservar a liberdade pessoal na web, não como uma forma de apoiar os desenvolvedores (que ainda codificam manualmente cada página HTML).



O usuário pode até mesmo ser capaz de controlar o grau de controle que deu às recomendações do autor da página; tal controle em uma frase de linguagem foi descrito por um 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 muitas dessas suposições, este projeto continha recursos que apareceram no CSS apenas décadas depois, senão mesmo. Por exemplo, ele tinha a capacidade de escrever expressões lógicas com base no ambiente do usuário:



AGE > 3d ? background.color = pale_yellow : background.color = white
DISPLAY_HEIGHT > 30cm ? http://NYT.com/style : http://LeMonde.fr/style


Em uma visão bastante otimista de ficção científica do futuro, acreditava-se que o navegador saberia o quão relevante cada elemento de conteúdo é para o usuário, permitindo que ele fosse exibido em um tamanho maior:

RELEVANCE > 80 ? h1.font.size *= 1.5


Todos nós sabemos o que aconteceu depois



A Microsoft está totalmente comprometida com os padrões abertos, especialmente na Internet.



- John Ludeman, 1994


Haakon Lee continuou a trabalhar na simplificação de sua proposta e, juntamente com Bert Bose, publicou a primeira versão da especificação CSS em dezembro de 1996. Ele acabou escrevendo sua tese de doutorado sobre a criação de CSS e este documento me ajudou tremendamente a escrever este artigo.



Comparado a muitas outras propostas, o aspecto notável do CSS foi sua simplicidade. É fácil de analisar, escrever e ler. Como sempre aconteceu na história da Internet, o vencedor é a tecnologia mais fácil de dominar para um iniciante, e não aquela que se revelou a mais poderosa para os especialistas.



Isso por si só é um lembrete de como a inovação aleatória pode ser. Por exemplo, suporte para seletores contextuais (body ol li) só foi adicionado porque o Netscape já tinha uma maneira de remover bordas de imagens que eram hiperlinks e parecia necessário fazer tudo que o navegador popular podia fazer. A própria funcionalidade causou um atraso significativo na implementação do CSS, porque na época, a maioria dos navegadores não armazenava uma "pilha" de tags ao analisar HTML. Isso significava que os analisadores precisavam ser reprojetados para oferecer suporte total ao CSS.



Por causa desses problemas (e do uso generalizado de tags HTML não padrão para estilização), o CSS não era utilizável até 1997 e não era totalmente compatível com nenhum navegador até março de 2000. Como qualquer desenvolvedor lhe dirá, o suporte ao navegador estava muito longe de ser compatível com os padrões e isso mudou há apenas alguns anos, quinze anos após o lançamento do CSS.





Netscape 4 CSS, <body>, , IE4 <body> , , CSS ? CSS. , IE4 , Netscape 4.





O Internet Explorer 3 é conhecido por ter sido lançado com (bastante terrível) suporte CSS. Foi decidido que, para poder competir no Netscape 4, essa linguagem também deve ser suportada. No entanto, em vez de redobrar os esforços para implementar esta terceira linguagem (depois de HTML e JavaScript), decidiu-se que ela deveria ser implementada transformando CSS em JavaScript e, em seguida, executando-o. Pior, foi decidido que esta folha de estilo JavaScript intermediária deveria estar disponível para desenvolvedores da web .



A sintaxe era JavaScript simples com a API de estilo adicionada:



tags.H1.color = "blue";
tags.p.fontSize = "14pt";
with (tags.H3) {
  color = "green";
}

classes.punk.all.color = "#00FF00"
ids.z098y.letterSpacing = "0.3em"


Foi ainda possível definir funções cujos valores foram calculados ao encontrar cada ocorrência de uma tag :



evaluate_style() {
  if (color == "red"){
    fontStyle = "italic";
  } else {
    fontWeight = "bold";
  }
}

tag.UL.apply = evaluate_style();


A ideia de simplificar a linha divisória entre estilos e scripts é bastante razoável, e hoje está até renascendo na comunidade React .



O próprio JavaScript era uma linguagem muito jovem na época, mas graças à engenharia reversa, o suporte para ele foi adicionado no IE3 (na forma de JScript). Um problema muito maior era que a comunidade já estava se reunindo em torno do CSS na época, e o Netscape era visto como um infrator pela maioria da comunidade de padrões da época . Quando a Netscape propôs o JSSS ao comitê de padrões, ela fez ouvidos moucos. Três anos depois, o Netscape 6 abandonou o suporte para JSSS e ele morreu gradualmente.



O que poderia nos esperar



Graças à censura pública do W3C, o Internet Explorer 5.5 foi lançado com suporte quase total para CSS1 em 2000. Claro, como sabemos agora, as implementações de CSS do navegador têm sido terrivelmente problemáticas e difíceis de trabalhar por pelo menos mais uma década. Felizmente, hoje a situação melhorou significativamente, o que finalmente tornou possível realizar o sonho dos desenvolvedores de que você pode escrever código uma vez e ele funcionará (quase) da mesma forma em diferentes navegadores.



Pessoalmente, deduzi de tudo isso o quão arbitrárias e contextuais eram as decisões que governam nossas ferramentas modernas. Se o CSS foi projetado para ser compatível com as restrições de 1996, talvez vinte e tantos anos depois isso nos dê permissão para fazer as coisas de uma maneira um pouco diferente.



All Articles