Tableless - Desenvolvimento inteligente com Padrões Web

15/12/2010
CSS

JQuery para produção de Layouts

Quando falta a compatibilidade de algumas propriedades do CSS nos browsers ou porque quando não é possível manipular o HTML manualmente para suprir suas necessidades, o JQuery poderá ajudar.

Por


O JQuery tem me dado um importante suporte para aqueles problemas que o CSS não consegue resolver por falta de compatibilidade em alguns browsers e também para evitar sujar o código HTML com elementos dispensáveis, em ocasiões comuns como no caso da criação de bordas arredondadas.
Nestes cenários, invarialmente temos que criar alguns elementos agregados que servirão para dar exclusivamente suporte visual para o layout.
Não é bom que sujemos nosso HTML com código que não carregue significado semântico nenhum, mas em alguns casos, como ao fazer bordas arredondadas, a criação destes elementos é necessária. É nesse ponto que o JQuery pode nos ajudar grandemente.

Se você é desenvolvedor client-side, tenha em mente que você não precisa saber programar para aprender JQuery. Sua sintaxe é muito simples e pode salvar sua vida quando ocorre problemas de compatibilidade entre browsers. É o que veremos a seguir: como o JQuery pode nos auxiliar em momentos da falta de suporte do CSS.

Criando elementos dinamicamente

Suponha que você tenha um botão simples, onde as bordas são arredondadas. Para facilitar nosso exemplo esse botão não terá altura variável, apenas largura. Eu poderia fazer duas imagens: uma imagem seria a borda da esquerda e a outra imagem a borda da da direita. Se fôssemos fazer com HTML e CSS puro, o código seria esse:

1
<a href="#" class="btn">texto do botão</a>

O CSS:

1
2
3
.btn {
  border-radius:10px;
}

Talvez eu teria que colocar um prefixo para o Frefox (-moz-) entender a borda arredondada, mas vamos simplificar nosso exemplo.

Os IE7-8 não reconheceriam essa propriedade. Mas se seu cliente precisa de que o suporte seja estendido para esses browsers, não há outra escolha a não ser fazer as benditas bordas (ou qualquer outro problema) funcionar no IE.

Uma maneira simples de ser feita é colocando um backgrounds diretamente no LINK, pode ser a borda da esquerda e em outro elemento definiríamos a borda da direita. Criar um elemento para que sua única função seja manter o padrão visual vai de encontro contra toda a ideia de semântica. Fazendo isso também misturamos aquela teoria de separação de formatação com informação. Mesmo assim essa a única solução. É aí que o JQuery vem nos ajudar. O código HTML, caso fossemos criar um elemento extra, seria:

1
<a href="#" class="btn">texto do botão <span class="borderdir"></span></a>

Para mantermos a integridade do nosso HTML, criaremos esse elemento via JQuery da seguinte forma utilizando a função JQuery.com/append/”>append:

1
2
3
$(document).ready(function(){
    $('.btn').append('<span class="borderdir" />');
});

Já que estes elementos são cridos dinamicamente, os leitores de tela e os indexadores de busca não os leem, logo, o código HTML não fica poluído e você não perde com SEO. A manutenção fica simples de ser mantida e o HTML, se já estiver sob programação server-side não precisará ser modificado manualmente.

Escolhendo elementos específicos

Outro problema muito comum é a necessidade de ter que escolher elementos específicos no Layout sem ter que adicionar manualmente classes ou tendo que fazer uma condição maluca para ter que capturar tais elementos. Isso seria muito simples se utilizássemos o pseudo-elemento nth-child do CSS. O nth-child seleciona determinados elementos em uma árvore de elementos. Por exemplo, você tem uma lista e quer pegar o terceiro ítem da lista, você utilizaria algo assim:

1
2
3
ul li:nth-child(3n) {
    color:red;
}

O problema? Nada disso funciona nos IEs. Mas isso é extremamente útil e com JQuery você pode adicionar uma classe nestes elementos para formatar com CSS.
A Home deste site foi feita desta forma. O conteúdo foi criado com um simples LOOP do WordPress que joga o HTML do conteúdo em uma única página. Veja que cada um blocos de texto desta home é diferente. Sem poder utilizar o nth-child eu utilizei a função JQuery.com/slice/”>slice do JQuery:

1
2
3
4
5
6
$(document).ready(function(){
    $('.homeposts article').slice(1, 3).addClass('destaqueprincipal');
    $('.homeposts article').slice(3, 6).addClass('destaquethird');
    $('.homeposts article').slice(6, 10).addClass('destaques');
    $('.homeposts article').slice(10, 12).addClass('chamadas');
});

Por exemplo, note essa linha:

1
2
3
$(document).ready(function(){
    $('.homeposts article').slice(1, 3).addClass('destaqueprincipal');
});

