页面布局是前端面试中CSS部分经常考到的问题,本文列举几种简单页面布局的方法:
- 绝对定位 + margin
- float
- inline-block
- flex
- 附加:响应式布局
其中几种方法在CSS代码上有相似之处,也有局限或是需要特殊注意的地方,下文具体指出。
首先,我们需要实现的布局效果如下:
上下结构,Footer设置为fixed位于页面底部;导航与主体内容为左右结构。
0、准备工作
开始动手来写代码吧~
1)、同一个HTML结构
<div class="container">
<nav>
<ul>
<li>Home</li>
<li>Home</li>
<li>Home</li>
<li>Home</li>
</ul>
</nav><div class="column">
<section class="title">Title</section>
<section class="content">The Firefox Shapes Inspector helpfully shows the reference box in use when you inspect a shape. In the screenshot below I have created a circle, using shape-outside: circle(50%). The floated element has 20 pixels of padding, border and margin applied, and the Shapes Inspector highlights these reference boxes. When using a Basic Shape the reference box used by default is the margin-box. You can see in the screenshot that the shape is being defined with reference to that part of the Box Model.</section>
</div>
<footer>Footer</footer>
</div>
值得注意的是代码第9行的nav与div中间没有换行是由于inline-block方法的要求两个inline-block中间不要有空行/空格等,否则会造成宽度的改变。
2)、CSS代码共性部分
* {
margin: 0;
box-sizing: border-box;
}
html, body, .container, nav, .column {
height: 100%;
}
nav{
border: 1px solid blue;
}
.column, .title {
border: 1px solid pink;
}
footer {
position: fixed;
bottom: 0;
left: 0;
height: 70px;
background-color: white;
width: 100%;
border: 1px solid gray;
}
简要解释两点:
1.box-sizing:box-sizing设置为border-box使得元素的宽度包含border等,可以更清晰地看到元素间的位置关系(不设置box-sizing默认为content-box);
2.Footer:display设置为fixed是针对浏览器定位的,所以几种方法的Footer的样式设置为一样。
1、绝对定位 + margin
优势:该方法可以实现导航宽度的具体数值表示和百分比(%)两种表示方法,较灵活;
注意:父元素需要设置position: relative,原因是子元素position: absolute是根据上层position为relative的父级元素定位的
.container {
position: relative;
}
nav {
position: absolute;
left: 0px;
width: 150px;
}
section {
margin-left: 150px;
}
2、float
优势:与绝对定位相同,导航宽度可以用两种表示方法;
注意:绝对定位的元素脱离文档流,父级的块级/行内元素都会被它覆盖,而float的元素会覆盖父级块级元素,行内元素会环绕float元素,详细学习请参考张鑫旭的CSS float浮动的深入研究、详解及拓展
但是在页面布局中,两者右侧的元素都需要设置margin-left,实现较为简单。
nav {
float:left;
width: 150px;
}
section {
margin-left: 150px;
}
更好的办法是通过右侧元素形成BFC来清除浮动:
nav {
float:left;
width: 150px;
}
section {
overflow: hidden;
}
比较:纯流体布局需要大小不确定的margin或padding等值撑开合适间距,无法CSS组件化,例如上文的150px,其他类似布局可能是90px,无法大规模复用。
3、inline-block
劣势:以下两种方法存在两个问题,一个是宽度需要通过百分比设置,二是右侧的title和content两个section需要被一个父元素column设置样式实现布局。
注意:inline-block是CSS中一个很重要的概念,设置display: inline-block的元素既可以多个元素在同一行并列出现,又可以设置宽高,可以实现很多效果。
nav {
display: inline-block;
vertical-align: top;
width: 25%;
}
.column {
display: inline-block;
vertical-align: top;
width: 75%;
}
在这里讲一下HTML代码中提到的第9行的写法,如果分为两行:
</nav>
<div class="column">
则右侧会出现在导航下方:
原因是nav和column元素的宽度分别设置为25%和75%,在中间没有空格元素的情况下正好占据整个页面宽度,可以并列显示。这种写法对于块级元素没有问题,但是设置为inline-block元素后会识别html中两个元素的中间有没有字符,有的话一起显示在页面中,所以宽度超过100%,自然右侧的元素要下移了。
4、flex
优点:flex布局较为灵活,写法也较为简单,有一个有趣的学习网址:青蛙与flex
.container {
display: flex;
}
nav {
width: 150px;
}
.column {
flex: 1;
}
5、附加:响应式布局
操作:左右拖动浏览器窗口宽度,或者打开Chrome控制台,左右拖动控制台宽度,可以看到在宽度小于某一值时导航的li由多行结构变成一行中并列显示,这样同一页面在手机端显示时能保持良好的页面布局风格。
html, body, .container, nav, .column {
height: auto;
}
@media screen and (min-width:600px) {
nav {
float: left;
width: 25%;
}
section {
margin-left: 25%;
}
}
@media screen and (max-width:599px) {
nav li {
display: inline;
}
}
总结
简单页面布局的方法还有很多,不同的页面布局的适用方法不一,需要在实践中发掘。
本文是在实践学习CSS布局后总结的,有错误的地方望朋友们指出,感谢大家~