<label> 怎样才能完全填满它的父 <td> 呢?

Posted

技术标签:

【中文标题】<label> 怎样才能完全填满它的父 <td> 呢?【英文标题】:How can a <label> completely fill its parent <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:我使用表格的原因是语义。我确实在展示表格数据。另外,这与我的问题无关。 失败的原因与:***.com/questions/1122381/… 【参考方案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 属性,当然,您对第二个 【参考方案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">
            tdborder:1px solid #000;width:200px;height:200px;
            labeldisplay: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%;

【讨论】:

以上是关于<label> 怎样才能完全填满它的父 <td> 呢?的主要内容,如果未能解决你的问题,请参考以下文章

如何使 <div> 完全填满浏览器窗口,包括截至 2019 年的 Mobile Safari

隐藏/锁定 <form> 按钮,直到表单完全填满验证

隐藏视图并相应地重新定位其他视图

XPath:从子节点获取父节点

怎样用JS获得<label>标签中的值

如何在 Git 中获取合并提交的父项?