Archive for the “css” Category

Palestra Engenharia de frontend de alta performance

Minha palestra sobre frontend de alta performance no frontinrio, que aconteceu dia 18/06/2011

jun 20, 2011 Posted Under: css, front in rio, html, javascript, palestra   Read More

Plugin jQuery para highlight em células de tabelas

Um dia desses estava no trabalho quando o AI (arquiteto de informação) me apresentou uma tabela cheia de efeitos no hover, você pode ver uma imagem dessa tabela ai embaixo.

Ele me explicou que quando o usuário passasse o mouse pela tabela as células anteriores, das respectivas linha e coluna, seriam marcadas por um background e quando clicasse a célula clicada ficaria marcada.

Como não era urgente e eu nunca tinha visto isso sendo feito com HTML logo fiz cara feia e que não saberia se seria possível fazer de uma forma que tivesse uma boa performance, para não deixar a página lenta por causa de um background bobo.

Logo pedi pra ele me mostrar um exemplo disso funcionando, o primeiro que não era exatamente o que ele queria não era uma tabela, na verdade era, mas feita com divs, ou seja, POG das brabas, eu imediatamente soltei um “rá eu te disse”, mas ele me mostrou outro exemplo que realmente era uma tabela, mas também não era exatamente o que ele queria.

Só para sacanear disse que iria tentar fazer, mas p ele ficar sabendo que o resultado seria horrível.

Alguns dias passaram e lembrei-me da tabela e por algum motivo, junto da lembrança da tabela veio a solução do problema, parei o que estava fazendo para testar a solução abaixo. Lembrando que estamos trabalhando com jQuery.

$(document).ready(function(){
	$('table.tab td').click(function(){
		$(this).parents('table').eq(0).find('td,th').each(function(){ $(this).removeClass('on'); });
		$(this).addClass('on');
		$(this).prevAll().addClass('on');
		var x  = $(this).prevAll().length;
		$(this).parent().prevAll().each(function(){
			$(this).find('>*').eq(x).addClass('on');
		});
		$(this).parents('table').eq(0).find('tr:first-child th').eq(x).addClass('on');
	}).hover(function(e){
		$(this).parents('table').eq(0).find('td,th').each(function(){ $(this).removeClass('on2'); });
		$(this).addClass('on2');
		$(this).parent().find('>:first-child').addClass('on2');
		var x  = $(this).prevAll().length;
		$(this).parents('table').eq(0).find('tr:first-child th').eq(x).addClass('on2');
	});
});

Agora vamos entender o que fiz, ah o HTML pra tabela que fiz foi esse aqui.

<table class="tab" border="1">
	<thead>
		<tr>
			<th> </th>
			<th><span>DOM</span> 24/12</th>
			<th><span>SEG</span> 25/12</th>
			<th><span>TER</span> 26/12</th>
			<th><span>QUA</span> 27/12</th>
			<th><span>QUI</span> 28/12</th>
			<th><span>SEX</span> 29/12</th>
			<th><span>SAB</span> 30/12</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<th><span>DOM</span> 24/12</th>
			<td><span>1</span></td>
			<td><span>2</span></td>
			<td><span>3</span></td>
			<td><span>4</span></td>
			<td><span>5</span></td>
			<td><span>6</span></td>
			<td><span>7</span></td>
		</tr>
		<tr>
			<th><span>SEG</span> 25/12</th>
			<td><span>1</span></td>
			<td><span>2</span></td>
			<td><span>3</span></td>
			<td><span>4</span></td>
			<td><span>5</span></td>
			<td><span>6</span></td>
			<td><span>7</span></td>
		</tr>
		<tr>
			<th><span>TER</span> 26/12</th>
			<td><span>1</span></td>
			<td><span>2</span></td>
			<td><span>3</span></td>
			<td><span>4</span></td>
			<td><span>5</span></td>
			<td><span>6</span></td>
			<td><span>7</span></td>
		</tr>
		<tr>
			<th><span>QUA</span> 27/12</th>
			<td><span>1</span></td>
			<td><span>2</span></td>
			<td><span>3</span></td>
			<td><span>4</span></td>
			<td><span>5</span></td>
			<td><span>6</span></td>
			<td><span>7</span></td>
		</tr>
		<tr>
			<th><span>QUI</span> 28/12</th>
			<td><span>1</span></td>
			<td><span>2</span></td>
			<td><span>3</span></td>
			<td><span>4</span></td>
			<td><span>5</span></td>
			<td><span>6</span></td>
			<td><span>7</span></td>
		</tr>
		<tr>
			<th><span>SEX</span> 29/12</th>
			<td><span>1</span></td>
			<td><span>2</span></td>
			<td><span>3</span></td>
			<td><span>4</span></td>
			<td><span>5</span></td>
			<td><span>6</span></td>
			<td><span>7</span></td>
		</tr>
		<tr>
			<th><span>SAB</span> 30/12</th>
			<td><span>1</span></td>
			<td><span>2</span></td>
			<td><span>3</span></td>
			<td><span>4</span></td>
			<td><span>5</span></td>
			<td><span>6</span></td>
			<td><span>7</span></td>
		</tr>
	</tbody>
