【问题标题】:Borders and spacing between specific table rows特定表格行之间的边框和间距
【发布时间】:2012-06-08 03:38:34
【问题描述】:

我是 CSS 新手,正在开发一个可在现代标准浏览器中呈现的内部网络应用程序(IE 支持是不是必要的)。我花了很多时间在这个网站和其他网站上寻找答案,只是为了找到答案“这是不可能的,因为......”或“改为做这个黑客......”但我不会接受。

这是我需要的:

  1. 具有一个标题行和多个正文行的表格;
  2. 标题行下方的实线边框;
  3. 仅在标题行和第一个正文行之间有垂直空白(填充?边距?间距?);
  4. 鼠标悬停时突出显示正文行。

在我为表格设置 border-collapse: collapse; 样式之前,我无法看到 (2)。美好的。但是 (3) 显然只适用于border-spacing,并且只适用于<td> 元素(不是<tbody><tr>),无论如何都会被collapse 禁用。同时,由于一些不可知的原因,<thead><tr><th> 元素无法识别margin,但在body 的<td> 作品的第一行有padding-top,除了它没有,因为当我将鼠标悬停在第一行上时,整个 margin-which-is-implemented-as-padding 也会突出显示,这让我感到恶心。

我知道在表格的标题和正文之间有几个像素的边距就像是一个非常左的字段,为什么-任何人都想要-想要的东西,但是我应该告诉你什么?我不是便宜的约会对象。

请尽可能粗暴和居高临下地指出我在理解 CSS 方面的愚蠢,如果你也 1) 说出如何在不更改标记的情况下进行操作(从而保持表示的分离从内容 CSS 显然是为了鼓励)或 2)同意我的观点,CSS 很奇怪。

<head><style>
  table {
    border-collapse: collapse;
    border-spacing: 0;
  }
  thead {
    border-bottom: 4px solid #123456;
  }
  /*** something goes here ***/
  tbody tr:hover {
    background-color: #ABCDEF;
  }
</style></head>

<body>
  <table>
    <thead>
      <tr><th>Fruit</th><th>Color</th><th>Yummy?</th></tr>
    </thead>
    <tbody>
      <tr><td>Apple</td><td>Green</td><td>Yes</td></tr>
      <tr><td>Banana</td><td>Yellow</td><td>Yes</td></tr>
      <tr><td>Pear</td><td>Brown</td><td>Yes</td></tr>
    </tbody>
  </table>
</body>

