最近面试的时候被问到如何设置一栏定宽,一栏自适应的两栏布局,回答得不好,因此又回去阅读了相关文档,现整理一下以作记录。
1. float方法
两栏布局
对于两栏布局,只需给左栏设置宽度,再设置float:left,右栏元素设置margin-left:为左边元素的宽度(右栏元素不可设置宽度,不然不能实现自适应),这样就完成了左栏固定,右栏自适应的两栏布局。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>float两栏布局</title>
<style>
header, footer { height: 100px;margin: 4px 0;background-color: #409BF7;clear: both; }
nav { background-color: #F4EA26;width: 200px;height: 100px;float: left; }
aside { background-color: #01F1A4;height: 250px;margin-left: 204px; }
</style>
</head>
<body>
<header>header</header>
<nav>nav1</nav>
<aside>aside1</aside>
<footer>footer</footer>
</body>
</html>
这里需要强调的是右栏不可设置宽度,不管用什么单位,都不会随着浏览器窗口自适应变化。如在此处给右栏设置width: 100%;
则右栏的宽度将是父元素的宽度,且由于设置了margin-left: 204px
,因此右栏会超出窗口204px。margin占据的空间并不算在width中。
另外需要注意的是,当浮动的那一栏的高度大于自适应的那一栏的高度时,页脚会填充在浮动元素(此处即左栏)四周,因此需要给footer 设置 clear: both;清除两侧的浮动,独占一行。
在浏览器窗口比较小的时候,左侧的浮动元素的宽度会大于右侧元素的宽度,但这样显示的效果很差,因此,我考虑利用媒体查询的特性来处理小屏幕的布局方式。
@media (max-width: 768px){
nav, aside { float: none;width: auto;margin: 0; }
}
这里只需要去除浮动并将各自的width设置为auto,两个元素都会恢复到原来的文档流,即成为占据父元素全部宽度的盒子。由于右侧的盒子之前制定了外边距,因此需要在此处指定外边距为0。
三栏布局
对于三栏布局也是相同的原理,左右的盒子设置好宽度之后,左边的盒子设置float:left; 右边设置float:right;中间设置左右margin即可,这样就完成了左右固定,中间自适应的三栏浮动布局。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>float三栏布局</title>
<style>
header, footer { height: 100px;margin: 4px 0;background-color: #409BF7;clear: both; }
#content { background-color: #E4E5E5;margin: 5px 0; }
#content .nav { background-color: #F4EA26;width: 200px;height: 200px;float: left; }
#content .aside { background-color: #ED4EF2;width: 200px;height: 250px;float: right; }
#content .article { background-color: #01F1A4;height: 450px;margin: 0 204px; }
</style>
</head>
<body>
<header>header</header>
<div id="content">
<div class="nav">nav</div>
<div class="aside">aside</div>
<div class="article">article</div>
</div>
<footer>footer</footer>
</body>
</html>
如果不给中间的元素设置左右margin值,那么该元素也会围绕在左右两个浮动的盒子四周。
注意,如果仔细观察的话,发现id为content的div元素上实际只包含着article元素,另外两个浮动元素已经脱离了文档流,不再受div#content的宽高限制。
同样,利用媒体查询来解决屏幕空间不足的问题。
@media (max-width: 768px){
#content .nav, #content .aside, #content .article { float: none;width: auto;margin: 0; }
}
@media (min-width: 768px) and (max-width: 979px) {
#content .aside { display: none; }
#content .article { margin-right: 0; }
}
这里另外制定了在屏幕宽度为 768px到979px之间的处理方式,将右侧的aside隐藏掉(右侧的侧边栏起辅助说明的作用,可以暂时不显示)。但但屏幕再小的话,就恢复成正常的位置,即从上到下排列,并布满整个父元素的宽度。
先暂时写这么多,下一篇再讲讲flex布局。欢迎大家留言指正。