【问题标题】:CSS-based layout基于 CSS 的布局
【发布时间】:2016-06-01 23:38:24
【问题描述】:

哦,基于表格的布局的黄金时代。我们不应该都回到那里去搞砸语义吗? (我知道,我知道,...)

但是我有一个棘手的网站布局,如果我使用表格,它可以在几秒钟内完成,并且只需要很少的代码行。两天来,我一直在努力实现与 div 相同的目标。也许有人可以帮忙。

这是我想要实现的布局: http://jsfiddle.net/reltek/13c6yfmh/

这是使用表格的代码,很简单:

<table border="1" width="100%">    
  <tr>
    <th rowspan="2" width="30%" valign="top">            
      <h2>Main Navigation</h2>
      <p>Might get really long, sometimes even longer than the Main Content and Footer combined.</p>
      <ul>
        <li>Nav 1</li>
        <li>Nav 2</li>
        <li>Nav 3</li>
      </ul>
    </th>
    <td valign="top">
      <h1>Main Content</h1>
      <p>Flexible, might get really long.</p>          
    </td>
  </tr>
  <tr>
    <td height="3em">      
      <h2>Footer</h2>
      <p>flexible height, should stay at the bottom of the page.</h2>
    </td>
  </tr>
</table>

我的基于 div 的 HTML 可以在这里找到:http://jsfiddle.net/reltek/48rmshen/

问题是:如果左列比右列长,则右侧的页脚不会停留在底部。

感谢大家的帮助,谢谢!

【问题讨论】:

  • 说到,他们的时间不仅仅是过去。如果表具有语义意义,则应使用它们。例如:如果你想显示表格数据(通常会放在电子表格中的东西),那么你应该使用表格。所以,尊重你的桌子并适当地使用它们。

标签: html css layout html-table


【解决方案1】:

这是flexbox 的工作(旧浏览器的前缀和解决方法留给读者练习)

body {
    display: flex;
}
nav {
    background: red;
}
.non-nav {
    display: flex;
    flex-direction: column;
}
main {
    background: green;
    flex-grow: 1;
}
footer {
    background: blue;
    flex-shrink: 1;
}
<nav>
     <h2>Main Navigation</h2>

    <p>Might get really long, sometimes even longer than the Main Content and Footer combined.</p>
    <ul>
        <li>Nav 1</li>
        <li>Nav 2</li>
        <li>Nav 3</li>
    </ul>
</nav>
<div class="non-nav">
    <main>
         <h1>Main Content</h1>

        <p>Flexible, might get really long.</p>
        <p>&nbsp;</p>
        <p>&nbsp;</p>
        <p>&nbsp;</p>
        <p>&nbsp;</p>
        <p>&nbsp;</p>
        <p>&nbsp;</p>
        <p>&nbsp;</p>
        <p>&nbsp;</p>
        <p>end of text</p>
    </main>
    <footer>
         <h2>Footer</h2>

        <p>flexible height, should stay at the bottom of the page.</p>
        <ul>
            <li>Nav 1</li>
            <li>Nav 2</li>
            <li>Nav 3</li>
        </ul>
    </footer>
</div>

【讨论】:

  • 感谢您指向 flexbox,我更喜欢干净的文档结构。但是糟糕的浏览器支持(几乎没有 IE)让我回避了这个选项。但转念一想,包括 IE 解决方法可能会奏效。
  • IE
  • 一针见血:这是一个企业/大学/科学网站。 IE9 甚至 IE8 仍然很常见。
【解决方案2】:

在您的示例中与您的 display:table 保持一致,以下工作。 这是jsfiddle http://jsfiddle.net/r4pg8p25/2/

您可以添加和减去空白段落,并查看它与左侧面板同步扩展和收缩。

希望这会有所帮助, 蒂姆

