Limite em torno de linhas específicas em uma tabela?

120

Estou tentando criar alguns HTML / CSS que podem colocar uma borda em torno de linhas específicas em uma tabela. Sim, eu sei que não devo usar tabelas para layout, mas ainda não conheço CSS suficiente para substituí-lo completamente.

De qualquer forma, tenho uma tabela com várias linhas e colunas, algumas mescladas com row e colspan, e gostaria de colocar uma borda simples em torno das partes da tabela. Atualmente, estou usando 4 classes CSS separadas (superior, inferior, esquerda, direita) que anexo às <td>células que estão ao longo da parte superior, inferior, esquerda e direita da tabela, respectivamente.

.top {
  border-top: thin solid;
  border-color: black;
}

.bottom {
  border-bottom: thin solid;
  border-color: black;
}

.left {
  border-left: thin solid;
  border-color: black;
}

.right {
  border-right: thin solid;
  border-color: black;
}
<html>

<body>

  <table cellspacing="0">
    <tr>
      <td>no border</td>
      <td>no border here either</td>
    </tr>
    <tr>
      <td class="top left">one</td>
      <td class="top right">two</td>
    </tr>
    <tr>
      <td class="bottom left">three</td>
      <td class="bottom right">four</td>
    </tr>
    <tr>
      <td colspan="2">once again no borders</td>
    </tr>
    <tr>
      <td class="top bottom left right" colspan="2">hello</td>
    </tr>
    <tr>
      <td colspan="2">world</td>
    </tr>
  </table>

</html>

Existe alguma maneira mais fácil de fazer o que eu quero? Tentei aplicar a parte superior e inferior de um, <tr>mas não funcionou. (ps Eu sou novo em CSS, então provavelmente há uma solução realmente básica para isso que eu perdi.)

nota: eu preciso ter várias seções com borda. A idéia básica é ter vários clusters com bordas, cada um contendo várias linhas.

Kyle Cronin
fonte
9
Off-topic, mas eu só queria dizer, mesas são perfeitamente adequado e recomendado ao exibir dados tabulares ...
md1337

Respostas:

114

Que tal tr {outline: thin solid black;}? Funciona para mim em elementos tr ou tbody e parece ser compatível com a maioria dos navegadores, incluindo o IE 8+, mas não antes.

enigment
fonte
Eu estava perguntando sobre colocar uma única borda em torno de várias linhas em uma tabela, essencialmente visualmente dividindo-a em várias seções, mas dentro da mesma tabela, para alinhar coisas de seções diferentes.
Kyle Cronin
3
Entendido, eu também precisava disso. Coloque o conjunto de linhas em que você deseja uma borda em seu próprio corpo, e o css acima criará uma borda em torno do conjunto delas - ou seja, uma borda superior na linha superior, uma borda inferior na linha inferior e esquerda e bordas direitas em todas as linhas do tbody. As bordas não estão "nessas" linhas, estão no contorno do corpo, apenas tentando descrever o efeito.
enigment
Ah, entendo, vários corpos - isso funciona e é algo que eu não tinha considerado. Voto a favor :)
Kyle Cronin
Eu sugeriria usar a propriedade nth-child () css em vez de definir tbodys, a menos que você realmente tenha alguns dados bastante dinâmicos. Usando enésimo filho (), enésimo último filho () e não (), você pode selecionar as linhas / células que desejar (desde que conheça os índices relativos das coisas na tabela). Por exemplo, você pode selecionar todas as linhas, exceto as duas primeiras e a inferior com tr: not (: nésimo filho (-n + 2)): not (: nésimo último filho (1))
BT
1
Observe que o contorno não tem a possibilidade de delimitar lados específicos de um elemento. Não existe um "esboço geral", por exemplo. Esta é uma solução limitada
BT
53

Obrigado a todos que responderam! Eu tentei todas as soluções apresentadas aqui e fiz mais pesquisas na Internet em busca de outras soluções possíveis, e acho que encontrei uma que é promissora:

