Ok, tive um problema simples de layout há uma ou duas semanas. Ou seja, as seções de uma página precisavam de um cabeçalho:
+---------------------------------------------------------+
| Title Button |
+---------------------------------------------------------+
Coisas muito simples. A coisa é que o ódio à mesa parece ter dominado o mundo da Web, do qual me lembrei quando perguntei Por que usar tags de listas de definições (DL, DD, DT) para formulários HTML em vez de tabelas? Agora, o tópico geral de tabelas vs divs / CSS foi discutido anteriormente, por exemplo:
Portanto, não se trata de uma discussão geral sobre CSS versus tabelas para layout. Esta é simplesmente a solução para um problema. Tentei várias soluções para o acima usando CSS, incluindo:
- Flutue para a direita para o botão ou div que contém o botão;
- Posição relativa ao botão; e
- Posição relativa + absoluta.
Nenhuma dessas soluções foi satisfatória por diferentes motivos. Por exemplo, o posicionamento relativo resultou em um problema de índice z em que meu menu suspenso apareceu sob o conteúdo.
Então acabei voltando para:
<style type="text/css">
.group-header { background-color: yellow; width: 100%; }
.group-header td { padding: 8px; }
.group-title { text-align: left; font-weight: bold; }
.group-buttons { text-align: right; }
</style>
<table class="group-header">
<tr>
<td class="group-title">Title</td>
<td class="group-buttons"><input type="button" name="Button"></td>
</tr>
</table>
E funciona perfeitamente. É simples, tão compatível com as versões anteriores quanto possível (provavelmente funcionará até mesmo no IE5) e simplesmente funciona. Sem problemas com posicionamento ou flutuadores.
Então, alguém pode fazer o equivalente sem tabelas?
Os requisitos são:
- Compatível com versões anteriores: para FF2 e IE6;
- Razoavelmente consistente: em diferentes navegadores;
- Centralizado verticalmente: o botão e o título têm alturas diferentes; e
- Flexível: permite um controle razoavelmente preciso sobre o posicionamento (preenchimento e / ou margem) e estilo.
Por outro lado, encontrei alguns artigos interessantes hoje:
EDIT: Deixe-me elaborar sobre a questão do float. Este tipo de trabalho:
<html>
<head>
<title>Layout</title>
<style type="text/css">
.group-header, .group-content { width: 500px; margin: 0 auto; }
.group-header { border: 1px solid red; background: yellow; overflow: hidden; }
.group-content { border: 1px solid black; background: #DDD; }
.group-title { float: left; padding: 8px; }
.group-buttons { float: right; padding: 8px; }
</style>
</head>
<body>
<div class="group-header">
<div class="group-title">This is my title</div>
<div class="group-buttons"><input type="button" value="Collapse"></div>
</div>
<div class="group-content">
<p>And it works perfectly. It's simple, as backward compatibile as it gets (that'll work probably even on IE5) and it just works. No messing about with positioning or floats.</p>
<p>So can anyone do the equivalent without tables that is backwards compatible to at least FF2 and IE6?</p>
<p>On a side note, I came across a couple of interesting articles today:</p>
</div>
</body>
</html>
Obrigado ao Ant P pela overflow: hidden
parte (ainda não entendi o porquê). É aqui que entra o problema. Digamos que eu queira que o título e o botão sejam centralizados verticalmente. Isso é problemático porque os elementos têm alturas diferentes. Compare isso com:
<html>
<head>
<title>Layout</title>
<style type="text/css">
.group-header, .group-content { width: 500px; margin: 0 auto; }
.group-header { border: 1px solid red; background: yellow; overflow: hidden; }
.group-content { border: 1px solid black; background: #DDD; }
.group-header td { vertical-align: middle; }
.group-title { padding: 8px; }
.group-buttons { text-align: right; }
</style>
</head>
<body>
<table class="group-header">
<tr>
<td class="group-title">This is my title</td>
<td class="group-buttons"><input type="button" value="Collapse"></td>
</tr>
</table>
<div class="group-content">
<p>And it works perfectly. It's simple, as backward compatibile as it gets (that'll work probably even on IE5) and it just works. No messing about with positioning or floats.</p>
<p>So can anyone do the equivalent without tables that is backwards compatible to at least FF2 and IE6?</p>
<p>On a side note, I came across a couple of interesting articles today:</p>
</div>
</body>
</html>
que funciona perfeitamente.
Respostas:
Não há nada de errado em usar as ferramentas que estão disponíveis para fazer o trabalho de forma rápida e correta.
Neste caso, uma mesa funcionou perfeitamente.
Eu pessoalmente teria usado uma mesa para isso.
Acho que tabelas aninhadas devem ser evitadas, as coisas podem ficar confusas.
fonte
Basta flutuar para a esquerda e para a direita e definir para limpar ambos e pronto. Não há necessidade de mesas.
Edit: Eu sei que recebi muitos votos positivos para isso, e acreditei que estava certo. Mas há casos em que você simplesmente precisa ter tabelas. Você pode tentar fazer tudo com CSS e funcionará em navegadores modernos, mas se você deseja suportar os mais antigos ... Para não me repetir, aqui o tópico de estouro de pilha relacionado e discurso retórico no meu blog .
Edit2: Como os navegadores mais antigos não são mais tão interessantes, estou usando o bootstrap do Twitter para novos projetos. É ótimo para a maioria das necessidades de layout e usa CSS.
fonte
Esta é uma pergunta capciosa: parece terrivelmente simples até você chegar
Quero deixar registrado que sim, a centralização vertical é difícil em CSS. Quando as pessoas postam, e parece não ter fim no SO, "você pode fazer X em CSS", a resposta é quase sempre "sim" e suas reclamações parecem injustificadas. Nesse caso, sim, essa coisa em particular é difícil.
Alguém deve apenas editar a questão inteira para "a centralização vertical é problemática em CSS?".
fonte
Float title left, float button right e (aqui está a parte que eu não conhecia até recentemente) - faça o contêiner de ambos
{overflow:hidden}
.Isso deve evitar o problema do índice z, de qualquer maneira. Se não funcionar e você realmente precisar do suporte IE5, vá em frente e use a mesa.
fonte
overflow:hidden
.Em CSS puro, uma resposta útil um dia será apenas usar
"display:table-cell"
. Infelizmente, isso não funciona nos navegadores de nível A atuais, portanto, para todos os efeitos, você também pode usar uma tabela se quiser obter o mesmo resultado de qualquer maneira. Pelo menos você terá certeza de que funciona bem no passado.Honestamente, use uma mesa se for mais fácil. Não vai doer.
Se a semântica e a acessibilidade do elemento da tabela realmente importam para você, há um rascunho de trabalho para tornar sua tabela não semântica:
http://www.w3.org/TR/wai-aria/#presentation
Eu acho que isso requer um DTD especial além do XHTML 1.1, o que apenas agitaria todo o debate
text/html
vsapplication/xml
, então não vamos lá.Então, para o seu problema de CSS não resolvido ...
Para alinhar verticalmente dois elementos em seu centro: isso pode ser feito de algumas maneiras diferentes, com alguns hackeamentos CSS obtusos.
Se você puder se ajustar às seguintes restrições, há uma maneira relativamente simples:
Então você pode usar o posicionamento absoluto com margens negativas:
Mas isso é inútil na maioria das situações ... Se você já sabe a altura dos elementos, então você pode apenas usar flutuadores e adicionar margem suficiente para posicioná-los conforme necessário.
Aqui está outro método que usa a linha de base do texto para alinhar verticalmente as duas colunas como blocos embutidos. A desvantagem aqui é que você precisa definir larguras fixas para as colunas para preencher a largura a partir da borda esquerda. Como precisamos manter os elementos travados em uma linha de base do texto, não podemos apenas usar float: certo para a segunda coluna. (Em vez disso, temos que deixar a primeira coluna larga o suficiente para empurrá-la.)
O HTML: adicionamos wrappers .valign ao redor de cada coluna. (Dê a eles um nome mais "semântico" se isso o deixar mais feliz.) Eles precisam ser mantidos sem espaços em branco ou então os espaços de texto os separarão. (Eu sei que é uma merda, mas isso é o que você ganha sendo "puro" com a marcação e separando-a da camada de apresentação ... Ha!)
O CSS: usamos
vertical-align:middle
para alinhar os blocos à linha de base do texto do elemento group-header. As diferentes alturas de cada bloco ficarão centradas verticalmente e empurrarão para fora a altura de seu contêiner. As larguras dos elementos precisam ser calculadas para caber na largura. Aqui, eles são 400 e 100, sem o preenchimento horizontal.As correções do IE: o Internet Explorer exibe apenas blocos embutidos para elementos embutidos nativamente (por exemplo, span, não div). Mas, se dermos o div hasLayout e depois exibi-lo embutido, ele se comportará como um bloco embutido. O ajuste da margem serve para corrigir uma lacuna de 1px no topo (tente adicionar cores de fundo ao título do .group para ver).
fonte
Eu recomendaria não usar uma tabela neste caso, porque não se trata de dados tabulares; é puramente de apresentação ter o botão localizado na extremidade direita. Isso é o que eu faria para duplicar a estrutura da sua tabela (mude para um H # diferente para se adequar a onde você está na hierarquia do seu site):
Se você deseja um alinhamento vertical verdadeiro no meio (ou seja, se o texto envolve o botão ainda está alinhado no meio em relação a ambas as linhas do texto), então você precisa fazer uma tabela ou trabalhar algo com
position: absolute
e margens. Você pode adicionarposition: relative
ao seu menu suspenso (ou mais provavelmente ao seu pai) para colocá-lo no mesmo nível de ordenação dos botões, permitindo que você o coloque acima deles com z-index, se for o caso.Observe que você não precisa
width: 100%
do div porque é um elemento em nível de bloco ezoom: 1
faz com que o div se comporte como se tivesse um clearfix no IE (outros navegadores pegam o clearfix real). Você também não precisa de todas essas classes estranhas se estiver direcionando as coisas um pouco mais especificamente, embora possa precisar de um div de invólucro ou extensão no botão para facilitar o posicionamento.fonte
zoom: 1
in.group-header
, que dispara o hasLayout e faz com que o IE 6 se comporte da mesma forma como se tivesse o elemento: after ativo.Faça um double float em um div e use o clearfix. http://www.webtoolkit.info/css-clearfix.html Você tem alguma restrição de preenchimento / margem?
fonte
fonte
Eu escolhi usar o Flexbox porque tornou as coisas muito mais fáceis.
Você basicamente precisa ir até o pai dos filhos que deseja alinhar e adicionar
display:box
(prefixados, é claro). Para fazê-los sentar nas laterais, use justify-content . Espaçar entre é a coisa certa quando você tem elementos que precisam ser alinhados ao final, como neste caso (ver link) ...Em seguida, o problema do alinhamento vertical. Como criei o pai dos dois elementos, você deseja alinhar um Flexbox. Agora é fácil de usar
align-items: center
.Em seguida, adicionei os estilos que você queria antes, removi o float do título e do botão no cabeçalho e adicionei um preenchimento:
Veja a demonstração
fonte
Eu concordo que realmente só se deve usar tabelas para dados tabulares, pela simples razão de que as tabelas não aparecem até que o carregamento seja concluído (não importa o quão rápido seja; é mais lento que o método CSS). No entanto, sinto que esta é a solução mais simples e elegante:
A função do botão e qualquer detalhe extra podem ser estilizados a partir desta forma básica. Desculpas pelas tags ruins.
fonte