Aqui eu digo que o primeiro, segundo e terceiro e elemento article de .homeposts terão uma classe adicional chamada destaqueprincipal. E a mesma lógica foi aplicada para os elementos posteriores.

Utilizando seletores complexos

Outro problema é a inserção de classes em elementos do mesmo gênero mas com funções diferentes, como os campos de formulários. Normalmente, quando produzimos um formulário de contato, por exemplo, precisamos diferenciar os inputs de texto, inputs de checkbox, inputs de radio, inputs de submit etc. Pode ser que estes inputs sejam criados dinamicamente pelo framework utilizado para auxiliar na programação back-end. Nesse caso não temos controle manual nenhum.
No melhor dos mundos utilizaríamos seletores complexos para aplicar um estilo específico para um dos elementos. A sintaxe em CSS ficaria mais ou menos assim:

1
2
3
input[type="text"] {
    border:1px solid gray;
}

O código acima define uma borda preta para os elementos input que tenham o atributo type cujo valor seja text. Você faria isso para cada um dos tipos dos inputs que você gostaria de formatar:

1
2
3
4
input[type="text"] {border:1px solid gray;}
input[type="checkbox"] {border:1px solid green;}
input[type="submit"] {border:1px solid red;}
input[type="radio"] {border:1px solid yellow;}

Esse código pode não funcionar em alguns browsers, por isso faremos com a ajuda de JQuery.
O código é muito simples e na realidade não foge muito da sintaxe do CSS. Adicionaremos uma classe para cada um destes elementos possibilitando a estilização via CSS por meio dessa classe. O código ficaria assim:

1
2
3
4
5
6
$(document).ready(function(){
    $('input[type="text"]').addClass('inputText');
    $('input[type="checkbox"]').addClass('inputCheckbox');
    $('input[type="submit"]').addClass('inputSubmit');
    $('input[type="radio"]').addClass('inputRadio');
});

Com as classes atribuídas, podemos temos controle total via CSS.

Conclusão

Estas pequenas dicas contribuem para soluções sustentáveis para seu código. Com um pouco de planejamento você conseguirá manter o controle total do seu código e um alto índice de compatibilidade com os browsers atuais no mercado. A diminuição de hacks no CSS também diminui bastante já que com uma mesma solução, você abrange até os browsers mais antigos.

Por Diego Eis

Diego Eis criou o Tableless para disseminar os padrões web no Brasil. Como consultor já treinou equipes de empresas como Nokia, Globo.com, Yahoo! e iG. É palestrante e empreendedor.

http://twitter.com/diegoeis/