</table>

Primeiramente defini o hook para a tabela com o seletor (‘table.tab td’), e adiciono o evento de hover em todos os TDs.

	$('table.tab td').hover(function(){
		//hover
	});

Feito isso passo a adicionar a classe on2 no TD com hover

		$(this).addClass('on2');

Mas antes de adicionar a classe do hover preciso remover qualquer outra classe on2 que possa ter em um TD, já que quando tirar o mouse de cima do TD tem que voltar ao estado sem background.

		$(this).parents('table').eq(0).find('td,th').each(function(){ $(this).removeClass('on2'); });

Após isso é que começa a brincadeira, primeiro pego todos os TDs, da mesma TR (linha), antes do TD com hover e adiciono a classe on2 também.

		$(this).prevAll().addClass('on2');

Agora veio a parte “mais chatinha” de ser feita. Dentro dessa tabela e dentro desse TR, pegar qual o índice do TD com hover, para poder colocar a classe on2 nos TDs da coluna.

		var x  = $(this).prevAll().length;
		$(this).parent().prevAll().each(function(){
			$(this).find('>*').eq(x).addClass('on2');
		});

Feito tudo isso a parte do hover estava pronta e devidamente testada, parti pra parte do click, que vai marcar a célula (TD) da tabela, então adiciono o evento de click adicionando a classe on para marcar.

	$('table.tab td').click(function(){
		$(this).addClass('on');
	});

Mas perae, tem que remover o estilo dos outros TDs que já foram clicados.

		$(this).parents('table').eq(0).find('td,th').each(function(){ $(this).removeClass('on'); });

Agora vamos transformar isso tudo em plugin, para não ter que repetir o código várias vezes, caso alguém ache motivos para fazer isso, ou colocar vários seletores, ou qualquer outro motivo que não seja somente a chamada do plugin.

( function( jQuery ) {
	jQuery.fn.highlightTable = function() {
		this.click(function(){
			jQuery(this).parents('table').eq(0).find('td,th').each(function(){ jQuery(this).removeClass('on'); });
			jQuery(this).addClass('on');
			jQuery(this).prevAll().addClass('on');
			var x  = jQuery(this).prevAll().length;
			jQuery(this).parent().prevAll().each(function(){
				jQuery(this).find('>*').eq(x).addClass('on');
			});
			jQuery(this).parents('table').eq(0).find('tr:first-child th').eq(x).addClass('on');
		}).hover(function(e){
			jQuery(this).parents('table').eq(0).find('td,th').each(function(){ jQuery(this).removeClass('on2'); });
			jQuery(this).addClass('on2');
			jQuery(this).parent().find('>:first-child').addClass('on2');
			var x  = jQuery(this).prevAll().length;
			jQuery(this).parents('table').eq(0).find('tr:first-child th').eq(x).addClass('on2');
		},function(){
			jQuery(this).parents('table').eq(0).find('td,th').each(function(){ jQuery(this).removeClass('on2'); });
		});
	};
} )( jQuery );

$(document).ready(function() {
    $("table.tab td").highlightTable();
});

