面试题目:假设高度一定,请写出三栏布局,左右宽度300px,中间宽度自适应,中间栏要放在文档流前面优先渲染;
先说一下我的想法,三栏布局,三栏就是三个栏目板块放在一行,最开始我看见的是左右定宽,中间自适应,最先想到的是是外面放一个大div,让他们直接inline-block,一个左浮动一个右浮动,中间100%宽度,这显然是一个贼蠢又错误的想法,这道题核心是中间栏放在文档流前面优先渲染, 所以遵循浏览器自上而下 加载代码的原则,应该把这个div盒子放在最前面,所以我的想法是先创建一个大div盒子叫min100%放在最前面,left和right左右俩个盒子放在后面,然后利用margin-left的负值将left和right移动上一行也就是这个min盒子左右边,然后在这个min的div盒子里面放一个小盒子不设宽度,叫他自适应,同时也优先渲染,虽然说的有点乱,但应该就是双飞翼布局
一、双飞翼布局
双飞翼布局据说是玉伯大大提出来的,始于淘宝UED,双飞翼布局用来诠释三栏布局就是把三栏布局比作一个大鸟,中间自适应那栏是鸟的身体,left和right那俩个栏是他们的翅膀;
其中的margin-left负值我也不太明白,最开始他们都是float:left,所以最开始margin-left是0;负的margin-left会让元素沿文档流向左移动,如果负的值较大,比如说-100%,相当于直接向左移动出100%一整行的距离,因为left左边是父元素边框,所以直接跳到上一行左移,移动100%距离相当于直接从上一行的末尾开始左移,移到上一行的开头,right在上一行末尾是因为负值300px,刚好是right的宽度,所以他从上一行的末尾开始向左移移动了300px;如果加大right的负值,他会继续向左移
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>双飞翼布局</title>
<style type="text/css">
.left, .main, .right /*并集标签选择器将共同属性写在一起,减少代码冗余*/{
float: left;
min-height: 130px;
text-align: center;
}
.left {
margin-left:-100%;/*设置margin-left-100%是为了让left向左移动一整行的位置*/
background:orange ;
width: 300px;
}
.right {
margin-left: -300px;/*让right移动到上一行的末尾*/
background-color: olive;
width: 300px;
}
.main {
background-color: #ccc;
width: 100%;/*宽度占一整行*/
}
.content{
margin: 0 300px 0 300px;/*排除掉俩边left和right盒子的300px宽度,宽度自适应*/
}
</style>
</head>
<body>
<div class="container">
<div class="main">
<div class="content">main</div>
</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
</body>
</html>

二、圣杯布局
圣杯布局是Kevin Cornell在2006年提出的一个布局模型概念,相当于中间那栏是圣杯主体,left和right俩栏是圣杯耳朵;用到定位的属性关系加上margin-left负值的特性来完成。
和双飞翼布局异同:他们解决办法一半是相同的,都是使用float浮动,利用了margin-left负值的特性,让他们移动到上一行,使三栏并排,形成三栏布局;不同的是双飞翼布局改变了html结构,多用了一个div,少用4个css属性,减少了相对定位的麻烦,比圣杯布局思路简单一点;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>圣杯布局</title>
<style type="text/css">
body{
min-width: 900px;
}
.container {
padding: 0 300px 0 300px;/*用padding300px给left和right俩个盒子留出位置*/
}
.left,
.main,
.right {
position: relative;/*利用相对定位*/
min-height: 130px;
float: left;
}
.left {
left: -300px;/*利用相对定位将这个盒子左移到之前container的padding值留白的地方,right同此理,使中间自适应;*/
margin-left: -100%;/*利用margin-left -100%*让其移动到main这一行上面*/
background: orange;
width: 300px;
}
.right {
right: -300px;
margin-left: -300px;
background-color: olive;
width: 300px;
}
.main {
background-color: #ccc;
width: 100%;
}
</style>
</head>
<body>
<div class="container">
<div class="main">main</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
</body>
</html>
之前圣杯布局没加 body{min-width: 900px; }之前会出现下图情况,就是缩小窗口宽度到一定宽度,布局会乱,可能是相对定位的影响;加上body{min-width: 900px; }之后就恢复正常了,如果left是200px,right是300px的话就是min-width:700px
三、flex弹性盒子布局
Flex是Flexible Box的缩写,俗称“弹性盒子布局”,任何一个容易都可以用flex布局
下面代码主要应用flex的order属性设置排列顺序,用flex-basis设置left和right的固定宽度
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>flex 三栏式布局</title>
<style>
*{
margin: 0;
padding: 0;
}
.container{
display: flex;
display: -webkit-flex;/*加这些前缀是为了解决css3兼容浏览器的问题,用这些浏览器内核加载*/
display: -moz-flex;
flex-direction: row;/*规定灵活项目的方向,row默认值,默认水平显示*/
box-sizing: border-box;/*计算的时候去掉border边框*/
border: 1px solid red;
margin: 0 auto;
min-height:150px;
}
.min{
flex: 1;/*让所有弹性盒子的子元素都有相同的长度*/
background-color:#ccc ;
}
.left{
flex-basis: 300px;/*用于设置弹性盒子伸缩基准值,也就是宽度*/
order: -1;/*设定弹性盒子的子元素的顺序,-1就是为了让left排在min左边*/
background-color: orange;
}
.right{
flex-basis: 300px;
background-color:orangered;
}
</style>
</head>
<body>
<div class="container">
<div class="min">中间布局</div>
<div class="left">左侧布局</div>
<div class="right">右侧布局</div>
</div>
</body>
</html>
四、绝对定位布局
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>绝对定位布局</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.container{
position: relative;
width: 100%;
}
.main, .right,.left{
top: 0;
height: 150px;
text-align: center;
}
.main{
top:0;
left:300px;
right:300px;
position: absolute;
background-color: blue;
}
.right{
position: absolute;
width: 300px;
right: 0;
background-color: red;
}
.left{
position: absolute;
width: 300px;
background-color: green;
left: 0;
}
</style>
</head>
<body>
<div class="container">
<div class="main">main</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
</body>
</html>
绝对定位使元素的位置与文档流无关,因此不占据空间,所以之前我自己想设置margin左右边距值,使min左右空出left和right盒子的宽度会出现以下问题,margin值的设立使布局出现偏差,以及混乱;
.main{
top:0;
margin:0 300px;
background-color: blue;
}
.main{
top:0;
margin:0 300px;
background-color: blue;
position: absolute;
}
所以应该用position定位的left和right值来留出左右盒子宽度让main自适应是最正确了
.main{
top:0;
left:300px;
right:300px;
position: absolute;
background-color: blue;
}
五、 table布局
这个布局高度由内容决定,再多的三栏布局不想研究了,前面几个布局研究了一天,累了,就这几个够我用了
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>绝对定位布局</title>
<style media="screen">
.container{
display: table;
width:100%;
}
.container>div{
display: table-cell;
}
.left{
width: 100px;
background:orange;
}
.main{
background: #ccc;
}
.right{
width: 200px;
background: orangered;
}
</style>
</head>
<body>
<div class="container">
<div class="left">left</div>
<div class="main">center</div>
<div class="right">right</div>
</div>
</body>
</html>