tr.top td {
  border-top: thin solid black;
}

tr.bottom td {
  border-bottom: thin solid black;
}

tr.row td:first-child {
  border-left: thin solid black;
}

tr.row td:last-child {
  border-right: thin solid black;
}
<html>

<head>
</head>

<body>

  <table cellspacing="0">
    <tr>
      <td>no border</td>
      <td>no border here either</td>
    </tr>
    <tr class="top row">
      <td>one</td>
      <td>two</td>
    </tr>
    <tr class="bottom row">
      <td>three</td>
      <td>four</td>
    </tr>
    <tr>
      <td colspan="2">once again no borders</td>
    </tr>
    <tr class="top bottom row">
      <td colspan="2">hello</td>
    </tr>
    <tr>
      <td colspan="2">world</td>
    </tr>
  </table>

</body>

</html>

Resultado:

insira a descrição da imagem aqui

Em vez de ter que adicionar os top, bottom, left, e rightclasses para cada <td>, tudo o que tenho a fazer é adicionar top rowao topo <tr>, bottom rowao fundo <tr>, e rowa cada <tr>no meio. Há algo de errado com esta solução? Há algum problema de plataforma cruzada que eu deva estar ciente?

Kyle Cronin
fonte
Acabei de executar um teste nas imagens dos navegadores e parece que o IE (todas as versões) não gosta dos atributos de primeiro filho e último filho. : - /
Kyle Cronin
1
Looks como o IE 7 e 8 suporte de primeira criança, mas nenhum suporte last-child (!) Msdn.microsoft.com/en-us/library/cc351024(VS.85).aspx
mechanical_meat
O cellspacingatributo está obsoleto no HTML5. Parece que o CSS table { border-collapse: collapse; border-spacing: 0; }é o caminho a percorrer agora.
Stefan van den Akker 5/05
36

Se você definir o border-collapseestilo como collapsena tabela pai, poderá estilizar o tr: (os estilos estão alinhados para demonstração)

<table style="border-collapse: collapse;">
  <tr>
    <td>No Border</td>
  </tr>
  <tr style="border:2px solid #f00;">
    <td>Border</td>
  </tr>
  <tr>
    <td>No Border</td>
  </tr>
</table>

Resultado:

Saída HTML

Nascer do sol
fonte
8

Eu estava apenas brincando de fazer isso também, e essa parecia ser a melhor opção para mim:

<style>
    tr { 
        display: table;            /* this makes borders/margins work */
        border: 1px solid black;
        margin: 5px;
    }
</style>

Observe que isso impedirá o uso de larguras de coluna fluidas / automáticas , pois as células não se alinham mais com as de outras linhas, mas a formatação de borda / cor ainda funciona bem. A solução é fornecer aos TR e TDs uma largura especificada (px ou%).

