CSS布局

124 阅读6分钟

布局的分类

  1. 固定宽度布局,一般宽度是960、1000、1024px

  2. 不固定宽度布局,主要靠文档流的原理来布局

    文档流本来就是自适应的,不需要加额外的样式

  3. 响应式布局:PC上固定宽度,手机上不固定宽度,也就是一种混合布局。

布局的思路

  1. 从大到小(适合老手) 先定下大局,然后完善每个部分的小布局。

  2. 从小到大(适合新手) 先完成小布局,然后组合成大布局。

布局如何确定属性?

float布局

  • 步骤:
  1. 在子元素上加float:left/rightwidth
  2. 在父元素上加.clearfix

记得在CSS中加clearfix:

.clearfix:after{

  content:'';
  
  display:block;
  
  clear:both;
  
}

用float布局做一个顶部条代码示例:

HTML:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<header class="clearfix">           //这里的header为父元素
  <div class="logo">XDML</div>      //子元素
  <nav>导航</nav>                   //子元素
  <div class="user">头像</div>      //子元素
</header>
</body>
</html>

CSS:

*{margin:0;padding:0;box-sizing:border-box;}

.clearfix:after{
  content:'';
  display:block;
  clear:both;
}
.logo{
  border:2px solid red;
  height: 40px;
  width: 100px;
  float:left;
  margin-top:5px;
}
nav{
  border:2px solid blue;
  height: 50px;
  float:left;
  width: 200px;
}
.user{
  float:left;
  border:2px solid green;
  height:30px;
  max-width:100px;
}
header{
  border:2px solid black;
}

效果演示:

  • 经验:
  1. 有经验者会留一些空间或者让最后一个元素不设width。

  2. 不需要做响应式,因为手机上没有IE,而这个布局时专门为IE准备的。

  3. IE6/7存在双倍margin的BUG,原因如下: 例:

.logo{
  border:2px solid red;
  height: 40px;
  width: 100px;
  float:left;
  margin-top:5px;
  margin-left:10px;      //在这里给margin加上10px的间隙,在IE6/7上打开就会变成双倍间隙20px.
}

解决办法有两个:

  1. 是将错就错,保留原先的代码,针对IE6/7把margin减半,再在前面加一个符号,如下划线 _ 或 * 等 示例:
margin-left:10px;
_margin-left:5px;
  1. 神来一笔,再加一个display:inline-block;

实践

  • 用float做两栏布局(如顶部条)

  • 用float做三栏布局(如内容区)

  • 用float做四栏布局(如导航)

  • 用float做平均布局(如产品展示区) 代码: js.jirengu.com/kulas/8/edi…

  • 经验

  1. 加上头(header)尾(footer)即可满足所有PC页面需求。
  2. float要程序员自己机算宽度,不灵活。
  3. float用来应付IE足矣。
  • vertical-align: top/middle;
    快捷输入:va:t/m + tab

作用:去掉图片下方多余的背景色。

  • border有时会对宽度造成干扰,可以改成outline

例: outline:1px solid red;

边框会无效。

  • 如果对象是块级元素(block),并且宽度是固定的话,用
margin-left:auto;
margin-right:auto;

会让图形居中

  • margin-bottom 用于设置元素底部的外边距,允许设置负值。

例如: margin-bottom:20px;

flex布局

来自CSS Tricks

container(容器)

让一个元素变成flex容器

.container{
   display:flex;  /* 或者inline-flex */
}

flex-container的样式

  • 改变items(主轴)流动方向
.container{
flex-direction: row / row-reverse / column / column-reverse
}

流动方向即主轴方向

  • 改变折行
.container{
flex-wrap: nowrap / wrap / wrap-reverse
}

默认是nowrap不折行

  • 主轴对齐方式 默认主轴是横轴,除非改变了flex-direction方向
.content{
justify-content:flex-start / flex-end / center / space-between
}

  • 次轴对齐 默认次轴为纵轴
.container{
align-items:stretch / flex-start / flex-end / center / baseline
}

  • 多行内容
.container{
align-content:flex-start / flex-end / center / stretch / space-between / space-around
}

flex items属性

1. order样式

例:

HTML:
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
</div>
</body>
</html>

以下属性,html均相同

CSS:
.container{
  display: flex;
  border:1px solid red;
  flex-direction: row;
  flex-wrap: wrap;
}
.item{
  border:1px solid green;
  width: 50px;
  height: 50px;
}
.item:first-child{
  order:5
}
.item:nth-child(2){
  order:4
}
.item:nth-child(3){
  order:3
}
.item:nth-child(4){
  order:-3
}
.item:last-child(3){    //最后一个孩子可以这么写
  order:1
}

效果展示:

竖方向也一样:

flex-direction: column;

  • 注意
  1. order可以是负数,最后一个可以用.item:last-child,同理第一个可以用first

  2. : 前后没有空格

2. flex-grow

在item上面加flex-grow,用于控制“变胖”

例:

