Como colocar espaçamento entre os elementos TBODY

95

Eu tenho uma mesa assim:

<table>
    <tfoot>
        <tr><td>footer</td></tr>
    </tfoot>
    <tbody>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
    </tbody>
</table>

Eu gostaria de colocar algum espaçamento entre cada elemento tbody, mas o preenchimento e a margem não têm efeito. Alguma ideia?

nickf
fonte
É correto repetir tags 'tbody'? O que sempre vi são todos os "<tr> .. </tr>" dentro de uma única tag "tbody '.
Saneef
23
Sim, isso é válido. A especificação diz: <! ELEMENT TABLE - - (CAPTION ?, (COL * | COLGROUP *), THEAD ?, TFOOT ?, TBODY +)> significando que deve haver um ou mais tbodies. w3.org/TR/html4/struct/tables.html#h-11.2.1
nickf

Respostas:

56

Experimente isso, se você não se importa de não ter fronteiras.

<style>
table {
  border-collapse: collapse;
}

table tbody {
  border-top: 15px solid white;
}
</style>

<table>
    <tfoot>
        <tr><td>footer</td></tr>
    </tfoot>
    <tbody>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
    </tbody>
</table>
Dave Jensen
fonte
7
Experimente border-top: 15px sólido transparente;
Steve Almond,
3
Queria enfatizar isso. Use transparentcomo a cor da borda. O que @SteveAlmond disse.
iheartcsharp
se table / tbody / tr / td tem uma cor de fundo, definir a cor da borda para transparentfornecerá a cor de fundo do elemento, essencialmente indistinguível do corpo do elemento. Você precisaria colorir explicitamente a borda da cor que deseja que apareça (para torná-la supostamente invisível)
Guy Passy
81

Algo assim funcionará, dependendo dos requisitos de suporte do seu navegador:

tbody::before
{
  content: '';
  display: block;
  height: 15px;

}
MacNimble
fonte
1
Esta é a única solução que funciona quando suas células têm um fundo que o espaço não deveria ter.
Laradda de
Isto funcionou bem para mim. Existem desvantagens? Além disso, por que dois dois pontos?
nh2
Ótima solução. Mantém tudo acessível!
Jason T Featheringham
1
@ nh2: dois pontos duplos são para pseudo-conteúdo e dois pontos simples são para pseudo-seletores. É uma atualização da sintaxe CSS. Tudo costumava usar apenas um único cólon. Navegadores mais antigos não oferecem suporte a dois pontos duplos (como, IE <= 8).
dbmikus
3
Não é mais seguro usar display: table-row;?
Rachel de
20

As pessoas sempre terão opiniões controversas sobre o uso de elementos de tabela vazios para fazer o layout de uma página (conforme evidenciado pelo voto negativo desta resposta). Eu reconheço isso, mas às vezes é mais fácil usá-los dessa forma quando você está trabalhando de forma " rápida e suja ".

Eu usei linhas vazias em projetos anteriores para grupos de linhas de tabela de espaço. Atribuí às linhas espaçadoras uma classe css própria e defini uma altura para essa classe que atuou como uma margem superior e inferior para esse grupo de linhas da tabela.

    .separator{
             height: 50px;
    }

   <table>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>

           <tr class="separator" colspan="2"></tr>

           <tr><td>Cell 1</td><td>Cell 2</td></tr>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>

           <tr class="separator" colspan="2"></tr>

           tr><td>Cell 1</td><td>Cell 2</td></tr>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>
           <tr><td>Cell 1</td><td>Cell 2</td></tr>
   </table>

Se você não tem bordas nas células da sua tabela, você também pode definir uma altura para a sua célula típica ou linha em sua folha de estilo que espace uniformemente todas as linhas de sua tabela.

