【问题标题】:How can a <label> completely fill its parent <td>?<label> 怎样才能完全填满它的父 <td> 呢?
【发布时间】:2011-02-19 22:52:56
【问题描述】:

这是相关代码(不起作用):

<html>
<head>
<title>testing td checkboxes</title>
<style type="text/css">
td { border: 1px solid #000; }
label { border: 1px solid #f00; width: 100%; height: 100% }
</style>
</head>
<body>
<table>
  <tr>
    <td>Some column title</td>
    <td>Another column title</td>
  </tr>
  <tr>
    <td>Value 1<br>(a bit more info)</td>
    <td><label><input type="checkbox" /> &nbsp;</label></td>
  </tr>
  <tr>
    <td>Value 2</td>
    <td><input type="checkbox" /></td>
  </tr>
</table>
</body>
</html>

原因是我希望单击表格单元格中的任意位置以选中/取消选中复选框。

编辑: 顺便说一句,出于可访问性的原因,请不要使用 javascript 解决方案。 我尝试使用 display: block;但这仅适用于宽度,不适用于高度

【问题讨论】:

  • 如果您担心可访问性,则不应使用表格布局来格式化表单。
  • @Andreas:我使用表格的原因是语义。我确实在展示表格数据。另外,这与我的问题无关。

标签: css


【解决方案1】:

我只在 IE 6、7、8 和 FF 3.6.3 中测试过。

<html>
<head>
<title>testing td checkboxes</title>
<style type="text/css">
tr {
    height: 1px;
}
td {
    border: 1px solid #000;
    height: 100%;
}
label { 
    display: block; 
    border: 1px solid #f00;
    min-height: 100%; /* for the latest browsers which support min-height */
    height: auto !important; /* for newer IE versions */
    height: 100%; /* the only height-related attribute that IE6 does not ignore  */
}
</style>
</head>
<body>
<table>
    <tr>
        <td>Some column title</td>
        <td>Another column title</td>
    </tr>
    <tr>
        <td>Value 1<br>(a bit more info)</td>
        <td><label><input type="checkbox" /> &nbsp;</label></td>
    </tr>
</table>
</body>
</html>

这里的主要技巧是定义行的高度,以便我们可以在其子项(单元格)上使用 100% 的高度,而在单元格的子项(标签)上依次使用 100% 的高度。这样,无论一个单元格中有多少内容,它都会强制扩展其父行,其兄弟单元格将跟随。由于标签的高度为已定义其高度的父级的 100%,因此它也会垂直扩展。

第二个也是最后一个技巧(但同样重要)是对 min-height 属性使用 CSS hack,如 cmets 中所述。

【讨论】:

  • 恭喜您获得了纯 CSS 跨浏览器解决方案!我只是不明白设置 1px 高度有什么帮助。显然,只要在 中找到任何内容,就会完全忽略 1px 高度,因此 的高度是“动态”确定的,或者更确切地说,根据内容确定。那么,这与在 上根本不设置高度有什么区别?
  • 我一直认为它的工作方式是它为 的子级百分比高度提供了一个实际值,而不是根本没有定义(NULL?)。你会注意到,一旦你把它拿出来,模型就会停止工作,因为 的高度值没有任何关系——即 100% 的 NULL 仍然是 NULL。
  • 不是跨浏览器。它不适用于 Safari 5.0、Iron 5.0.380 或 Opera 9.64。
  • 半跨浏览器呢? :) 严肃地说,我也相信确保这适用于所有浏览器(或至少尽可能多的浏览器)的唯一方法将意味着在某种程度上使用 JS,但话又说回来,这也将如果用户出于某种原因禁用了 JS,则完全失败。我想最终“正确”的答案完全取决于肖恩需要他的应用程序在什么上运行。
  • 完全失败是什么意思?我的 jQuery 解决方案是渐进式增强。绝大多数用户(是的,甚至有屏幕阅读器的人)都启用了 JS。即使对于那些没有的,它也会依赖 CSS。但话又说回来......你也可以禁用CSS。 ;)
【解决方案2】:

默认情况下,标签是内联元素,因此设置宽度和高度不起作用。

label { display: block; }

会做的。

(但是,将标签围绕它应该与之关联的复选框而不是显式使用for的做法在IE中不起作用。)