Obviamente, você pode fazer o seletor tr.myClassse quiser aplicá-lo apenas a determinadas linhas. Aparentemente display: table, não funciona para o IE 6/7, no entanto, mas provavelmente existem outros hacks (hasLayout?) Que podem funcionar para eles. :-(

Simon East
fonte
6
Esta solução está incorreta: "display: table" coloca a linha inteira em uma célula da tabela --- você perde a formatação em relação às outras linhas da tabela. Eu tentei isso no Firefox e no Chromium.
Yaakov Belch 13/02/2013
Yaakov, acho que o que você está se referindo é que as larguras das colunas fluidas não se alinham mais com outras linhas da tabela (como pode ser visto neste violino: jsfiddle.net/MrKtw ), mas a formatação de borda / cor ainda funciona bem. A solução é fornecer aos TR e TDs uma largura especificada (px ou%).
Simon East
Simon, para mostrar o que quero dizer, bifurquei e mudei seu violino. Veja isto: jsfiddle.net/a6DZV --- Eu aplico a formatação "display: table" a apenas uma linha. Como você vê, isso transforma essa linha efetivamente em uma célula da tabela. Em outras palavras: você obtém a mesma saída que aninhar tabelas de uma linha dentro de uma célula de outra tabela (e mostrando a borda dessa tabela interna). Sua solução salva alguns nós no DOM, mas não é tão compatível.
Yaakov Belch
3

Aqui está uma abordagem usando elementos tbody que podem ser a maneira de fazer isso. Você não pode definir a borda em um tbody (o mesmo que não pode em um tr), mas pode definir a cor do plano de fundo. Se o efeito que você deseja obter puder ser obtido com uma cor de plano de fundo nos grupos de linhas em vez de em uma borda, isso funcionará.

<table cellspacing="0">  
    <tbody>
        <tr>    
            <td>no border</td>    
            <td>no border here either</td>  
        </tr>  
    <tbody bgcolor="gray">
        <tr>    
            <td>one</td>    
            <td>two</td>  
        </tr>  
        <tr>    
            <td>three</td>    
            <td>four</td>  
        </tr>  
    <tbody>
        <tr>    
             <td colspan="2">once again no borders</td>  
        </tr>  
    <tbody bgcolor="gray">
        <tr>    
             <td colspan="2">hello</td>  
        </tr>
    <tbody>
    <tr>    
         <td colspan="2">world</td>  
    </tr>
</table>
sipwiz
fonte
2

Agrupe linhas usando a <tbody>tag e aplique o estilo.

<table>
  <tr><td>No Style here</td></tr>
  <tbody class="red-outline">
    <tr><td>Style me</td></tr>
    <tr><td>And me</td></tr>
  </tbody>
  <tr><td>No Style here</td></tr>
</table>  

E o css em style.css

.red-outline {
  outline: 1px solid red;
}
csi
fonte
1

A única outra maneira que posso pensar em fazer isso é colocar cada uma das linhas em que você precisa de uma borda em uma tabela aninhada. Isso facilitará a borda, mas potencialmente criará outros problemas de layout, você precisará definir manualmente a largura nas células da tabela, etc.

Sua abordagem pode muito bem ser a melhor, dependendo de outras exigências de layout, e a abordagem sugerida aqui é apenas uma alternativa possível.

<table cellspacing="0">  
    <tr>    
        <td>no border</td>    
        <td>no border here either</td>  
    </tr>  
    <tr>
        <td>
             <table style="border: thin solid black">
                  <tr>    
                        <td>one</td>    
                        <td>two</td>  
                  </tr>  
                  <tr>    
                      <td>three</td>    
                      <td>four</td>  
                  </tr>  
             </table>
         </td>
    </tr>
    <tr>    
         <td colspan="2">once again no borders</td>  
    </tr>  
    <tr>
        <td>
             <table style="border: thin solid black">
                  <tr>    
                        <td>hello</td>  
                   </tr>
             </table>
         </td>
    </tr>
    <tr>    
         <td colspan="2">world</td>  
    </tr>
</table>
sipwiz
fonte
Obrigado pela sua resposta; você está certo sobre os problemas de layout - eu preferiria que as colunas se alinhem sem fazer isso manualmente. Que tal aplicar uma classe a uma tag <tr> - isso é possível?
Kyle Cronin
Se você usar uma tabela com “layout da tabela: fixo” e definir explicitamente a largura de cada coluna (usando <col> ou apenas definindo a largura das células na primeira linha), as colunas serão alinhadas independentemente do conteúdo. Você nem precisa aninhar as tabelas, três tabelas separadas fariam o exemplo bem.
22990 bobince as
1

Com base no seu requisito de que você deseja colocar uma borda em torno de um bloco arbitrário de células MxN, não há realmente nenhuma maneira mais fácil de fazer isso sem usar Javascript. Se suas células estiverem fixas, você poderá usar flutuadores, mas isso é problemático por outros motivos. o que você está fazendo pode ser entediante, mas tudo bem.

Ok, se você está interessado em uma solução Javascript, usando jQuery (minha abordagem preferida), você acaba com este pedaço de código bastante assustador:

<html>
<head>

<style type="text/css">
td.top { border-top: thin solid black; }
td.bottom { border-bottom: thin solid black; }
td.left { border-left: thin solid black; }
td.right { border-right: thin solid black; }
</style>
<script type="text/javascript" src="jquery-1.3.1.js"></script>
<script type="text/javascript">
$(function() {
  box(2, 1, 2, 2);
});

function box(row, col, height, width) {
  if (typeof height == 'undefined') {
    height = 1;
  }
  if (typeof width == 'undefined') {
    width = 1;
  }
  $("table").each(function() {
    $("tr:nth-child(" + row + ")", this).children().slice(col - 1, col + width - 1).addClass("top");
    $("tr:nth-child(" + (row + height - 1) + ")", this).children().slice(col - 1, col + width - 1).addClass("bottom");
    $("tr", this).slice(row - 1, row + height - 1).each(function() {
      $(":nth-child(" + col + ")", this).addClass("left");
      $(":nth-child(" + (col + width - 1) + ")", this).addClass("right");
    });
  });
}
</script>
</head>
<body>

<table cellspacing="0">
  <tr>
    <td>no border</td>
    <td>no border here either</td>
  </tr>
  <tr>
    <td>one</td>
    <td>two</td>
  </tr>
  <tr>
    <td>three</td>
    <td>four</td>
  </tr>
  <tr>
    <td colspan="2">once again no borders</td>
  </tr>
</tfoot>
</table>
</html>

Ficarei feliz em receber sugestões de maneiras mais fáceis de fazer isso ...

cleto
fonte
1
Parece que você está apenas adicionando classes às tags td? Por que isso não pôde ser feito com algum script do lado do servidor, gerado estaticamente ou na pior das hipóteses apenas à mão? Parece abuso de JavaScript para mim.
Thomas
3
Na verdade, o cartaz pediu uma solução Javascript. Você não pode dizer que é abuso de Javascript, pois não há informações suficientes. Por exemplo, as bordas estão sendo adicionadas ao clicar no usuário? Nesse caso, uma solução de servidor está incorreta.
Cletus
Desculpe pela falta de informação. Isso será gerado no servidor, por isso é verdade que eu poderia apenas adicionar as classes manualmente, mas gosto de como a solução JS fornece uma interface mais simples para isso. Então, embora eu provavelmente não vá com o JS, é uma boa solução para ver.
Kyle Cronin
0

o truque é com a estrutura de tópicos, graças à resposta do enigment com poucas modificações

use esta classe

.row-border{
    outline: thin solid black;
    outline-offset: -1px;
}

depois no HTML

<tr>....</tr>
<tr class="row-border">
    <td>...</td>
    <td>...</td>
</tr>

e o resultado é insira a descrição da imagem aqui esperança que isso ajude você

Basheer AL-MOMANI
fonte
-5

Uma maneira mais fácil é tornar a tabela um controle no servidor. Você pode usar algo semelhante a este:

Dim x As Integer
table1.Border = "1"

'Change the first 10 rows to have a black border
 For x = 1 To 10
     table1.Rows(x).BorderColor = "Black"
 Next

'Change the rest of the rows to white
 For x = 11 To 22
     table1.Rows(x).BorderColor = "White"
 Next
Curtis
fonte
1
OP está pedindo uma maneira mais fácil de fazer isso
orique
2
Cuidado, o OP também está pedindo uma maneira mais fácil de fazer isso em HTML / CSS. Não vejo em nenhum lugar na pergunta dele a palavra-chave VB ou VBA. Sugiro que você dê uma olhada em nossa seção de Ajuda: stackoverflow.com/help/how-to-answer Boa sorte.
ForceMagic