tr{
   height: 40px;
}
kevtrout
fonte
bem, se você vai adicionar marcação extra, por que não apenas colocar uma classe na primeira linha de cada corpo?
nickf
Bem, isso pode ser porque as linhas são códigos gerados, e adicionar uma linha separada na marcação pode ser mais sustentável do que criar um caso especial para a primeira linha de conteúdo gerado.
Rolf Rander
12
Faça downvote em tudo que quiser, mas esta é a única solução sem inconvenientes - e mesmo que viole a separação, uma linha vazia não é grande coisa, IMO.
Xkeeper de
11
Sem inconvenientes, minha bunda! Tente usar um leitor de tela para isso e observe as contagens de linhas incorretas. Melhor ainda, tente copiar e colar a tabela em uma planilha. Você estará reformatando por horas se tiver muito conteúdo. As tabelas destinam-se a exibir dados (e ser extremamente acessíveis), não a corrigir a apresentação entre as seções.
Jason T Featheringham
É apenas visual. Lembre-se de que html também são documentos que podem ser processados, portanto, o conteúdo dentro deles deve ser bem formatado. Conforme mencionado acima, a tabela de copiar e colar ou o uso do leitor de tela simplesmente falharão. Esse design não deve ser encorajado. :: solução de conteúdo é melhor porque não atrapalha a marcação.
pawel-kuznik
12

Eu estava com problemas para espaçar corretamente vários <tbody>com ::beforepseudo, na presença de <tr>contendo <td>com rowspan em alguns navegadores.

Basicamente, se você tiver uma <tbody>estrutura assim:

<tbody>
    <tr>
        <td>td 1</td>
        <td rowspan"2">td 2</td>
        <td>td 3</td>
        <td>td 4</td>
    </tr>
    <tr>
        <td>td 1</td>
        <td>td 2</td>
        <td>td 4</td>
    </tr>
</tbody>

E você segue quem aconselha a escrever css em ::beforepseudoelementos como este:

tbody::before
{
    content: '';
    display: block;
    height: 10px;
}

Isso afetará o intervalo de linhas , fazendo com que a tabela "perca" em um segundo <tr>quantos <td>-rowspan estão presentes no primeiro.

Portanto, se alguém encontrar esse tipo de problema, a solução é denominar o ::beforepseudo desta forma:

tbody::before
{
    content: '';
    display: table-row;
    height: 10px;
}

Aqui está um violino

Nineoclick
fonte
6

Aqui está outra possibilidade que depende de: primeiro filho, que não está disponível em todos os navegadores:

<style>
table {
  border-collapse: collapse;
}

td {
  border: 1px solid black;
}

tbody tr:first-child td {
  padding-top: 15px;
}

</style>

<table>
    <tfoot>
        <tr><td>footer</td></tr>
    </tfoot>
    <tbody>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
    </tbody>
</table>
Dave Jensen
fonte
3
Este não funcionará muito bem se você tiver algo que dependa da posição do conteúdo em relação ao tamanho da célula, como sombra de caixa, imagens de fundo ou praticamente qualquer outra coisa.
Xkeeper de
1
Apenas para esclarecer para outras pessoas que estão encontrando esta resposta no google, presumo que, como isso foi escrito em 2008, esta resposta agora (2015) tem suporte total para todos os principais navegadores. Pelo menos checar caniuse.com primeiro filho parece bem suportado?
redfox05
6

Basta definir displaycomo blocke funcionará.

table tbody{
    display:block;
    margin-bottom:10px;
    border-radius: 5px;
}
user007
fonte
1
esta resposta deve ser aceita porque é a única que permite usar um tbody com borda com colunas "sem borda".
robsonrosa
13
display:blockquebra o alinhamento da coluna entre os elementos do corpo. Você não tem mais o benefício do mecanismo de layout de mesa
M Conrad
4

De todas as respostas fornecidas acima, apenas as respostas de djenson47 mantêm a separação de apresentação e conteúdo . A desvantagem do método do modelo de borda recolhida é que você não pode mais usar os atributos de borda da tabela ou de espaçamento entre células para separar as células individuais. Você pode argumentar que isso é bom e que existem algumas soluções alternativas, mas pode ser uma dor. Portanto, acho que o método do primeiro filho é o mais elegante.

Como alternativa, você também pode definir a propriedade de estouro da classe TBODY para qualquer coisa diferente de "visível". Este método permite que você retenha um modelo de bordas separadas também:

<style>
tbody {
    overflow: auto;
    border-top: 1px solid transparent;
}
</style>
<table>
    <tfoot>
        <tr><td>footer</td></tr>
    </tfoot>
    <tbody>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
        <tr><td>Body 1</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
        <tr><td>Body 2</td></tr>
    </tbody>
    <tbody>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
        <tr><td>Body 3</td></tr>
    </tbody>
