在<a>标记中包装HTML表格行

Yar*_*rin 45 html html-table

是否可以将整个表行包装在<a>标签中?我希望整行成为可点击的链接.

如果我尝试以下操作,链接将在表格的上方和外部呈现:

这个:

<table>
<a href="value_url"><tr><td>value</td><td>value</td></tr></a>
<a href="value_url"><tr><td>value</td><td>value</td></tr></a>
</table>
Run Code Online (Sandbox Code Playgroud)

渲染如下:

<a href="value_url"></a>
<a href="value_url"></a>
<table>
<tr><td>value</td><td>value</td></tr>
<tr><td>value</td><td>value</td></tr>
</table>
Run Code Online (Sandbox Code Playgroud)

N4p*_*peL 38

因为每个td中的链接不是一个好的选择,使用js有点脏,这是另一种html/css方法:

HTML:

<div class="table">
    <a class="table-row" href="/mylink">
        <div class="table-cell">...</div>
        <div class="table-cell">...</div>
        <div class="table-cell">...</div>
    </a>
</div>
Run Code Online (Sandbox Code Playgroud)

CSS:

.table { display:table; }
.table-row { display:table-row; }
.table-cell { display:table-cell; }
Run Code Online (Sandbox Code Playgroud)

  • 这不是一个好方法.这不是语义,不能很好地与屏幕阅读器一起使用. (14认同)
  • 该解决方案打破了网络.仅在您不关心可访问性或可用性时使用. (5认同)
  • 您可以探索使用aria-role使屏幕阅读器更容易访问. (4认同)

Boj*_*les 37

它之所以呈现,是因为浏览器遵循W3C规范,只允许<tr>标签作为直接后代<table>.

作为一种解决方案,您可以<a>每个 标记内部放置一个<td>指向同一URL 的标记:

<table>
    <tr>
        <td>
            <a href="http://url/stuff">
                First column
            </a>
        </td>
        <td>
            <a href="http://url/stuff">
                Second column
            </a>
        </td>
    </tr>
</table>
Run Code Online (Sandbox Code Playgroud)

或者您可以使用JavaScript 绑定onClick处理程序<tr>.一个jQuery示例是这样的:

$('table tr').click(function() {
    window.location = 'http://location/here';
});
Run Code Online (Sandbox Code Playgroud)

或者,更好的是,使用委托事件(jQuery 1.7+):

$('table').on('click', 'tr', function() {
    window.location = 'http://location/here';
});
Run Code Online (Sandbox Code Playgroud)

  • 我们曾经使用过Javascript版本而后悔了.用户无法按住Ctrl键单击或按住Shift键单击以在新选项卡/窗口中打开.值得注意的是; 它甚至可能适合您的应用/网站. (24认同)
  • @BernhardHofmann可以在点击和测试`event.metaKey`或`event.ctrlKey`时捕获`event`,但我同意,它不太理想,因为有时它可能被弹出窗口拦截器阻止.http://stackoverflow.com/a/2445640/436014 (2认同)

小智 13

另一个简单的仅CSS解决方案是<a>变成块元素

<tr>
  <td><a href="#">name 1</a></td><td><a href="#">link 1</a></td>    
</tr>
<tr>
  <td><a href="#">name 2</a></td><td><a href="#">link 2</a></td>    
</tr>
Run Code Online (Sandbox Code Playgroud)

CSS将是:

td > a {
  display: block;
}
Run Code Online (Sandbox Code Playgroud)

然后,如果为一行中的每个单元格重复链接,那么<a>将占用整个<td>,并使整个行可以在没有JS的情况下单击.

https://jsfiddle.net/evwa451n/

  • @IanGoldby 什么是“-ve 利润”? (2认同)

Dav*_*mas 11

拥有除a 之外的任何元素或作为a的直接子元素thead,这是无效的HTML ,并且这些元素仅作为有效子元素.tbodytfoottabletr

任何其他内容必须在a内tdth有效.

您所看到的是浏览器重构DOM以使其尽可能有效.依赖于该行为的问题是不同的浏览器以不同的方式做出反应.

如果你需要一个tr交互式(以及点击这些元素来引导某些地方/做某事),你应该使用JavaScript.

但是,简短的回答,是的,你可以做到,但这样做无效,所以请不要这样做.

但是,对于交互式表行,一种解决方案(在纯JavaScript中):

var rows = document.getElementsByTagName('tr'),
    url;

for (var i=0,len=rows.length; i<len; i++){
    rows[i].onclick = function(){
        uri = this.getAttribute('data-url');
        window.location = uri;
    };
}
Run Code Online (Sandbox Code Playgroud)

JS小提琴演示.

(显然,这要求tr元素具有一个data-url属性来指定它们应链接到的位置.)


Jan*_*an 7

使用CSS 子网格的新的甚至更好的解决方案(我很兴奋):

我们现在可以对表行使用子网格。这样我们还可以向各个行添加悬停状态或填充。