Ah, mais uma coisinha de última hora, quando der o “blur”,entre aspas que o evento está mais para hover out mas não lembro de um nome para esse evento, da tabela remover a classe on2 para não ter nenhuma marcação de hover

,function(){
	jQuery(this).parents('table').eq(0).find('td,th').each(function(){ jQuery(this).removeClass('on2'); });
}

Bom, é isso espero que seja útil para muitas pessoas, gostou, não gostou, achou um bug ou simplesmente que falar alguma coisa comenta ai embaixo.

Ate a próxima.

Ah, já ia esquecendo o link para o exemplo funcional do plugin de highlight de hover e click em células de tabelas.

Desafio do leitor: Outro exemplo de dois backgrounds na mesma página; Missão dada, é missão cumprida!!!

O leitor Marco lançou um desafio, utilizar a técnica de dois backgrounds de uma forma um pouco diferente, ao invés de um background p repetir em X e Y, e outro p repetir somente em x, ele quer dois backgrounds na vertical, sendo que ele testou da seguinte forma no css:

html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
html {
  background: transparent url(images/bg_02.gif) repeat-y 0 0;
}
body {
  background: transparent url(images/bg_01.gif) repeat-y right 0;
}


E as palavras dele sobre o código:

Ao deslizar a barra de rolagem, observe que o background da tag body não segue até o final, pois este possui [height:100%], ou seja, 100% da área visível do browser. E se colocar [height:auto], o background segue o tamanho do conteúdo inserido no documento, ou seja, se não houver conteúdo, não haverá background na tag body.”

Então quando temos um conteúdo maior do que a área util do browser, o bg do body não continua repetindo, segundo ele um pequeno bug no Firefox (não tenho uma opinião sobre ser ou não um bug do Firefox, pois eu tenho um pensamento um pouco radical, se ta diferente no IEca e no Firefox o IEca ta errado.) testei no Opera e aconteceu a mesma coisa que no Firefox, e que ao colocar height: auto, até funciona, mas caso nao tenha conteúdo o bg não aparece.

Eis que entra um pequeno truque, que fez funcionar no Firefox e no Opera, no IE já estava “funcionando”, então é só colocar um height: auto !important; e um min-height: 100%; no body, mas para não ter dúvidas colocamos no html também, mas só no body já resolve o problema…

[UPDATE]
O leitor percebeu uma falha minha, por pura preguiça minha, e talvez um pouco de organização demais, coloquei o height:auto !important; min-height: 100%; no html e no body, o que faz voltarmos ao erro de nao exibir o bg caso nao tenha conteudo.. Obrigado Marco ou Allan…
[/UPDATE]

html, body {
  height:auto !important;
  height: 100%;
  min-height: 100%;
  margin: 0;
  padding: 0;
}
html {
  background: transparent url(images/bg_02.gif) repeat-y 0 0;
}
body {
  height:auto !important;
  min-height: 100%;
  background: transparent url(images/bg_01.gif) repeat-y right 0;
}


O height: auto !important é para os browsers que nao reconhecem o min-height, o IEca não precisa pois ele ignora sumariamente que tenha uma altura fixa, que não é este o caso, o min-height é para os browsers que interpretam e vão forçar para que eles tenham uma altura minima, no nosso caso 100%.

O exemplo funcionando pode ser visto aqui.

Então ai está, missão dada, é missão cumprida. Se aparecerem outras dúvidas mandem, quem sabe a sua dúvida não vira um ‘desafio do leitor‘.

fev 20, 2008 Posted Under: css, desafio do leitor, dicas, exemplos, praticando   Read More

Dois backgrounds na mesma página com CSS

Esta semana desenvolvendo um projeto, me deparei com o seguinte problema, dois backgrounds em direções diferentes um horizontal no alto da tela e outro vertical.

A primeira coisa que pensei foi que teria que colocar uma div com 100% de altura e largura para poder colocar esses dois backgrounds, para eu não ter que fazer uma imagem gigantesca. Só que foi não querendo colocar uma div para fazer o papel de um “segundo body”, que tive uma brilhante idéia, vou colocar uma das imagens na tag html e a outra no body.

html, body {
   margin: 0;
   padding: 0;
 }