【讨论】:

  • 显示:块适用于宽度,但不适用于高度。但是非常感谢那个 IE 警告!我想我可以将输入元素包装在标签中并在其中放置一个 for 属性,对吧?
  • 是的,你可以。实际上刚刚检查过,这在 IE7 中已修复;只有IE6会受到影响。您可以在块上设置height,但如果您设置百分比高度,则父元素(相对于百分比)必须自己指定height
  • 好吧,在这种情况下,父元素没有指定高度。那我该怎么办?
  • 嗯,TD 的高度取决于它的内容。 CSS有没有办法说:“一旦我们确定了TD元素的尺寸,让标签元素100%的TDs宽度和高度”?
  • 不是,因为&lt;td&gt;的内容区域的高度就是&lt;label&gt;的高度。不知道单元格中静态流内容的高度,就无法知道单元格的auto高度。
【解决方案3】:

您应用标签的方式并不能使表单元素完全可访问。标签应应用于与表单元素关联的文本,而不仅仅是表单元素。但是在表单元素上添加另一个标签以使TD 内的整个区域可点击并没有错。这实际上是可取的,以便为有运动障碍的人提供更大的点击区域。 &lt;label for="whatever"&gt;Your label&lt;/label&gt; 面向使用屏幕阅读器浏览 Web 表单的用户。

此外,使用 JavaScript 增强可访问性并没有什么不可访问性。只要 JavaScript 优雅降级并且不会阻止屏幕阅读器阅读页面,就可以使用 JavaScript。此外,没有办法在不严重破坏页面外观的情况下使用 CSS 来填充旧版本 IE(仍然被大量用户使用)的单元格高度。这就是说,你应该使用 jQuery 来填充整个TD。我不说 JavaScript 的原因是 jQuery 隐藏了许多复杂的代码,让你在绝大多数浏览器中都能正常工作。

这是完全跨浏览器可访问的启用 jQuery 的代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <title>Accessible Checkboxes</title>

    <script type="text/javascript" src="js/jquery.min.js"></script>

    <script type="text/javascript">
      $(document).ready(function() {
        $("table > tbody tr").each(function() { // Loop through all table rows
          var Highest=0; // We want to find the highest TD... start at zero
          var ThisHeight=0; // Initiate the temporary height variable (it will hold the height as an integer)

          $($(this).children('td')).each(function() { // Loop through all the children TDs in order to find the highest
            ThisHeight=parseInt($(this).height()); // Grab the height of the current TD

            if (ThisHeight>Highest) { // Is this TD the highest?
              Highest=ThisHeight; // We got a new highest value
            }
          });

          $(this).children('td').css('height',Highest+'px');  // Set all TDs on the row to the highest TD height
        });
      });
    </script>

    <style type="text/css">
      table {
        border: 1px solid #000;
      }

      td, label { 
        height: 100%;
        min-height: 100%;
      }

      th {
        text-align: left;
      }

      td, th {
        border: 1px solid #000;
      }

      label { 
        display: block;
      }
    </style>
  </head>
  <body>
    <form action="whatever.shtml" method="post" enctype="multipart/form-data">
      <table cellspacing="3" cellpadding="0" summary="A description of what's in the table.">
        <thead>
          <tr>
            <th scope="col">Some column title</th>
            <th scope="col">Another column title</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td scope="row"><label for="value1">Value 1<br />(a bit more info)</label></td>
            <td><label><input id="value1" type="checkbox" /> &nbsp;</label></td>
          </tr>
          <tr>
            <td scope="row"><label for="value2">Value 2</label></td>
            <td><label><input id="value2" type="checkbox" /></label></td>
          </tr>
        </tbody>
      </table>
    </form>
  </body>
</html>

您需要下载jQuery 并将jquery.min.js 文件放在名为js 的文件夹下。

正如您在代码中看到的,通过添加table summarytheadthscopelabel for 等,该表单已完全可访问。当然,它不是你问了什么,但我把它作为额外的奖励添加了。

【讨论】:

  • 现在这是一个详尽的答案!非常感谢!我不知道 scope 属性和 summary 属性,当然,您对第二个
  • 没问题肖恩。我已经在需要可访问性的环境中工作了大约 6 年以上。你边走边学。 :) 至于脚本...某些浏览器(cough IE cough)没有将TD 的高度设置为TR 的完整高度当一个TD 高于其他时。该脚本纠正了这个缺陷。它的作用是逐行检查哪个TD 是该特定行的最高值。然后它将该行的所有TD 高度显式设置为最大值。这样,LABEL 单元格将能够跨越单元格的整个高度。
  • 我明白了,感谢您的澄清。所以你也会认为如果没有 javascript,我想要实现的目标是不可能的?
  • 是的,如果您的目标是跨浏览器兼容性,这是不可能的。在这种情况下,JavaScript (jQuery) 将提高您网页的可访问性。
  • 不可能?对于 FreekOne 提出的解决方案,您有什么想说的?它是纯 CSS 的。是跨浏览器吗?