<style>
.grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, auto)); /* Auto sizing columns */
}
.grid-row {
  display: grid;
  grid-template-columns: subgrid; /* New feature, makes row inherit parents grid */
  grid-column: 1 / -1; /* make row span full grid */
}
</style>

<div class="grid">
  <div>Header column 1</div>
  <div>Header column 2 (Any content size works)</div>
  <div>Header column 3</div>
  <a href="https://example.com" class="grid-row">
    <div>Every column adjusts dynamically</div>
    <div>Content 2</div>
    <div>Content 3</div>
  </a>
  <a href="https://example.com" class="grid-row">
    <div>Content 1</div>
    <div>Content 2</div>
    <div>Content 3</div>
  </a>
  <a href="https://example.com" class="grid-row">
    <div>Content 1</div>
    <div>Works like a table!</div>
    <div>Content 3</div>
  </a>
</div>
Run Code Online (Sandbox Code Playgroud)

新奇的解决方案:有趣的是,到 2021 年,仍然没有针对带有链接的表行的干净解决方案 - 我建议您改用显示网格。使用repeat(YOUR_COLUMN_COUNT, minmax(0, auto))forgrid-template-columns可以实现网格的行为与表格非常相似 - 您可以自动调整大小和调整列。此外,您可以使用锚标记,甚至创建粘性标题,而不会发疯:

<div style="display: grid; grid-template-columns: repeat(3, minmax(0, auto));">
  <div>Header column 1</div>
  <div>Header column 2 (Any content size works)</div>
  <div>Header column 3</div>
  <a href="https://example.com" style="display: contents;">
    <div>Every column adjusts dynamically</div>
    <div>Content 2</div>
    <div>Content 3</div>
  </a>
  <a href="https://example.com" style="display: contents;">
    <div>Content 1</div>
    <div>Content 2</div>
    <div>Content 3</div>
  </a>
  <a href="https://example.com" style="display: contents;">
    <div>Content 1</div>
    <div>Works like a table!</div>
    <div>Content 3</div>
  </a>
</div>
Run Code Online (Sandbox Code Playgroud)

更新:不幸的是,除非使用 JavaScript 动态插入表行,否则下面的原始解决方案不起作用(请参见下面的示例)。当通过 JavaScript 插入新元素时,浏览器会跳过语法检查,这样就可以让锚标记保留在表中并防止浏览器将它们移出。

let tbody = document.getElementById("myTBody");

for (let i = 0; i < 2; i++) {
  let anchor = document.createElement("a");

  anchor.setAttribute("style", "display: contents;");
  anchor.setAttribute("href", "https://example.com");

  let row = document.createElement("tr");

  let col1 = document.createElement("td");
  let col2 = document.createElement("td");
  col1.append(document.createTextNode("Column 1"));
  col2.append(document.createTextNode("My longer Column 2"));

  row.appendChild(col1);
  row.appendChild(col2);

  anchor.appendChild(row);
  tbody.appendChild(anchor);
}
Run Code Online (Sandbox Code Playgroud)
<p>This table doesnt work with anchors around the rows:</p>
<table>
  <thead>
    <tr>
      <th>Column 1</th>
      <th>Column 2</th>
    </tr>
  </thead>
  <tbody>
    <a href="https://example.com" style="display: contents !important;">
      <tr>
        <td>Column 1</td>
        <td>My longer Column 2</td>
      </tr>
    </a>
    <a href="https://example.com" style="display: contents !important">
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
      </tr>
    </a>
  </tbody>
</table>
<p>This table does work with anchors around the rows:</p>
<table>
  <thead>
    <tr>
      <th>Column 1</th>
      <th>Column 2</th>
    </tr>
  </thead>
  <tbody id="myTBody">
    <!-- Rows get inserted by javascript -->
  </tbody>
</table>
Run Code Online (Sandbox Code Playgroud)

原文:您也可以使用display: contents;. 这会导致 a 标签子项的行为就像它们是 a 标签父项的子项一样。

在您的 HTML 中:

<table>
  <thead>
    <tr>
      <th>Column 1</th>
      <th>Column 2</th>
    </tr>
  </thead>
  <tbody>
    <a href="https://example.com" style="display: contents;">
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
      </tr>
    </a>
    <a href="https://example.com" style="display: contents;">
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
      </tr>
    </a>
  </tbody>
</table>
Run Code Online (Sandbox Code Playgroud)

大多数时候,不同浏览器的支持应该足够了(请参阅https://caniuse.com/#feat=css-display-contents)。

  • 我认为这是最好的非 JavaScript 解决方案;但是,请注意,锚标记不包含在可访问性树中[这是大多数浏览器中的当前错误,应该包含它](请参阅MDN:https://developer.mozilla.org/en-US/docs/Web /CSS/display#display_contents) (2认同)

小智 5

您可以使用onclick,以便您可以动态获取内容

<td onclick="window.location='http://www.google.com';" style='cursor: pointer;'>Hello</td>
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/ankJw/