.item:first-child{
  flex-grow:1;
}
.item:nth-child(2){
  flex-grow:2;           //2表示占了双倍的空间
}
.item:nth-child(3){
  flex-grow:1;
}

同理,flex-grow: 1; 写在每个item上,则三个占的空间一样大。

假如,给第二个孩子一个flex-grow: 1; 其余全不写,那么随着页面的缩放,多余的空间会全部给到第二个孩子(nth-child(2))

flex-grow: 0的话就是默认效果,宽度由内部字数的数量决定,写flex-grow: 0等于不写

3. flex-shrink

用于控制“变瘦”,一般写 flex-shrink: 0 防止变窄。 默认是1

.item{
  border:1px solid green;
  width: 150px;
  height: 50px;
}
.item:first-child{
  flex-grow:1;
    flex-shrink: 1;
}
.item:nth-child(2){
   flex-grow:1;
  flex-shrink: 0;
}
.item:nth-child(3){
  flex-grow:1;
    flex-shrink: 1;
}

flex-shrink数值越大,收缩窗口时,“瘦”的越快。

0的话不变

4. flex-basis

控制基准宽度,默认值是auto

5. align-self定制align-items

例:

CSS:

.item{
  border:1px solid green;
  width: 50px;
  height: 50px;
}
.item:first-child{
  height: 150px
}
.item:nth-child(2){
  height: 100px
}
.item:nth-child(3){ 
  height: 50px;
  align-self: flex-end;    //在这里加上align-self属性可以单独给第三个孩子添加样式
}

效果演示:

实践

  • 用flex做两栏布局(如顶部条)
  • 用flext做三栏布局(如内容区)
  • 用flex做四栏布局(如导航)
  • 用flex做平均布局(如产品展示区) 代码: js.jirengu.com/nuvib/1/edi…
  • 经验
  1. 永远不要把width和height写死,除非特殊说明。(最忌讳写死宽度,比如width: 100px;)
  2. 最好用min-width/max-width/min-height/max-height代替固定宽度。
  3. flex可以基本满足所有需求。
  4. flex和margin-xxx: auto配合有意外效果。

grid布局

功能最强大的布局方案;

二维布局用grid,一维布局用flex

grid也分container和items

  • 设置container
.container{
display: grid/inline-grid;
}
  • 行和列
.container{
grid-template-columns:40px 50px auto 50px 40px;
grid-template-rows:25% 100px auto;
}

  • item可以设置范围 代码示例:
HTML:
<body>
<div class="container">
  <div class="a"></div>
  <div class="b"></div>
  <div class="c"></div>
  <div class="d"></div>
  <div class="e"></div>
</div>
</body>

CSS:
*{margin:0;padding:0;box-sizing:border-box;}

.container{
  display:grid;
  border:1px solid red;
  min-height:200px;
}
.container>div{
  border:1px solid black;
}
.a{
  grid-row-start:1;
  grid-row-end:2;
  grid-column-start:1;
  grid-column-end:6;
}

*{margin:0;padding:0;box-sizing:border-box;}
.container{
  display:grid;
  grid-template-columns: 1fr 1fr 1fr;    //竖方向上三列
  grid-template-rows: 1fr 50px 1fr 1fr;   //横方向上四行
  border:1px solid red;
  min-height: 400px;
}
.container > div{
  border:1px solid black;
}
.e{
  grid-column-start: 2;
  grid-column-end: 4;
}

效果展示:

  • 空隙gap

gap属性用于设置网格行与列之间的间隙,该属性是row-gap和column-gap的简写形式。

例如:grid-gap: 20px; 用于设置20px间隙,横竖方向上均为20px。* 表示所有元素

横竖方向上均可设置不同的间隙,例:

*{margin:0;padding:0;box-sizing:border-box;}
 
.container{
  display:grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 1fr 50px 1fr 1fr;
  grid-column-gap: 10px;               //竖方向上设置间隙10px
  grid-row-gap: 20px;                  //横方向上设置间隙20px
  border:1px solid red;
  min-height: 400px;
}
.container > div{
  border:1px solid black;
}

效果演示:

HTML:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<div class="container">
  <header>header</header>
  <aside>aside</aside>
  <main>主要内容</main>
  <div class="ad">ad</div>
  <footer>footer</footer>
</div>
  </body>
</html>

CSS:

*{margin:0;padding:0;box-sizing:border-box;}

.container{
  display:grid;
  min-height: 100vh;
  grid-template-columns: 60px auto 60px;
  grid-template-rows: 100px auto 100px;
  grid-template-areas:                   //前面铺垫,以下重点布局
    "header header header"
    "aside main ad"                      //注意:.表示empty空白,如果想让布局中空出一部分,可以用.
    "footer footer footer";
    grid-column-gap: 5px;
}
.container > * {
  border:1px solid red;
}
.container > header{
  grid-area: header;
}
.container > main{
  grid-area: main;
}
.container > aside{
  grid-area: aside;
}
.container > .ad{
  grid-area: ad;
}
.container > footer{
  grid-area: footer;
}

效果演示:

grid尤其适合不规则布局