Veja os outros posts de

  • http://www.wallacerick.com.br Wallace Erick

    Artigo de bastante ajuda… Sugiro criar algum falando de odd, even, e esses outros… tão coisas simples que ajudam bastante e não poluem de class e id o código.

  • http://www.daviferreira.com/blog Davi Ferreira

    Uma dica sobre os seletores de form é que eles podem ser substituídos por pseudo-seletores:

    $(‘input:text’)
    $(‘input:checkbox’)
    $(‘input:radio’)
    $(‘input:submit’)

  • Pingback: Tweets that mention JQuery para produção de Layouts | Boas práticas de Desenvolvimento com Padrões Web -- Topsy.com

  • http://www.imgnation.com.br Bruno Gama

    Legal e para completar toda magia fazer wrap desse javascript todo numa função anônima para não entupir o código de sujeira :D

  • http://www.vintedois.com.br Shankar Cabus

    Sou totalmente contra hacks, mas esta solução com jQuery também não acho uma boa opção para garantir compatibilidade entre browsers, pois fere a organização do código. Devemos evitar ao máximo colocar HTML no JS, JS no HTML, CSS no HTML e CSS no JS.

    JavaScript é última camada, para prover interação com o usuário, executando ações. Deixar elementos do layout a cargo da execução de JavaScript é preocupante. Em alguns casos ele não executa também como gostaríamos, principalmente em páginas de conteúdo dinâmico.

    Mas concordo com o uso do jQuery para selecionar elementos especiais, já que os IEs não não suportam a maioria desses seletores. Tem que saber usar com moderação.

    Bem, como disse, hack não é solução pra nada, é apenas mais um problema, então considero uma das melhores soluções o uso de múltiplas folhas de estilo com comentário condicional (para páginas estáticas).

    Já para as páginas dinâmicas, existe uma solução mais elegante, que é a identificação do browser pelo servidor., que já monta a página com uma classe no BODY com o nome do browser. Depois fica fácil usar propriedades específicas para cara browser.

    Ex:

    #verMais { margin: 20px }
    body.ie7 #verMais { margin-left: 10px; }

  • Pingback: Tweets that mention JQuery para produção de Layouts | Boas práticas de Desenvolvimento com Padrões Web -- Topsy.com

  • Pingback: Tweets that mention JQuery para produção de Layouts | Boas práticas de Desenvolvimento com Padrões Web -- Topsy.com

  • http://diegoprates.com.br Diego Prates

    Parabéns pelo artigo, foram apresentados alguns problemas comuns que nós desenvolvedores encontramos no dia-a-dia, e que muitas vezes quebramos a cabeça (entenda-se procuramos no google) para solucionar.

  • http://twitter.com/juliobitencourt Julio Bitencourt

    O ruim é ter que recorrer à isto por causa dos IEs. Concordo em partes com o Shankar. Mas é quase impossível não sujar o HTML para contornar problemas de incompatibilidade entre os browsers.

    Ultimamente aqui na agência estamos utilizando muito Graceful Degradation. Estamos utilizando Gradientes, Shadows e Bordas redondas somente nos navegadores que suportam, desde que não prejudiquem muito a estética.

    Para nossa surpresa, muitos clientes tem entendido o problema e aceitado esta prática.

  • http://barraponto.blog.br Capi Etheriel

    No exemplo do loop em WordPress, porque você não colocou a classe no PHP direto? Por uma questão semântica?

  • http://twitter.com/sigmus76 Flávio Medeiros

    Sobre JavaScript ajudando nos seletores complexos, isso aqui parece interessante:

    http://selectivizr.com/
    (retirado daqui:
    http://www.smashingmagazine.com/2010/12/10/why-we-should-start-using-css3-and-html5-today/
    )

    Alguém já testou isso?

  • http://blog.sergiorodrigues.art.br/ Sérgio Rodrigues

    Caro Shankar Cabus, não entendi sua posição, você se diz contra qualquer tipo de ‘hack’ mais em seu exemplo de “não uso” de ‘hacks’ você usou um código que pra mim se caracteriza como um ‘hack’, gostaria que você se expressasse melhor, pois a duvida ficou no ar..Ótimo texto Diego.

  • http://tutorial-city.net/ Eduardo Matos

    Sempre uso um script chamado Selectivizr. Essa biblioteca dá suporte nativo ao CSS pra seletores complexos para o Internet Explorer. Você pode usar a:nth-child(5) e ficar tranquilo quanto ao funcionamento no IE6 por exemplo. A única coisa que precisa é de um framework de javascript (jQuery ou Mootools ou Prototype ou … são muitas opções), e como quase sempre usamos um, não vejo nisso um problema.
    Não imagino um motivo pra não usar essa solução. Até hoje não vi solução melhor.

  • Capi Etheriel

    Cara, acho que seu site está com algum problema. Veja como ele fica em uma tela de netbook, 1024×600: http://imm.io/2CIn

    Além disso, slice(1,3) seleciona do segundo ao quarto elemento, e slice(3,6) seleciona do quarto ao sétimo. Você quer mesmo dar todas essas classes pro quarto elemento?

  • Giovani Generali

    Legal Diego, essas soluções quebram um galhão!

    Um comentário sobre essa frase “Se você é desenvolvedor client-side, tenha em mente que você não precisa saber programar para aprender JQuery”

    Na minha opnião se o cara é um devel client-side ele deve saber sim, não adianta entrar no jQuery se você não tem nenhuma base de JS. Por isso que vejo muita sujeira por ai :)

    Abs.

  • http://www.vintedois.com.br Shankar Cabus

    Sérgio Rodrigues, desculpa se não fui claro, talvez tenha faltado explicar o que é hack. Dá uma lida nesse texto do próprio Diego Eis que explica muito bem: http://tableless.com.br/csshacks

    Resumidamente, hacks sao “técnicas” (para não chamar de gambiarras) que exploram falhas na interpretação do CSS de alguns browsers, ou seja, alguns caracteres como * e _ são ignorados por alguns browsers e interpretados (como erro) por outros.

    Ex de hack:

    body {
    background-color: red; /* Todos os browsers */
    background-color /*\**/: pink\9; /* Apenas IE8 */
    *background-color: blue; /* IE6 e IE7 */
    _background-color: black; /* IE6 */
    }

    Abraços

  • http://rafael.bernard-araujo.com/ rafael bernard rodrigues araújo

    Diego, achei muito interessante a solução proposta, pois, a mim, parece que continuamos escravos do hack em algum momento e este parece um “hack” menos intrusivo, nocivo e trabalhoso.

    O ganho que temos com a compatibilidade de navegadores se estende no uso de dispositivos móveis? O jQuery ainda não está engatinhando para estes dispositivos?

  • http://www.vintedois.com.br Rafael Verger

    Bem, estou com o Shankar e com Eduardo Matos.

    O :select[ivizr] é realmente um script excelente para habilitar os seletores de CSS3 para os browsers não modernos (IE6~8).

    Mas, para problemas de layout, ou melhor, de renderização de elementos diferente em cada browser, a solução que o Shankar propôs é a melhor. Não necessita nem de uma programação avançada ou utilização de tecnologias como jsp ou asp para implementá-la, é possível fazer com javascript ou como o Paul Irish sugere.

    Por que a solução com a adição de classes à tag html/body é melhor? Simples, se você é adepto à solução que o Diego Eis sugere, você pode correr o risco do usuário, mesmo tendo o javascript habilitado, ver a página “errada” até que o $(document).ready() seja executado, já com esta solução que propomos, não há a necessidade de esperar o documento ser totalmente carregado para aplicar as classes, basta que a tag body já tenha sido impressa na página, então o usuário já verá o a renderização correta (utilizando as classes .msie6 como Shankar disse).

    Sobre isso ser um hack, é falso. A única característica que aproxima essas técnicas é que ambas necessitam de mais linhas de código.

  • Pingback: Tropeçando 38 | Rafael Bernard Araujo

  • Pingback: Escalabilidade client-side | Tableless - Desenvolvimento com Padrões Web

  • Pingback: CSS3: Cantos arredondados, sombras e degradês até no IE | Klaus Laube

  • http://leobalter.net Leo Balter

    Um comentário em relação a uma frase em específico: “Se você é desenvolvedor client-side, tenha em mente que você não precisa saber programar para aprender JQuery”.

    Discordo, mas não diretamente ao conceito da frase, mas sim que quando alguém é desenvolvedor, deveria estar implícito que ele sabe desenvolver, logo ele deve saber programar.

    Desenvolvedor client side não é apenas implementador html/css, há uma diferença gritante entre um profissional e outro, além de fazer uma diferença enorme.

    O que diferencia o Desenvolvedor Client Side de um Implementador é justamente a programação, o conhecimento em Javascript. Assim como um Designer também pode saber o mesmo que um Implementador (além das outras características de um designer) e nem por isso ele é um Desenvolvedor (não necessariamente).

    Em relação a saber jQuery sem precisar saber programar, isso é um perigo enorme. Claro que é tranquilo utilizar um plugin, mas não saber o que está fazendo pode se tornar vital ao projeto, sem contar que as chances de fazer sobrinhada aumentam consideravelmente.

    Outra parte que é conveniente comentar:

    $(‘.homeposts article’).slice(1, 3).addClass(‘destaqueprincipal’);
    $(‘.homeposts article’).slice(3, 6).addClass(‘destaquethird’);
    $(‘.homeposts article’).slice(6, 10).addClass(‘destaques’);
    $(‘.homeposts article’).slice(10, 12).addClass(‘chamadas’);

    Muito cuidado pois código nessa forma causa problemas sérios de performance, que podem ser resolvidos facilmente com uma referência do objeto selecionado em uma variável. Pra entender isso é o momento onde a pessoa já tem que conhecer pelo menos um básico de programação.

  • http://leobetosouza.com/ Leonardo Alberto Souza

    Já tive tantos problemas com esse negócio de controlar a apresentação (o trabalho das CSS) via JavaScript que hoje em dia abomino completamente esse tipo de coisa.

    Pode ser uma mão na roda fazer $(elemento).css({background:”#f00″,color:”#fff”});, mas na hora da manutenção isso costuma causar umas dores de cabeças (a sua e do resto da equipe) bem desagradáveis, principalmente se não foi você quem escreveu o código.

    Se contar no problema de performance. É o usual “meu site tá lento pra renderizar e eu não sei o porque.”

    E reforçando o que o Leo Balter disse, mesmo sabendo que o Diego não concorda (já não é o primeiro artigo que ele fala o contrário): Desenvolvedor Client-side, Front-end ou seja lá que nome seja dado precisa saber JavaScript sim!

    Só recortar layouts com um HTML/CSS legal não torna o cara um desenvolvedor. Configurar um plugin do jQuery também não. O que define o cara ser um desenvolvedor é desenvolver (dãã), ou seja programar. E a línguagem de programação client-side é JavaScript. HTML, como o nome diz, é uma linguagem de marcação.

  • http://tcelestino.com.br Tiago Celestino

    Algum tempo atras tb achava q nao precisava saber já para usar jquery, entre outros frameworks, porém, uma coisa que fiquei espantado é que para coisas simples, como um sumir um elemento, desenvolvedores utilizavam o jquery, ou seja, muita gente sabe usar o framework mas num sabe usar a base do framework.

    Acho valido ter que aprender js para depois usar um framework que facilite o trabalho.