</table>
Calvin
fonte
Eu estava tentando fazer algo semelhante, isso é perfeito para mim
Eruant
4

Como o preenchimento pode ser aplicado aos DTs, você pode fazer um truque com o sinal +. Então será possível dar um preenchimento superior aos TD's do primeiro TR de um corpo:

// The first row will have a top padding
table tbody + tbody tr td {
    padding-top: 20px;
}

// The rest of the rows should not have a padding
table tbody + tbody tr + tr td {
    padding-top: 0px;
}

Eu adicionei o "tbody + tbody" para que o primeiro tbody não tenha um preenchimento superior. No entanto, não é obrigatório.

Pelo que eu sei, não há desvantagens :), embora não teste os navegadores mais antigos.

Maarten
fonte
2

Você pode usar border-spacingem uma tabela com grupos de linhas de tabela para adicionar um espaço entre esses grupos. Porém, não acho que haja uma maneira de especificar quais grupos são espaçados e quais não são.

<table>
  <thead>
    ...
  </head>
  <tbody>
    ...
  </tbody>
  <tbody>
    ...
  </tbody>
  <tfoot>
    ...
  </tfoot>
</table>

CSS

table {
  border-spacing: 0px 10px; /* h-spacing v-spacing */
}
OdraEncoded
fonte
0

NOVA RESPOSTA

Você pode usar quantas <tbody>tags quiser. Eu não sabia que o W3C estava ok até agora. Não quer dizer que minha solução abaixo não funcione (funciona), mas para fazer o que você está tentando fazer, atribua suas <tbody>classes de tags e, em seguida, referencie suas <td>tags individuais por meio de CSS, assim:

table tbody.yourClass td {
    padding: 10px;
}

e seu HTML assim:

<table> 
<tbody>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
</tbody>
<tbody class="yourClass">    
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
</tbody>
<tbody>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
</tbody>
</table>

Experimente esse cara :)

RESPOSTA ANTIGA

faça o que fizer, NÃO insira linhas em branco ...

você não deve ter mais de 1 elemento tbody em sua tabela. o que você pode fazer é definir o atributo class ou id em seus <tr>elementos e fornecer <td>preenchimento de tags correspondentes :

table {
    border-collapse: collapse;
}

tr.yourClass td {
    padding: 10px;
}

Você pode até atribuir <tr>uma classe adicional à parte superior e inferior , de modo que eles só façam o preenchimento superior ou inferior, respectivamente:

tr.yourClass.topClass td {
    padding: 10px 0 0 0;
}

tr.yourClass.bottomClass td {
    padding: 0 0 10px 0;
}

e em seu HTML, sua <tr>tag seria assim:

<table> 
<tbody>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr class="yourClass topClass"><td>Text</td></tr>
<tr class="yourClass"><td>Text</td></tr>
<tr class="yourClass bottomClass"><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
</tbody>
</table>

Espero que isto ajude!

Jason
fonte
0

A resposta djensen47 funciona muito bem para navegadores mais recentes, no entanto, como foi apontado, o IE7 não funciona no.

Minha solução para esse problema de suporte aos navegadores mais antigos era envolver o conteúdo de cada célula dentro de um div. Em seguida, adicione um margin-top ao div.

<table class="tbl">
<tr></tr>
<tr></tr>
<tr></tr>
<tr><td><div></div></td></tr>
</table>

CSS

.tbl tr td div {
    height:30px;
    margin-top:20px;
}

A configuração de altura mantém as células com pelo menos 30 px de altura para evitar que qualquer coloração de célula usada dentro do div seja reduzida ao redor do texto. A margem superior cria o espaço desejado tornando toda a linha mais alta.

Jereme Guenther
fonte
0

Deparei com isso enquanto tentava resolver sozinho. Tive sucesso colocando uma <br>tag logo antes da </tbody>tag de fechamento . É uma correção puramente visual, mas parece funcionar na maioria dos navegadores que testei.

<table>
    <tbody>
        <tr>
            <td></td>
        </tr>
        <br>
    </tbody>
    <tbody>
        <tr>
            <td></td>
        </tr>
    </tbody>
</table>

Deve ser acessível também.

Ian
fonte