我在这样的布局上遇到问题:
.wrapper {
clear: both;
background-color: #ccc;
}
.wrapper+.wrapper {
margin-top: 50px;
}
.side,
.main {
height: 100px;
padding: 10px;
box-sizing: border-box;
margin-top: 20px;
}
.box {
padding: 10px;
}
.top {
background: yellow;
}
.side {
width: 100px;
float: left;
background: lightblue;
}
.main {
margin-left: 100px;
background: lightgreen;
}
<div class="wrapper">
<div class="top"></div>
<div class="side">side</div>
<div class="main">main</div>
</div>
<div class="wrapper">
<div class="top">
<div class="box">top</div>
</div>
<div class="side">side</div>
<div class="main">main</div>
</div>
.main
和.side
元素需要对齐。如您在上面的代码段中所见,除非.top
元素没有高度,否则一切都很好,在这种情况下,margin-top
规则会导致它们倾斜。以下所有“解决”问题,但每个都有缺点:
.wrapper
上添加边框(我也许可以使用透明边框,但是我真的不喜欢这样,因为它感觉像是脏东西,我宁愿不添加边框。出于某种原因,边框需要具有至少1px的宽度,否则将无法正常工作).wrapper {
clear: both;
background-color: #ccc;
border: 1px solid #000;
}
.wrapper+.wrapper {
margin-top: 50px;
}
.side,
.main {
height: 100px;
padding: 10px;
box-sizing: border-box;
margin-top: 20px;
}
.box {
padding: 10px;
}
.top {
background: yellow;
}
.side {
width: 100px;
float: left;
background: lightblue;
}
.main {
margin-left: 100px;
background: lightgreen;
}
<div class="wrapper">
<div class="top"></div>
<div class="side">side</div>
<div class="main">main</div>
</div>
overflow: hidden
添加到.wrapper
(这会隐藏某些元素的某些部分,并导致其他元素放置在错误的位置)overflow: auto
添加到.wrapper
(在某些情况下,这将添加滚动条)后两段在我的代码段中并不明显,但在实际应用中,它们会引起here所述的问题。
我非常怀疑这个问题与Why doesn't the height of a container element increase if it contains floated elements?和CSS container doesn't stretch to accommodate floats有关,但是我尝试了许多建议,但似乎都无法解决问题-也许是因为我的一个div浮动了,而另一个却没有。
由于这是大型应用程序的一部分,所以我不想大幅度地更改布局,只需具有一些css即可使.main
和.side
保持对齐,而与这些元素之前的内容无关。
您可以将主要元素设置为inline-block
,然后使用calc设置宽度。这不会对您的布局产生太大影响,您将获得正确的输出:
.main {
width:calc(100% - 100px);
display:inline-block;
background: lightgreen;
}
完整代码:
.wrapper {
background-color: #ccc;
clear: both;
}
.wrapper+.wrapper {
margin-top: 50px;
}
.side,
.main {
height: 100px;
padding: 10px;
box-sizing: border-box;
margin-top: 20px;
}
.box {
padding: 10px;
}
.top {
background: yellow;
}
.side {
width: 100px;
float: left;
background: lightblue;
}
.main {
width:calc(100% - 100px);
display:inline-block;
background: lightgreen;
}
<div class="wrapper">
<div class="top"></div>
<div class="side">side</div>
<div class="main">main</div>
</div>
<div class="wrapper">
<div class="top">
<div class="box">top</div>
</div>
<div class="side">side</div>
<div class="main">main</div>
</div>
另一个hacky的想法是确保您的顶部元素永远不会为空:
.top:empty {
font-size:0;
}
.top:empty::before {
content: "\80"; /* a random character */
}
完整代码
.wrapper {
background-color: #ccc;
clear: both;
}
.wrapper+.wrapper {
margin-top: 50px;
}
.side,
.main {
height: 100px;
padding: 10px;
box-sizing: border-box;
margin-top: 20px;
}
.box {
padding: 10px;
}
.top {
background: yellow;
}
.side {
width: 100px;
float: left;
background: lightblue;
}
.main {
margin-left: 100px;
background: lightgreen;
}
.top:empty {
font-size:0;
}
.top:empty::before {
content: "\80"; /* a random character */
}
<div class="wrapper">
<div class="top"></div>
<div class="side">side</div>
<div class="main">main</div>
</div>
<div class="wrapper">
<div class="top">
<div class="box">top</div>
</div>
<div class="side">side</div>
<div class="main">main</div>
</div>
您也可以考虑相同的技巧,但在主包装器上使用伪元素:
.wrapper::before {
content: "\80"; /* a random character */
display:block;
font-size:0;
}
完整代码
.wrapper {
background-color: #ccc;
clear: both;
}
.wrapper+.wrapper {
margin-top: 50px;
}
.side,
.main {
height: 100px;
padding: 10px;
box-sizing: border-box;
margin-top: 20px;
}
.box {
padding: 10px;
}
.top {
background: yellow;
}
.side {
width: 100px;
float: left;
background: lightblue;
}
.main {
margin-left: 100px;
background: lightgreen;
}
.wrapper::before {
content: "\80"; /* a random character */
display:block;
font-size:0;
}
<div class="wrapper">
<div class="top"></div>
<div class="side">side</div>
<div class="main">main</div>
</div>
<div class="wrapper">
<div class="top">
<div class="box">top</div>
</div>
<div class="side">side</div>
<div class="main">main</div>
</div>
您还可以使包装器inline-block
的宽度等于100%,并且其行为几乎与块元素相同:
.wrapper {
background-color: #ccc;
display:inline-block;
width:100%;
vertical-align:top; /* avoid some unwanted white space issue*/
}
.wrapper+.wrapper {
margin-top: 50px;
}
.side,
.main {
height: 100px;
padding: 10px;
box-sizing: border-box;
margin-top: 20px;
}
.box {
padding: 10px;
}
.top {
background: yellow;
}
.side {
width: 100px;
float: left;
background: lightblue;
}
.main {
margin-left: 100px;
background: lightgreen;
}
<div class="wrapper">
<div class="top"></div>
<div class="side">side</div>
<div class="main">main</div>
</div>
<div class="wrapper">
<div class="top">
<div class="box">top</div>
</div>
<div class="side">side</div>
<div class="main">main</div>
</div>
为进行说明,您面临着the specification中所述的边距合并问题:
两个边距在且仅在以下情况下邻接:
- 均属于参与相同块格式上下文的流内块级框
- 没有线框,没有间隙,没有填充,也没有边框将它们分隔开(请注意,为此目的,某些零高度的线框(请参见9.4.2)将被忽略。)
- 都属于垂直相邻的盒子边缘,即形成以下形式之一:
- 盒子的上边距和第一个流入子元素的上边距
您可以使用网格更加优雅地进行此操作。这是网格代码:
.wrapper {
display: grid;
grid-template-areas:
"top top"
"side main";
grid-template-columns: 100px 1fr;
}
.top{grid-area:top}
.side{grid-area:side}
.main{grid-area:main}
注意我还可以注释掉其他几个元素,并且仍然保留所需的布局。
.wrapper {
/*clear: both;*/
background-color: #ccc;
}
.wrapper+.wrapper {
margin-top: 50px;
}
.side,
.main {
height: 100px;
padding: 10px;
box-sizing: border-box;
/*margin-top: 20px;*/
}
.box {
padding: 10px;
}
.top {
background: yellow;
}
.side {
/*width: 100px;
float: left;*/
background: lightblue;
}
.main {
/*margin-left: 100px;*/
background: lightgreen;
}
.wrapper {
display: grid;
grid-template-areas:
"top top"
"side main";
grid-template-columns: 100px 1fr;
}
.top{grid-area:top}
.side{grid-area:side}
.main{grid-area:main}
<div class="wrapper">
<div class="top"></div>
<div class="side">side</div>
<div class="main">main</div>
</div>
<div class="wrapper">
<div class="top">
<div class="box">top</div>
</div>
<div class="side">side</div>
<div class="main">main</div>
</div>