css布局之圣杯布局和双飞翼布局
文章目录
1. 圣杯布局
- 我对header和footer没有设置宽度
- 对left 和right 有设置固定宽度
- 对left,right 和 middle 有设置高度
- 对middle 宽度设置为100%
- 使用定位和margin值将left 和 right 元素进行布局
代码上附有步骤:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
*{padding:0;margin: 0;}
header{
background-color: darkcyan;
height: 50px;
}
.container{
background-color:cyan;
overflow: hidden;
/*4. 因为文字会被left元素挡住,所以使用padding将内容显示出来,同时需要知道left的宽度*/
padding-left:200px;
padding-right: 300px;
}
.middle,.left, .right{
float: left; /* 1. 三者都设置为float left,且三者都有高度*/
height: 500px;
/*5. 此时left也会跟着回来,所以使用相对定位*/
position: relative;
word-wrap: break-word;/*解决文字换行*/
}
.middle{
background-color: palevioletred;
width: 100%; /* 2. middle 宽度使用100% */
}
.left{
width: 200px;
background-color: tomato;
margin-left: -100%; /*3. 使用margin-left: -100% 将left元素拉回来*/
/*5.1 对left进行设置*/
left: -200px;
}
.right{
background-color: purple;
width: 300px;
/*5.2 将right盒子拉回*/
margin-left: -300px;
right: -300px;
}
footer{
background-color: yellowgreen;
height: 60px;
}
</style>
</head>
<body>
<header>
<h4>header</h4>
</header>
<div class="container">
<div class="middle">
<h4>middle</h4>
<p>mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm</p>
</div>
<div class="left">
<h4>left</h4>
<p>llllllllllllllllllllllllllllllllllll</p>
</div>
<div class="right">
<h4>right</h4>
<p>rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr</p>
</div>
</div>
<footer>
<h4>footer</h4>
<p>pppppppppppppppppp</p>
</footer>
</body>
</html>
2. 双飞翼布局
注意:从图片上看感觉布局一样
但还是要看代码哟,双飞翼布局没有使用position,而且container只包括了middle元素哦
- 设置了四个高度,分别是left right container,middle
- 对container设置了100%,使用margin 将left 和right 拉回来
- 对middle 进行设置,使用margin 为left和right 进行留白
- 底部使用clear:both 清除浮动
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>双飞翼布局</title>
<style>
* {
padding: 0;
margin: 0;
text-align: center;
word-wrap: break-word;
}
header {
background-color: darkcyan;
height: 50px;
}
.container {
width: 100%;/*2. width:100%*/
}
.container,.left,.right{
float: left;/*1.float*/
height: 500px;
}
.middle {
background-color: palevioletred;
margin-left: 300px;/*4.使用margin 将左右两边留白*/
margin-right: 200px;
height: 500px;
}
.left {
background-color: tomato;
width: 300px;
margin-left: -100%; /*3.1 将left拉回来*/
}
.right {
background-color: purple;
width: 200px;
margin-left: -200px; /*3.2 将right拉回来*/
}
footer {
background-color: yellowgreen;
height: 60px;
clear: both;/*5.使底部恢复 clear 属性规定元素的哪一侧不允许其他浮动元素。*/
}
</style>
</head>
<body>
<header>
<h4>header</h4>
</header>
<div class="container">
<div class="middle">
<h4>middle</h4>
<p>mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm</p>
</div>
</div>
<div class="left">
<h4>left</h4>
<p>llllllllllllllllllllllllllllllllllll</p>
</div>
<div class="right">
<h4>right</h4>
<p>rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr</p>
</div>
<footer>
<h4>footer</h4>
<p>pppppppppppppppppp</p>
</footer>
</body>
</html>
3. flex弹性盒布局
- 设置了left middle right 的高度
- 设置了left 和 right 的宽度
- 对left middle right 的父级元素container设置display:flex后就会自动这样
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>flex弹性布局</title>
<style>
* {
padding: 0;
margin: 0;
text-align: center;
}
header {
background-color: darkcyan;
height: 50px;
}
.container {
background-color: cyan;
display: flex;
}
.middle,
.left,
.right {
height: 500px;
word-wrap: break-word;
/*解决文字换行*/
}
.middle {
background-color: palevioletred;
}
.left {
width: 200px;
}
.right {
background-color: purple;
}
footer {
background-color: yellowgreen;
height: 60px;
}
</style>
</head>
<body>
<header>
<h4>header</h4>
</header>
<div class="container">
<div class="left">
<h4>left</h4>
<p>llllllllllllllllllllllllllllllllllll</p>
</div>
<div class="middle">
<h4>middle</h4>
<p>mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm</p>
</div>
<div class="right">
<h4>right</h4>
<p>rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr</p>
</div>
</div>
<footer>
<h4>footer</h4>
<p>pppppppppppppppppp</p>
</footer>
</body>
</html>
注意:
我发现虽然设置了left 和 right 的宽度 但是随着,middle 里内容的文字增加,right的宽度会变化
我对上面的代码进行了修改,如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>flex弹性布局</title>
<style>
* {
padding: 0;
margin: 0;
text-align: center;
word-wrap: break-word;
}
header {
background-color: darkcyan;
height: 50px;
}
.container {
background-color: cyan;
display: flex;/*1.设置flex属性*/
}
.middle,
.left,
.right {
height: 500px;
word-wrap: break-word;
/*解决文字换行*/
}
.middle {
background-color: palevioletred;
flex-grow: 1;
}
.left {
order: -1; /*2.设置布局,定义项目的排列顺序,越小越靠前,默认为0*/
flex-basis:200px;
}
.right {
background-color: purple;
flex-basis:300px;
}
footer {
background-color: yellowgreen;
height: 60px;
}
</style>
</head>
<body>
<header>
<h4>header</h4>
</header>
<div class="container">
<div class="middle">
<h4>middle</h4>
<p>mmmmmmmmmmmmmmmmmmmmmmmmm</p>
</div>
<div class="left">
<h4>left</h4>
<p>lllllllllllllllllllllllll</p>
</div>
<div class="right">
<h4>right</h4>
<p>rrrrrrrrrrrrrrrrrrrr</p>
</div>
</div>
<footer>
<h4>footer</h4>
<p>pppppppppppppppppp</p>
</footer>
</body>
</html>
加入了flex-grow:使其剩下的填满
flex-basis:设置规定值
得到了下面的布局
但是还是会随着每个内容的长度进行比例切换
比如当m增加时,会这样,对于left 和right里内容也是这样
我又重新查了一下flex的属性
display:flex;如果一个容器设置了这个属性,则这个盒子里的所有子元素都会变成伸缩项
- justify-content 设置子元素的排列方式 flex-start,flex-end,center
- space-between
- sapce-between 左右对齐父容器的开始和结束,中间平均分布,产生相同的间距
- sapce-around 将多余的空间平均分布在每一个子元素的两边(主轴上的)中间的减减压是左右两边的两倍
- flex-wrap 控制子元素是否换行 nwrap 不换行 wrap 换行
- flex-direction:元素排列方向,主轴方向默认为row(水平方向)
- row 水平方向–主轴 垂直方向 —侧轴 默认row-reverse
- column 垂直方向–主轴 水平方向为–侧轴 column-reverse从上到下
- flex-flow 由flex-wrap 和 flex-direction 组成
- flex-grow 扩展了子元素的宽度,设置当前元素应该占据剩余空间的比例值(默认为0)
- flex-shrink 定义收缩比例,通过设置的值来计算收缩空间(默认为1)
- 比例值计算:flex-grow/所有兄弟的flex-grow的和
- flex:用来设置当前伸缩子项占据剩余空间的比例值
- align-item 设置子元素(伸缩项)在侧轴上的对齐方式
- center 侧轴上居中对齐
- stretch 侧轴方向上进行拉伸,填充满整个侧轴方向(默认值)
- baseline 基线对齐
- align-self:设置单个元素在侧轴方向上的对齐方式
例
.box {
display: flex;
justify-content: center;
align-items: flex-end;
}
使用sapce-between
.box {
display: flex;
justify-content: space-between;
}
.box {
display: flex;
flex-direction: column;
justify-content: space-between;
}
align-self
.box {
display: flex;
}
.item:nth-child(2) {
align-self: center;
}
4. 使用flex做的圣杯布局(by 阮一峰)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.HolyGrail {
display: flex;
min-height: 100vh;
flex-direction: column;
}
header,
footer {
flex: 1;
background-color: darkcyan;
}
.HolyGrail-body {
display: flex;
flex: 1;
background-color: blueviolet;
}
.HolyGrail-content {
flex: 1;
background-color: red;
}
.HolyGrail-nav, .HolyGrail-ads {
/* 两个边栏的宽度设为12em */
flex: 0 0 12em;
background-color: yellow;
}
.HolyGrail-nav {
/* 导航放到最左边 */
order: -1;
}
</style>
</head>
<body class="HolyGrail">
<header>...</header>
<div class="HolyGrail-body">
<main class="HolyGrail-content">cccccccccccccccccccccccccccccccccccccccccccccccccccccccccc</main>
<nav class="HolyGrail-nav">lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll</nav>
<aside class="HolyGrail-ads">...</aside>
</div>
<footer>...</footer>
</body>
</html>
我在对body中加入了文字换行,但是结果布局的左边还是会被内容撑到变形