【解决方案4】:

我没有发现其他答案在当前浏览器(2017)中有效,但绝对定位标签对我有用:

https://jsfiddle.net/4w75260j/5/

<html>
<head>
    <style type="text/css">            
        td.checkbox {
            position: relative;
        }
        td.checkbox label {
            /* Take up full width/height */
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;

            /* Ensure the checkbox is centered */
            display: flex;
            align-items: center;
            justify-content: center;
        }
    </style>
</head>
<body>
    <table>
        <tr>
            <td>Checkboxes</td>
            <td>Text</td>
        </tr>
        <tr>
            <td class="checkbox"><label><input type="checkbox" /></label></td>
            <td>Lorem ipsum dolor sit amet...</td>
        </tr>
    </table>
</body>
</html>

请注意,此解决方案使用 flexbox 使复选框居中;如果您的目标是较旧的浏览器,您可能需要尝试transform style of centering

【讨论】:

    【解决方案5】:

    此代码可以满足您的需求,并且已在 IE7+、FF、Google Chrome、Opera 和 Safari 上进行了测试:

    <html>
        <head>
            <title>testing td checkboxes</title>
    
            <style type="text/css">
                td{border:1px solid #000;width:200px;height:200px;}
                label{display:block;border:1px solid #f00;width:198px;height:198px;}
            </style>
    
        </head>
        <body>
    
            <table>
                <tr>
                    <td>Some column title</td>
                    <td>Another column title</td>
                </tr>
                <tr>
                    <td>Value 1<br>(a bit more info)</td>
                    <td><label><input type="checkbox" /> &nbsp;</label></td>
                </tr>
                <tr>
                    <td>Value 2</td>
                    <td><input type="checkbox" /></td>
                </tr>
            </table>
    
        </body>
    </html>
    

    如果您的问题没有解决,希望这能解决它! ;)

    【讨论】:

    • 谢谢,但我不能保证我的内容总是适合 200 x 200 像素,我当然不希望出现滚动条..
    • 我放置的宽度和高度仅用于演示目的!它可以根据您的需要进行更改...目标是告诉您必须设置宽度和高度,否则您想要的将不起作用!
    • 我明白了。不幸的是,由于内容的动态特性,我无法提前知道内容需要多大的单元格。
    【解决方案6】:

    这个答案有点“不合时宜”——要成为有效的 HTML,您必须定义自己的 DTD,而且无论如何它在 IE 或 Opera 中不起作用(在 Firefox 中起作用)。因此,无论如何这都不是一个可行的解决方案,但我想我还是会出于兴趣分享:

    HTML:

    <table>
        <tr>
            <td>Some content</td>
            <label><input type="checkbox" /></label> <!-- no TD -->
        </tr>
        <tr>
            <td>Some<br />multi-line<br />content</td>
            <label><input type="checkbox" /></label>
        </tr>
    </table>
    

    CSS:

    label { display: table-cell; }
    

    【讨论】:

    • 有趣。我对自定义 DTD 的了解还不够(我计划有一天学习)以完全理解这个解决方案,但这是我还没有想到(也没有见过)的一种方法。感谢分享!
    • @Gert,理论上 屏幕阅读器应该检查元素的 style 以确定如何处理它,而不是 名称。但是,是的,你是对的:就像我说的那样,考虑到糟糕的跨浏览器支持,这确实不可行。
    • @nickf - 对此表示怀疑。您可能想阅读语义标记和可访问性。
    【解决方案7】:

    我想点击表格单元格中的任意位置

    <tr onclick="alert('process click here');"> ... </tr>
    

    【讨论】:

    • 我应该添加:“出于可访问性的原因,没有 javascript”但无论如何谢谢 :)
    • 那么,为什么不玩 tr:hover 呢??
    • 有趣,但是 CSS 可以选中和取消选中复选框吗? tr:hover {选中/取消选中复选框}
    • 实际上,你能解释一下“玩 tr:hover”是什么意思吗?
    【解决方案8】:

    为你的标签试试这个 CSS

    label  {
     border:1px solid #FF0000;
     display:block;
     height:35px;
    }
    

    这里是现场演示http://jsbin.com/ehoke3/2/

    【讨论】:

    • 如果左列中间的那个单元格有另一行文本怎么办?或者如果我后来决定更改文本大小怎么办?这个解决方案并不理想,因为我不能总是知道细胞的精确高度。
    • 你有两个选择,要么使用内联样式,要么你真的应该使用 JavaScript——我的意思是为什么不呢?
    • 我真的不明白内联样式对我有什么帮助。在我编写代码时,我仍然无法确定 TD 的精确像素大小,而且它可能会随着时间而改变。而对于 javascript,如果一切都失败了我不介意,但我仍然觉得我应该为那些没有它的人尝试一下(出于各种原因)
    【解决方案9】:

    在您的“价值 1”行中,您不仅有“更多信息”,还包括休息时间。在我看来,当左列中的内容包含&lt;br&gt; 时,您真正需要做的就是在右列的任何标签中包含&lt;br&gt;。此外,显然&lt;label&gt; 需要将display CSS 属性设置为block

    <html>
    <head>
    <title>testing td checkboxes</title>
    <style type="text/css">
    td { border: 1px solid #000; }
    label { border: 1px solid #f00; display: block;}
    </style>
    </head>
    <body>
    <table>
    <tr><td>Some column title</td><td>Another column title</td></tr>
    <tr><td>Value 1<br>(a bit more info)</td><td><label><input type="checkbox" /> &nbsp;<br>&nbsp;</label></td></tr>
    <tr><td>Value 2</td><td><label><input type="checkbox" /></label></td></tr>
    </table>
    </body>
    </html>
    

    请注意:如果不使用 JavaScript 之类的东西,您将无法在过去 10 年的所有主要浏览器中获得完美的工作性能(例如 IE6)。我相信我的解决方案是不借助 JavaScript 的最佳解决方案。

    【讨论】:

    • 更多关于 IE6 隐式标签错误:evotech.net/blog/2009/09/ie6ie7-implicit-label-bug
    • 我刚刚添加了
      以便内容会用完两行。内容还有其他方式可以用完两行(或更多行),例如有一个很长的文本字符串,需要分成两行以适应屏幕。这意味着简单地计算
      s 并在右列中添加相同的数量并不总是有效。但是非常感谢您的尝试。
    【解决方案10】:

    解决方法如下:

    • &lt;label&gt; 完全填满&lt;td&gt; 高度
    • 支持任何单元格高度(即没有固定的像素高度)
    • 仅适用于 CSS(即无 JavaScript)
    • 是多浏览器(MSIE 7/8/9/10/11、Firefox 42、Chrome 46、Seamonkey 2.39、Opera 33、Safari 5.1.7)

    <html>
    <head>
    <title>testing td checkboxes</title>
    <style type="text/css">
    td { border: 1px solid #000; }
    label { border: 1px solid #f00; display:block; min-height:2.3em;}
    </style>
    </head>
    <body>
    <table style="table-layout:fixed">
      <tr>
        <td>Some column title</td>
        <td>Another column title</td>
      </tr>
      <tr>
        <td>Value 1<br>(a bit more info)</td>
        <td><label><input type="checkbox" style="vertical-align:-50%" />&nbsp;</label></td>
      </tr>
      <tr>
        <td>Value 2</td>
        <td><input type="checkbox" /></td>
      </tr>
    </table>
    </body>
    </html>

    解释:

    • display:block 使&lt;label&gt; 占据&lt;td&gt; 全宽
    • min-height:2.3em; 使&lt;label&gt; 采用&lt;td&gt; 全高(最小高度略高于两行,因为该行的第一个单元格中有两行;您可能需要增加,例如,我在代码中使用 3.3em)
    • vertical-align:-50% 使复选框在单元格的中心垂直对齐(仅当单元格内容跨越的行数少于行的第一个单元格时才需要这样做)

    【讨论】:

      【解决方案11】:

      我发现使用 display: table 对我有用。我尝试了(之前建议的)display: table-cell,但没有奏效。

      td label {
          display: table;
          box-sizing: border-box;
          width: 100%;
          height: 100%;
      }
      

      【讨论】:

        猜你喜欢
        相关资源
        最近更新 更多
        热门标签