Граница вокруг определенных строк в таблице?


120

Я пытаюсь разработать HTML / CSS, который может поставить рамку вокруг определенных строк в таблице. Да, я знаю, что на самом деле мне не нужно использовать таблицы для макета, но я еще не знаю достаточно CSS, чтобы полностью заменить его.

В любом случае, у меня есть таблица с несколькими строками и столбцами, некоторые из которых объединены с rowspan и colspan, и я хотел бы поставить простую рамку вокруг частей таблицы. В настоящее время я использую 4 отдельных класса CSS (верхний, нижний, левый, правый), которые я прикрепляю к <td>ячейкам, расположенным вверху, внизу, слева и справа от таблицы соответственно.

.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>

Есть ли более простой способ сделать то, что я хочу? Я попробовал применить верх и низ к a, <tr>но это не сработало. (ps Я новичок в CSS, поэтому, вероятно, есть действительно простое решение, которое я пропустил.)

примечание: мне нужно иметь несколько разделов с рамками. Основная идея состоит в том, чтобы иметь несколько кластеров с границами, каждый из которых содержит несколько строк.


9
Не по теме, но я просто хотел сказать, что таблицы идеально подходят и рекомендуются при отображении табличных данных ...
md1337 06

Ответы:


114

Как насчет tr {outline: thin solid black;}? У меня работает с элементами tr или tbody и кажется совместимым с большинством браузеров, включая IE 8+, но не ранее.


Я просил поставить одну рамку вокруг нескольких строк в таблице, по сути, визуально разделив ее на несколько разделов, но внутри одной таблицы, чтобы элементы из разных разделов выровнялись.
Kyle Cronin

3
Понятно, мне это тоже нужно. Включите набор строк, вокруг которых вы хотите создать границу, в их собственном tbody, и приведенный выше css создаст границу вокруг их набора, то есть верхнюю границу в верхней строке, нижнюю границу в нижней строке и левую и правые границы на всех строках в теле. Границы на самом деле не «на» этих строках, они находятся на контуре самого тела, просто пытаясь описать эффект.
enigment 07

О, я вижу, несколько tbodys - это работает, и я не думал об этом. Проголосовали :)
Kyle Cronin

Я бы предложил использовать свойство css nth-child () вместо того, чтобы определять tbodys, если у вас действительно нет довольно динамических данных. Используя nth-child (), nth-last-child (), а не (), вы можете выбрать любые строки / ячейки, которые вам нужны (если вы знаете относительные индексы вещей в таблице). Например, вы можете выбрать все строки, кроме двух верхних и нижней, с помощью tr: not (: nth-child (-n + 2)): not (: nth-last-child (1))
BT

1
Обратите внимание, что контур не может ограничивать определенные стороны элемента. Например, нет «контура-верха». Это ограниченное решение
BT

53

Спасибо всем, кто откликнулся! Я пробовал все решения, представленные здесь, и я больше искал в Интернете другие возможные решения, и я думаю, что нашел одно многообещающее:

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>

Вывод:

введите описание изображения здесь

Вместо того, чтобы добавить top, bottom, leftи rightклассы каждый <td>, все , что нужно сделать , это добавить top rowк верху <tr>, bottom rowк низу <tr>, и rowкаждому <tr>между ними. Что-то не так с этим решением? Есть ли какие-либо кроссплатформенные проблемы, о которых мне следует знать?


Просто запустил тест через браузерные снимки, и похоже, что IE (все версии) не любит атрибуты first-child и last-child. : - /
Kyle Cronin

1
Похоже, что IE 7 и 8 поддерживают первого ребенка, но ни один из них не поддерживает последний ребенок (!) Msdn.microsoft.com/en-us/library/cc351024(VS.85).aspx
Mechanical_meat

cellspacingАтрибут является устаревшим в HTML5. Похоже, что CSS table { border-collapse: collapse; border-spacing: 0; }- это то, что нужно.
Стефан ван ден Аккер

36

Если вы установите border-collapseстиль collapseв родительской таблице, вы сможете стилизовать tr: (стили встроены для демонстрации)

<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>

Вывод:

Вывод HTML


8

Я тоже просто играл с этим, и это показалось мне лучшим вариантом:

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

Обратите внимание, что это предотвратит использование гибкой / автоматической ширины столбцов , поскольку ячейки больше не будут выравниваться с ячейками в других строках, но форматирование границ / цвета по-прежнему работает нормально. Решение состоит в том, чтобы задать ширину TR и TD (в пикселях или%).