html {
   background: #0ff url(images/bg_02.gif) repeat 0 63px;
}
body {
   background: transparent url(images/bg_01.gif) repeat-x 0 0;
}

As imagens:
exemplo de solução de problema
exemplo de solução de problema

Só que ai veio o problema a unica imagem que aparecia era a que estava na tag html, que estranhamente assim que se retirava o css da tag html aparece o bg da tag body.

Foi ai que percebi, na minha opinião, um bug de renderização/interpretação do css, e logo vi que tinha que achar um jeito para resolver isso, foi em minha terceira tentativa que tive sucesso no que queria fazer, coloquei as tags html e body com height: 100%, e assim resolvi o problema.

html, body {
   height: 100%;
   margin: 0;
   padding: 0;
 }
html {
   background: #0ff url(images/bg_02.gif) repeat 0 63px;
}
body {
   background: transparent url(images/bg_01.gif) repeat-x 0 0;
}

As outras duas tentativas sem sucesso foram colocar o height: 100% só no body e depois só no html. Caso queira ver o problema resolvido, veja aqui um exemplo funcionando.

jan 28, 2008 Posted Under: css, dicas, html, praticando   Read More

Rounded corners – Cantos arredondados e como fazê-los

Atualmente os cantos arredondados, são uma grande dor-de-cabeça no desenvolvimento, pois existem vários modos de implementar, com uma, duas ou quatro imagens?, sem imagens?, só com css?, javascript? qual javascript utilizar?, essas questões incomodam a cada vez que é necessário implementar este tipos de borda, que até o presente momento, não tem como serem feitas somente com css, quem sabe um dia, quando o css3 for lançado.

http://www.w3.org/TR/css3-background/#the-border-radius

Mas enquanto esta e muitas outras melhorias no css3 não chegam e não vão chegam nem tão cedo, temos que nos virar com o que temos, então abaixo listarei algumas técnicas que são as mais interessantes de se implementar, cada uma tem suas vantagens e desvantagens.

Cantos arredondados com uma imagem.

A imagem para criar os cantos arredondados é esta aqui embaixo, para o fundo branco e sem borda, o procedimento para criar a imagem é simples, faça um box de cantos arredondados, em seu software de edição de imagens preferido, e corte um dos cantos, faça uma imagem como a abaixo, colocando os cantos de forma que cada um fique na posição oposta ao outro.

Imagem com 4 cantos arredondados

Crie um div para segurar todo o conteúdo do box arredondado e outros dois, um para os cantos de cima e o outro para os cantos de baixo, com mais um dentro de cada um, parece complicado? mas olhe o código abaixo é bem simples…

<div class="wrap-rounded_corners">
    <div class="top_corners">
      <div></div>
    </div>
    conteúdo do box
    <div class="bottom_corners">
      <div></div>
    </div>
  </div><!-- /wrap-rounded_corners -->

E o seguinte css:


/* define o estilo para o box que segura todo o conteúdo
   o overflow hidden é para esconder o que estiver para
   fora da div.wrap-rounded_corners, retire e veja o que acontece
*/
div.wrap-rounded_corners {
        margin: 10px;
        padding: 0 10px;
        background: #0f0;
        overflow: hidden;
}

/* define que todos os divs abaixo terão posição relativa,
    largura de 100% e 9px de altura */
div.wrap-rounded_corners div.top_corners,
div.wrap-rounded_corners div.top_corners div,
div.wrap-rounded_corners div.bottom_corners,
div.wrap-rounded_corners div.bottom_corners div {
        position: relative;
        width: 100%;
        height: 9px;
}

/* define que esta div tem o posicionamento relativo à esquerda negativa em 10px,
    para compensar os 10px de padding da div.wrap-rounded_corners
*/
div.wrap-rounded_corners div.top_corners {
  left: -10px;
  background: transparent url(images/corners.gif) no-repeat -10px -10px;
}

/* define que esta div tem o posicionamento relativo à direita negativa em 30px,
    para compensar os 20px de padding (10px de cada lado) da div.wrap-rounded_corners
    e os 10px de margem negativa da div.top_corners
*/
div.wrap-rounded_corners div.top_corners div {
  right: -30px;
  background: transparent url(images/corners.gif) no-repeat right -10px;
}