<html>
    <header>
        <style>  

            html, body { text-align: justify; height: 100%; }

            .layout { display: table;  height: 100%;}
            .layout .columns-container { display: table-row;  height: 100%;}
            .layout .columns-container .column { display: table-cell;  height: 100%;}
            .layout .top { display: table-row;  height: 100%;}
            .layout .bottom { display: table-row;  height: 100%;}
            .layout .top .main{ display: table-cell;  height: 100%;}
            .layout .top .footer{ display: table-cell;  height: 100%;}

            .one-third { width:33%; float: left;  height: 100%;}
            .two-thirds { width:66%; height:100%; float: right; }

            .main-footer { height: 100%; }

            .nav { background: red; padding: 20px; }
            .main { background: green; padding: 20px;  height: 100%; }
            .footer { background: brown; padding: 20px; height: 150px; }

        </style>
    </header>
    <body>
        <div class="layout">
            <div class="columns-container">
                <div class="column one-third">
                    <div class='nav'>
                        <h2>Main Navigation</h2>
                        <p>Might get really long, sometimes even longer than the Main Content and Footer combined.</p>
                         padding-bottom:100%; margin-bottom:-100%;
                        <ul>
                            <li>Nav 1</li>
                            <li>Nav 2</li>
                            <li>Nav 3</li>
                        </ul>
                        <p>&nbsp;</p>
                        <p>&nbsp;</p>
                        <p>&nbsp;</p>
                        <p>&nbsp;</p>
                        <p>&nbsp;</p>
                        <p>&nbsp;</p>
                        <p>&nbsp;</p>
                        <p>&nbsp;</p>
                        <p>&nbsp;</p>
                        <p>&nbsp;</p>
                        <p>&nbsp;</p>
                        <p>&nbsp;</p>
                        <p>end</p>
                    </div>
                </div>
                <div class="column two-thirds">
                    <div class="layout main-footer">
                        <div class='top'>
                            <div class="main" role="main">
                                <h1>Main Content</h1>
                                <p>Flexible, might get really long.</p>
                                <p>end of text</p> 
                            </div>
                        </div>

                        <div class='bottom'>
                            <div class="footer">
                                <section id="colophon" class="site-info" role="contentinfo">
                                    <h2>Footer</h2>
                                    <p>flexible height, should stay at the bottom of the page.</p>
                                </section>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>        
    </body>
</html>

【讨论】:

  • 谢谢蒂姆,我对它进行了修改,它完全按计划工作。不过,实现这种效果的 div 数量相当大。所以我选择了一个灵活的高度页脚,这样可以减少文档结构的混乱。在设计上不是完美的解决方案,但我想我会等待更好的 flexbox 支持。
  • 没问题,我也会这样做。事实上,在我开始之前,我已经看到了@Quentin 的答案。我认为看到完成同一件事的多种方法总是很好,我认为你会很高兴看到它以你开始的方式完成。有一个伟大的。
  • 您可能希望接受正确的答案(根据您提出的问题)。你让它坐了一会儿。最好的。
【解决方案3】:

你可以使用display:table,但不幸的是你不能做rowspan,所以你需要对div结构有点创意:

html, body {
    min-height:100%;
    padding:0;
    margin:0;
}
#wrapper {
    position:absolute;
    top:0;
    bottom:0;
    left:0;
    right:0;
}
.table {
    display:table;
    width:100%;
    height:100%;
}
.row {
    display:table-row;
}
.cell {
    display:table-cell;
}
#left-column {
    width:30%;
    background:red;
}
#right-column {
    width:70%;
    height:100%;
}
#content, #header {
    height:100%;
}
#header {
    background-color:green;
}
#footer {
    background-color:blue;
}
<div id="wrapper">
    <div class="table">
        <div class="row">
            <div id="left-column" class="cell">
                 <h2>Main Navigation</h2>

                <p>Might get really long, sometimes even longer than the Main Content and Footer combined.</p>
                <ul>
                    <li>Nav 1</li>
                    <li>Nav 2</li>
                    <li>Nav 3</li>
                </ul>
            </div>
            <div id="right-column" class="cell">
                <div id="content" class="table">
                    <div id="header" class="row">
                        <div class="cell">
                             <h1>Main Content</h1>

                            <p>Flexible, might get really long.</p>
                        </div>
                    </div>
                    <div id="footer" class="row">
                        <div class="cell">
                             <h2>Footer</h2>

                            <p>flexible height, should stay at the bottom of the page.</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Example Fiddle

【讨论】:

  • 感谢Pete,这正是我想要实现的!我希望有一个更简单的文档结构,而不仅仅是模仿表格结构。但这似乎是要走的路。
  • 您可以在 Quentin 的回答中使用 flex 结构(取决于您需要支持的浏览器)并将其拉伸到 100% 高度。
  • 不幸的是,网站流量将非常依赖 IE... :-( 不需要 100% 高度,因为有问题的部分只是整个页面的一小部分(添加页眉等) .).