Конечно, вы можете создать селектор, tr.myClassесли хотите применить его только к определенным строкам. Однако, по-видимому display: table, не работает для IE 6/7, но, вероятно, есть другие хаки (hasLayout?), Которые могут сработать для них. :-(


6
Это решение неверно: "display: table" помещает всю строку в одну ячейку таблицы - вы теряете форматирование по отношению к другим строкам таблицы. Я пробовал это в Firefox и Chromium.
Яаков Белч

Яаков, я думаю, вы имеете в виду, что ширина гибких столбцов больше не совпадает с другими строками в таблице (как видно из этой скрипки: jsfiddle.net/MrKtw ), но форматирование границ / цветов по-прежнему работает нормально. Решение состоит в том, чтобы задать ширину TR и TD (в пикселях или%).
Саймон Ист

Саймон, чтобы показать, что я имею в виду, я раздвоил и сменил твою скрипку. Взгляните на это: jsfiddle.net/a6DZV --- Я применяю форматирование «display: table» только к одной строке. Как видите, это фактически превращает эту строку в одну ячейку таблицы. Другими словами: вы получаете тот же результат, что и при вложении однострочных таблиц в ячейку другой таблицы (и отображении границы этой внутренней таблицы). Ваше решение сохраняет несколько узлов в DOM, но не настолько совместимо.
Яаков Белч

3

Вот подход с использованием элементов тела, которые могли бы быть способом сделать это. Вы не можете установить границу на tbody (так же, как вы не можете на tr), но вы можете установить цвет фона. Если желаемый эффект можно получить с помощью цвета фона в группах строк вместо границы, это сработает.

<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>

2

Сгруппируйте строки вместе с помощью <tbody>тега, а затем примените стиль.

<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>  

И css в style.css

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

1

Единственный другой способ, который я могу придумать, - это заключить каждую из строк, которые вам нужны, во вложенную таблицу. Это упростит создание границы, но может создать другие проблемы с макетом, вам придется вручную установить ширину ячеек таблицы и т. Д.

Ваш подход вполне может быть лучшим в зависимости от других требований к макету, и предлагаемый здесь подход является лишь возможной альтернативой.

<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>

Спасибо за Ваш ответ; Вы правы насчет проблем с макетом - я бы предпочел, чтобы столбцы выстраивались в линию, не делая это вручную. А как насчет применения класса к тегу <tr> - возможно ли это?
Кайл Кронин,

Если вы используете таблицу с «table-layout: fixed» и явно устанавливаете ширину каждого столбца (используя <col> или просто задавая ширину ячеек в первой строке), столбцы будут выстраиваться в линию независимо от содержимого. Вам даже не нужно вкладывать таблицы, три отдельные таблицы отлично подойдут.
bobince,

1

Исходя из вашего требования, что вы хотите поставить рамку вокруг произвольного блока ячеек MxN, действительно нет более простого способа сделать это без использования Javascript. Если ваши ячейки зафиксированы, вы можете использовать поплавки, но это проблематично по другим причинам. то, что вы делаете, может быть утомительным, но это нормально.

Хорошо, если вы заинтересованы в решении Javascript с использованием jQuery (мой предпочтительный подход), вы получите этот довольно страшный фрагмент кода:

<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>

Я с радостью приму предложения о более простых способах сделать это ...


1
Похоже, вы просто добавляете классы в теги td? Почему это нельзя сделать с помощью какого-нибудь серверного скрипта, созданного статически, или, в худшем случае, просто вручную? Мне кажется, это злоупотребление JavaScript.
Thomas

3
На самом деле плакат ПРОСИЛ решение для Javascript. Нельзя сказать, что это злоупотребление Javascript, поскольку информации недостаточно. Например, добавляются ли границы из-за нажатия пользователем? Если да, то серверное решение неверно.
cletus

Извините за отсутствие информации. Это будет сгенерировано на стороне сервера, так что это правда, что я мог бы просто добавить классы вручную, но мне нравится, как решение JS предоставляет более простой интерфейс для этого. Так что, хотя я, вероятно, не буду использовать JS, это хорошее решение.
Кайл Кронин,


-5

Более простой способ - сделать таблицу элементом управления на стороне сервера. Вы можете использовать что-то подобное:

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

1
OP просит более простой способ сделать это
orique 09

2
Будьте осторожны, OP также просит более простой способ сделать это в HTML / CSS. Я нигде не вижу в его вопросе ключевого слова VB или VBA. Предлагаю вам заглянуть в наш раздел справки: stackoverflow.com/help/how-to-answer Удачи.
ForceMagic 09
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.