为何tbody内的<td>元素无法显示为100vw宽度?
问题:设置tbody内元素宽度为100vw未生效
我正在学习FreeCodeCamp响应式网页设计课程,当前处于「通过制作资产负债表学习CSS伪选择器」模块第53步。尝试设置tbody内的元素宽度为100vw,预期每个的宽度等于视口宽度,但实际并未实现。
相关源代码
CSS代码
span[class~="sr-only"] { border: 0 !important; clip: rect(1px, 1px, 1px, 1px) !important; clip-path: inset(50%) !important; height: 1px !important; width: 1px !important; position: absolute !important; overflow: hidden !important; white-space: nowrap !important; padding: 0 !important; margin: -1px !important; } html { box-sizing: border-box; } body { font-family: sans-serif; color: #0a0a23; } h1 { max-width: 37.25rem; margin: 0 auto; padding: 1.5rem 1.25rem; } h1 .flex { display: flex; flex-direction: column-reverse; gap: 1rem; } h1 .flex span:first-of-type { font-size: 0.7em; } h1 .flex span:last-of-type { font-size: 1.2em; } section { max-width: 40rem; margin: 0 auto; border: 2px solid #d0d0d5; } #years { display: flex; justify-content: flex-end; position: sticky; z-index: 999; top: 0; background: #0a0a23; color: #fff; padding: 0.5rem calc(1.25rem + 2px) 0.5rem 0; margin: 0 -2px; } #years span[class] { font-weight: bold; width: 4.5rem; text-align: right; } .table-wrap { padding: 0 0.75rem 1.5rem 0.75rem; } span { font-weight: normal; } table { border-collapse: collapse; border: 0; width: 100%; position: relative; margin-top: 3rem; } table caption { color: #356eaf; font-size: 1.3em; font-weight: normal; position: absolute; top: -2.25rem; left: 0.5rem; } tbody td { width: 100vw; }
HTML代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Balance Sheet</title> <link rel="stylesheet" href="./styles.css"> </head> <body> <main> <section> <h1> <span class="flex"> <span>AcmeWidgetCorp</span> <span>Balance Sheet</span> </span> </h1> <div id="years" aria-hidden="true"> <span class="year">2019</span> <span class="year">2020</span> <span class="year">2021</span> </div> <div class="table-wrap"> <table> <caption>Assets</caption> <thead> <tr> <td></td> <th><span class="sr-only year">2019</span></th> <th><span class="sr-only year">2020</span></th> <th class="current"><span class="sr-only year">2021</span></th> </tr> </thead> <tbody> <tr class="data"> <th>Cash <span class="description">This is the cash we currently have on hand.</span></th> <td>$25</td> <td>$30</td> <td class="current">$28</td> </tr> <tr class="data"> <th>Checking <span class="description">Our primary transactional account.</span></th> <td>$54</td> <td>$56</td> <td class="current">$53</td> </tr> <tr class="data"> <th>Savings <span class="description">Funds set aside for emergencies.</span></th> <td>$500</td> <td>$650</td> <td class="current">$728</td> </tr> <tr class="total"> <th>Total <span class="sr-only">Assets</span></th> <td>$579</td> <td>$736</td> <td class="current">$809</td> </tr> </tbody> </table> <table> <caption>Liabilities</caption> <thead> <tr> <td></td> <th><span class="sr-only">2019</span></th> <th><span class="sr-only">2020</span></th> <th><span class="sr-only">2021</span></th> </tr> </thead> <tbody> <tr class="data"> <th>Loans <span class="description">The outstanding balance on our startup loan.</span></th> <td>$500</td> <td>$250</td> <td class="current">$0</td> </tr> <tr class="data"> <th>Expenses <span class="description">Annual anticipated expenses, such as payroll.</span></th> <td>$200</td> <td>$300</td> <td class="current">$400</td> </tr> <tr class="data"> <th>Credit <span class="description">The outstanding balance on our credit card.</span></th> <td>$50</td> <td>$50</td> <td class="current">$75</td> </tr> <tr class="total"> <th>Total <span class="sr-only">Liabilities</span></th> <td>$750</td> <td>$600</td> <td class="current">$475</td> </tr> </tbody> </table> <table> <caption>Net Worth</caption> <thead> <tr> <td></td> <th><span class="sr-only">2019</span></th> <th><span class="sr-only">2020</span></th> <th><span class="sr-only">2021</span></th> </tr> </thead> <tbody> <tr class="total"> <th>Total <span class="sr-only">Net Worth</span></th> <td>$-171</td> <td>$136</td> <td class="current">$334</td> </tr> </tbody> </table> </div> </section> </main> </body> </html>
渲染效果

添加边框后的效果(可见宽度远小于100vw):
原因分析
- 父容器的宽度锁死:
<table>被设置为width: 100%,它的宽度直接继承自父元素.table-wrap,而.table-wrap又被包裹在max-width: 40rem的<section>中,这就导致表格的最大宽度被限制在40rem内,<td>作为表格子元素,无法突破这个宽度约束。 - 表格的布局规则限制:表格是特殊的布局容器,浏览器会自动根据列数、内容宽度分配列宽,单个
<td>的width设置会被表格的布局算法覆盖,优先保证表格整体的布局合理性,不会让单个单元格独占100vw的宽度。 - 100vw的生效条件:100vw代表视口宽度,但只有当元素的父容器没有宽度限制时,这个值才能正常生效。在表格布局中,单元格的宽度计算依赖于表格整体,而非独立的视口宽度。
可行解决方向
- 给
<table>设置width: 100vw,突破<section>的max-width限制,但会导致表格超出容器产生横向滚动 - 修改表格的显示模式,比如给
<tr>设置display: block,<td>设置display: block; width: 100vw,但这会破坏表格的默认行列结构 - 移除
<section>的max-width属性,让表格可以随视口宽度自适应
内容的提问来源于stack exchange,提问作者journeywithjavascript
相关产品推荐
相关产品推荐