【问题讨论】:

    标签: css html-table row border margin


    【解决方案1】:

    这将解决您的问题而无需任何黑客攻击,当然这是完全可能的。更新后的代码(仅 CSS 更改)在下面分享,并附有说明。

    问题 3

    我们可以连续使用 CSS 选择器:first-of-type(只针对第一行)和它下面的所有&lt;td&gt;,并使用属性padding-top。简单:-)

    &lt;tr&gt; 默认情况下不能有边距值。黑客再次可用(上面提到的答案)但我不会去那里,因为你不想要它。

    而且由于我们使用了padding,悬停效果可以完美地应用于整个行内容。因此,无需任何标记更改即可获得所需的更改。

    问题 2

    我们可以从table 中删除属性border-collapse,而是在&lt;th&gt;标签上应用边框(让border-spacing: 0 保留,否则边框将不连续)。再次简单:-)

    问题 1 和 4 已涵盖。没有您希望的标记更改。 Here is the Fiddle

    所以更新后的样式代码看起来像

    <head><style>
      table {
        border-spacing: 0;
      }
      thead tr th {
        border-bottom: 4px solid #123456;
      }
      tbody tr:hover {
        background-color: #ABCDEF;
      }
    
      /*** added ***/
      tbody tr:first-of-type td {
        padding-top: 10px;
      }
    
    </style></head>
    

    【讨论】:

      【解决方案2】:

      好的,按顺序:

      1:一个表头一行多正文行:

      这就是 theadtbody 元素的设计目的:

      <table>
          <thead>
              <tr><th>heading one</th><th>Heading two</th></tr>
          </thead>
          <tbody>
              <!--
                  all body table rows in here
              -->
          </tbody>
      </table>
      

      还有tfoot(参见参考资料),如果使用它,必须在tbody 元素之前声明

      2:标题行下方的实线边框:

          thead tr th {
              border-bottom: 2px solid #000;
          }
      

      thead 元素中选择th 元素,tr 选择器在这里可能是不必要的,虽然它没有害处,但可以简化为:thead th {/*...*/}

      3: 仅在标题行和第一个正文行之间的垂直空白(填充?边距?间距?)。 padding 似乎不能应用于 theadtbodytr 元素,因为它们本质上(我想)是“非视觉的”,因此必须在 @ 987654339@ 元素。这在悬停时确实意味着在:hover 期间第一行占据了令人不安的大“行”(请参阅​​下一部分)。

          tbody tr:first-child td {
              padding-top: 1em;
          }
      

      4:在鼠标悬停时突出显示正文行。

          tbody tr:hover td {
              background-color: #ffa;
          }
      

      虽然您可以将 :hover 应用于当前悬停的单元格,但您不能将样式应用于先前出现的兄弟姐妹,因此我们在这里设置样式td 元素响应其父 tr:hover

      我们必须设置td 的样式(而不是直接更改trbackground-color 的原因是因为td 元素通常不会默认为透明背景,这意味着更改/突出显示background-colortd 元素中的background-color“隐藏”。

      JS Fiddle demo.

      参考资料:

      【讨论】:

      • 对我来说缩小一点:什么不起作用?所有的?只是一部分?您使用的是什么浏览器/操作系统?啊;好的,this hack 怎么样。
      • 谢谢。这样可行。不过,我不会将答案标记为已接受,因为这是一个 hack。正如我在我的问题中所说,CSS 应该将表示与内容分开,并且使用 CSS 将空白内容插入网页以破解空白似乎比人们仅使用 HTML 时更糟糕。除非有人能提出相反的合理论点,否则我不得不认为这不是一个好习惯。
      • 这并不完美,不。我可能会建议添加一个空的tbody 和/或tr,例如this, for example。但是,似乎无论发生什么,都必须是某种“黑客”。也许只是因为当前的实现不完整。
      • 我不同意使用定位是一种技巧。它完全按照预期的方式在页面上放置元素,否则表格将按照 w3c 的预期运行 - 它是一个实心块,行之间没有空格。
      • @KonstantinLevin 定位和大卫托马斯上面的例子都不起作用,前者是因为我在下面的评论中提到的原因,后者是因为它只是用纯色覆盖了填充,我不能这样做因为我在那里有一个背景渐变。无论如何感谢您的帮助。
      【解决方案3】:

      要将margin 应用于表格的第一行,您需要先将其设为display: block;,因为边距只能应用于块元素(包括内联块)

      但这里有另一种使用定位的解决方案:

      <head><style>
        table {
          border-collapse: collapse;
          border-spacing: 0;
          position: relative; /* Add positioning */
          margin-top: 40px; /* Add some margin */
        }
        thead {
          border-bottom: 4px solid #123456;
        }
        /*** something goes here ***/
        thead {
          position: absolute; /* Position this element absolute */
          top: -40px;  /* And move it up */
        }
        tbody tr:hover {
          background-color: #ABCDEF;
        }
      </style></head>
      
      <body>
        <table>
          <thead>
            <tr><th>Fruit</th><th>Color</th><th>Yummy?</th></tr>
          </thead>
          <tbody>
            <tr><td>Apple</td><td>Green</td><td>Yes</td></tr>
            <tr><td>Banana</td><td>Yellow</td><td>Yes</td></tr>
            <tr><td>Pear</td><td>Brown</td><td>Yes</td></tr>
          </tbody>
        </table>
        <p>Thats how its done!</p>
      </body>
      

      基本上我们将position: relative; 应用于表格并将position: absolute; 应用于头部。 现在您可以使用topbottomleftright 属性在表格内移动thead。我们将使用top: -40px; 将其向上移动 40px 我们不会将position: absolute; 应用于 tbody,因为如果我们这样做 - 此元素将不再“拉伸页面”,或者换句话说,所有以下元素将忽略其高度。 (尝试这样做,看看下面会发生什么

      块) 我们剩下的唯一一件事就是在表格本身上应用一些 margin-top,将其向下移动(当我们将 thead 向上移动时)

      是的,CSS 有时看起来有点奇怪,但这主要是因为我们忘记了一些页面元素应该如何处理(即表格及其子元素)

      【讨论】:

      • 我试过你的例子。然后我尝试使用display: block; margin-bottom: 20px; 对所有&lt;tr&gt; 元素进行样式设置。我所有的列都没有垂直对齐。 display: block; 一定有什么东西会影响表格对齐。但至少 margin 现在可以工作了。
      • 好块元素应该转到下一个“行”,因此您可以将其更改为 inline-block 以将它们保持在一个单独的行上。实际上,我找到了另一个使用定位的快速解决方案,我会在一分钟内更新我的答案。
      【解决方案4】:

      在开头添加一个空行怎么样

      <tbody>
          <tr><td> </td></tr>
          <tr><td>blablablabla</td></tr>
      

      并使用这个 CSS

      tbody tr:first-child td{
          padding-top: 15px;
      }
      tbody tr:first-child:hover{    
          background-color: transparent;
      }
      

      所以填充将被添加到第一行并且第一行不会在鼠标悬停时突出显示? :)

      【讨论】:

        【解决方案5】:

        你所有的 4 点都在那里-

        1. 首先在这里下载metro ui css http://metroui.org.ua/
        2. 将其两个 css 文件 1.metro-bootstrap、2.metro-bootstrap-responsive 包含到您的项目中。
        3. 在 BundleConfig 中注册。

          bundles.Add(new StyleBundle("~/Content/css/metroUI").Include("~/Content/css/metro-bootstrap.css", "~/Content/css/metro-bootstrap-responsive.css"));

        4. 现在对表格使用“gr-items”类

        <thead>
            <tr><th><span>Comment</span></th></tr>
        </thead>
        <tbody>
            <tr>
                <td><span>OperationDateTime</span></td>
            </tr>
             <tr>
                <td><span>OperationDateTime</span></td>
             </tr>
        </tbody>
        

        希望这是你想要的。

        【讨论】:

        • 这说明不了什么。而且您的解决方案需要更改标记(“说明如何在不更改标记的情况下进行操作”)。如果您想了解上述问题,我认为您应该避免使用框架。如果您正在寻找一个干净的解决方案,您应该尝试减少您的代码,而不是使用过度的额外 css 来扩展它