/* define que esta div tem o posicionamento relativo à esquerda negativa em 10px,
    para compensar os 10px de padding da div.wrap-rounded_corners
*/
div.wrap-rounded_corners div.bottom_corners {
  left: -10px;
  background: #f00 url(images/corners.gif) no-repeat -10px 0;
}

/* define que esta div tem o posicionamento relativo à direita negativa em 30px,
    para compensar os 20px de padding (10px de cada lado) da div.wrap-rounded_corners
    e os 10px de margem negativa da div.bottom_corners e o overflow hidden, para corrigir
    um bug do IEca que aparentemente não tem explicação para estar ocorrendo,
    retire e veja do que estou falando
*/
div.wrap-rounded_corners div.bottom_corners div {
  right: -30px;
  background: transparent url(images/corners.gif) no-repeat right 0;
  overflow:hidden;
}

Você pode conferir aqui este exemplo funcionando.

Cantos arredondados com duas imagens.

Este tipo de canto arredondado é para um box com largura fixa, o procedimento é simples, é so criar duas imagens, uma com cantos arredondados de cima, e outra com os cantos de baixo, como estas do exemplo abaixo.

Cantos arredondados superiores Cantos arredondados inferiores

Agora, é só criar dois divs, como no exemplo abaixo, um dentro do outro e colocar uma classe em cada um, se quizer caso não queira não tem necessidade, mas é melhor para nao haver problemas, de herança de estilos, com outras divs que possam estar dentro do box:

<div class="top_corners">
  <div class="bottom_corners">
    conteudo do box
  </div><!-- /bottom_corners -->
</div><!-- /top_corners -->

e o seguinte css:


    /*
      Esta div é para segurar todo o conteudo do box de cantos arredondados,
      definindo a largura do box, e colocando a cor de fundo e a imagem dos cantos superiores
    */
      div.top_corners {
        width: 104px;
        background: #2a70ff url(images/rounded_top.gif) no-repeat 0 0;
      }

      /*
        e esta div é para os cantos inferiores, coloca-se a imagem dos cantos
        inferiores com alinhamento ao rodape, esta div não deve ter cor de fundo,
        pois caso tenha irá "esconder" os cantos superiores, e um espaçamento
        para não ter nenhum conteúdo sobre os cantos.
      */
      div.top_corners div.bottom_corners {
        padding: 10px;
        background: transparent url(images/rounded_bottom.gif) no-repeat 0 bottom;
      }

Você pode conferir aqui este exemplo funcionando.

Estes foram dois exemplos simples para dar a direção de como podem ser feitos boxes com cantos arredondados, existem uma grande variedade de possibilidades para fazer os cantos arredondados, é só colocar a cabeça para funcionar que surgirão idéias para resolver o problema.

Agora mostrarei alguns javascripts para fazer os cantos arredondados que você irá ver os prós e contras para ver se é melhor ou pior que fazer com imagens, um ponto a favor é que são “menos trabalhosos” de se implementar e um contra, se o site for “grande e/ou pesado” pode demorar “renderizar” os cantos arredondados.

O primeiro exemplo é o do transcorners, que foi criado por um(a) “cara” ou site chamado Inviz , que o site não está mais no ar, pelo menos não esta pagina, que por acaso eu so consegui depois de sofrer muito em achar para deixar de exemplo, e so me dei esse trabalho porque é um bom script.

Você pode conferir o exemplo funcionado. (em inglês)

Este outro exemplo de javascript foi visto aqui, que por acaso estava fora no momento em que estava escrevendo este post.

Não sei se utilizei todas as configurações disponiveis no exemplo, caso não tenham sido, me avise que coloco todas as propriedades possiveis. Este script é bastante simples de ser implementado e compreendido, ele pode ser conferido aqui.

Esses foram somente alguns exemplos de como colocar em prática os cantos arredondados, caso queira mais algum exemplo vc pode usar um de seus amigos, o Google ou o Yahoo, ou o seu site de buscas preferido, ou este excelente link no CssJuice com uma lista de 25 técnicas diferentes de cantos arredondados.

[]´s e até o próximo post, que pretendo que não demore tanto novamente.