CSS布局

158 阅读5分钟

CSS布局一图流

c16620d4cf8e71306eebcad1d1d106a.png

float布局

步骤:

  1. 子元素加 float: left 和 width
  2. 父元素加上 .clearfix
    • 父元素加上class: class="clearfix"
    • .clearfix的写法
.clearfix::after {
  content:'';
  display:block;
  clear:both;
}

一些经验:

  • 最后一个子元素不设置width, 可以设置为max-width
  • IE6/7存在双倍margin bug,解决办法有两个
    • 针对IE6/7把margin减半;即:margin-left: 10px;下面再写一个:_margin-left: 5px;
    • 再加一个display: inline-block;
  • img 设置Max-width
  • 如果图片下面有多余的空白,就在图片上写上 vertical-align: top或者middle
  • 如果border干扰了布局,可以用outline: 1px solid red, outline不占用位置
  • 固定元素的块级元素居中的方法: 写上margin: 0 auto; 或者 margin-left: auto; margin-right: auto;(比前者好,因为没有影响上下的Margin)
  • 平均布局的关键点:负Margin

例子:

  • 用float布局做两栏布局(如顶部条)
  • 用float布局做三栏布局(如内容区)
  • 用float布局做四栏布局(如导航)
  • 用float布局做平均布局(如产品展示区)
<header class="clearfix">
    <div class="logo">
      <img src="https://static.nowcoder.com/fe/file/logo/1.png" alt="">
    </div>
    <ul class="clearfix nav">
      <li>首页</li>
      <li>课程</li>
      <li>优惠</li>
      <li>关于</li>
    </ul>
  </header>
  
  <div class="content clearfix">
    <aside>一行有六个字</aside>
    <main></main>
    <div class="ad"></div>
  </div>
  
  <div class="imageList clearfix">
    <div class="x">
      <div class="image"></div>
      <div class="image"></div>
      <div class="image"></div>
      <div class="image"></div>
      <div class="image"></div>
      <div class="image"></div>
      <div class="image"></div>
      <div class="image"></div>
    </div>
  </div>
*{margin:0;padding:0;box-sizing: border-box;}
ul,ol{
  list-style: none;
}
img{
  max-width: 100%;
}

.clearfix::after{
  content: '';
  display: block;
  clear: both;
}

.logo{
  background: grey;
  display: inline-block;
  float: left;
  margin-top: 8px;
  margin-left: 10px;
}
.logo>img{
  height: 26px;
  /*border: 1px solid red;*/
  vertical-align: top/*middle*/;/*如果在图片下面发现有多余的东西,写这个*/
}

.nav{
  float: left;
  margin-left: 20px;
}

ul > li{
  float: left;
  /*border: 1px solid red;*/
  padding: 4px 0.5em;
  line-height: 32px;
}

ul{
  /*border: 1px solid green;*/
  display: inline-block;
}
header{
  /*border: 1px solid blue;*/
  background: grey;
  color: white
}

.content{
  outline/*border*/: 1px solid red;/*有时border会影响宽度,可以改成outline*/
  width: 800px;
  /*margin: 0 auto;居中*/
  margin-left: auto;
  margin-right: auto;/*这两句也是居中,比上面的要好,因为上面会覆盖margin-top*/
}
.content>aside{
  width: 200px;
  /*border: 1px solid green;*/
  height: 300px;
  float: left;
  background: #999;
}
.content>main{
  /*border: 1px solid purple;*/
  height: 300px;
  width: 500px;
  float: left;
  background: #ccc;
}
.content>.ad{
  /*border: 1px solid black;*/
  height: 300px;
  width: 100px;
  float: left;
  background: #000;
}

.imageList{
  outline: 1px solid green;
  width: 800px;
  margin-left: auto;
  margin-right: auto;
  margin-top: 10px;
}
.imageList >.x> .image{
  width: 191px;
  height: 191px;
  background: #000;
  border: 1px solid blue;
  float: left; 
  margin-bottom: 10px;
  margin-right: 12px;
}
.imageList >.x{
  margin-right: -12px;
}

效果:

cf60f2a8138fb78e17e13b90cbaa24f.png float布局需要手动计算宽度,比较麻烦,所以可以用flex布局

flex布局

flex主要有两大块:container(容器)和items(项目)

5056887e95f3d51a86c8286fcc831d7.png

container属性

让一个元素变成flex容器

<div class="container"></div>
.container{
  display: flex;
}
  1. 改变主轴流动方向
flex-direction: row;/*默认,从左往右*/

86ad2558eca0970b58835401487a535.png

flex-direction: column;/*从上往下*/

f0ee4b8f9610dddadbe75fad83f28c5.png

flex-direction: row-reverse;/*从右往左*/

bb90d2a38b75ba43614627c2aabea4f.png

flex-direction: column-reverse;/*从下往上*/

6c4d393552c4876b288269a3a50bc90.png

  1. 改变折行
flex-wrap: nowrap/*默认,不折行*/ | wrap/*折行*/ | wrap-reverse/*折行,但是从下往上折,即最下面一行是开始*/

7ed2a81d21bca63b45584950dfa83f2.png

  1. 主轴对齐方式

默认主轴是横轴,除非你改变了flex-direction方向

justify-content: flex-start;/*默认,左对齐*/
justify-content: flex-end;/*右对齐*/
justify-content: center;/*居中*/
justify-content: space-between;/*空隙再每两个项目中间*/
justify-content: space-around;/*空隙围绕在项目周围*/
justify-content: space-evenly;/*所有空隙大小一样*/

690df3796553c525a9024e7b32bd201.png

  1. 次轴对齐方式

默认次轴是纵轴

align-items: flex-start;/*顶部对齐*/
align-items: flex-end;/*底部对齐*/
align-items: center;/*居中对齐*/
align-items: stretch;/*默认,将所有item拉长到与最长的item一样长*/
align-items: baseline;/*用的少*/

47034e76d5d428c8fccf35e0665bd23.png

  1. 多行内容

多行内容的分布,很少用到

align-content: flex-start | flex-end | center | space-between | space-around | stretch;

ba56fd62db1d7d0232dba0c1ee97543.png

item属性

  1. order

默认是0,可以给item排序

  • 按照order从小到大的顺序排
  • 负数、0、正数

107a282efbe01eb3ea70fc25678c5e6.png

  1. flex-grow

控制自己如何长胖,默认是0

  • 使用技巧:三栏布局时,两边的不设置,中间的设置flex-grow:1.

1afd3680b32f9b6bc812b0e5bcd73a1.png 3. flex-shrink

控制如何变瘦,一般写flex-shrink:0;(防止变瘦),默认是1

  1. flex-basis

控制基准宽度,默认auto,很少用

  1. align-self

定制align-items

35c87a731f02e6d24138f981adf16fa.png

重点

  • display: flex;
  • flex-direction: row / column;
  • flex-wrap: wrap;
  • justify-content: center / space-between;
  • align-items: center;

工作中基本只用以上这些

实践:用flex实现上面float: jsbin.com/nukoyegitu/…

经验:

  • 永远不要把width和height写死,除非特殊情况
  • 用min-width/max-width/min-height/max-height
  • flex可以基本满足所有需求
  • flex和margin-xxx: auto;配合有意外效果
  • 在写平均布局时,即使用Justify-content:space-between也无法满足要求:

1592296754051-73aa20e1-4926-420c-9818-2cb559ae403c.png 第一行是对的,但是第二行就错了,所以我们还是需要用到负margin

首先在Image上加上一个wrapper div

1592296961191-12b63cb1-a2df-478f-9110-2cad8e3f359d.png

然后再加上负Margin,负Margin的值就是每个Image的Margin-right的值

.imageList > .wrapper {
  display: flex;
  flex-wrap: wrap;
  margin-right: -12px;
}

grid布局

二维布局用Grid,一维布局用Flex

Grid也分container和items

grid属性过多,列举一些常用的

成为container

.container{
    display: grid | inline-grid;
}

行和列

6fd1e6b2dfae21f0df05d2b1edb6b13.png

<div class="container"> 
  <div class="a"></div>
  <div class="b"></div>
  <div class="c"></div>
  <div class="d"></div>
  <div class="e"></div>
</div>
* {margin:0;padding:0;box-sizing: border-box;}

.container {
  display: grid;
  grid-template-columns: 40px 50px auto 50px 40px;
  grid-template-rows: 60px 400px 200px;
  border: 1px solid red;
}

.a, .b, .c {
  border: 1px solid black;
}

.a {
  /*从row的1号线到row的2号线*/
  grid-row-start: 1;
  grid-row-end:2;
  /*从column的1号线到6号线*/
  grid-column-start:1;
  grid-column-end:6;
}

.b {
  grid-column-start: 1;
  grid-column-end: 3;
}

.c {
  grid-row-start: 2;
  grid-row-end: 3;
  grid-column-start: 3;
  grid-column-end: 5;
}

b55f90b35f2cdcbfa0f30b32f5f7fb9.png 也可以给每条线取名字

fr - free space 的用法

用fr来实现平均布局,就不再需要写负Margin了,而且非常方便

<div class="container">
  <div class="image"></div>
  <div class="image"></div>
  <div class="image"></div>
  <div class="image"></div>
  <div class="image"></div>
  <div class="image"></div>
  <div class="image"></div>
  <div class="image"></div>
</div>
* {margin:0;padding:0;box-sizing: border-box;}

.container {
  display:grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  border: 1px solid red;
  min-height: 400px;
  width: 800px;
  grid-gap: 12px;
}

.image {
  width: 191px;
  height: 191px;
  border: 1px solid green;
}

6a7f81bafef1a4dfc2191a1c8f7e91b.png

分区 grid-template-areas 和 空隙 grid-gap

<div class="container">
  <header>header</header>
  <aside>aside</aside>
  <main>main</main>
  <div class="ad">ad</div>
  <footer>footer</footer>
</div>
* {margin:0;padding:0;box-sizing: border-box;}

.container{
  min-height: 100vh;
  display: grid;
  grid-template-rows: 60px auto 60px;
  grid-template-columns: 100px auto 100px;
  grid-gap: 10px;
  grid-template-areas:
    "header header header"
    "aside main ad"
    "footer footer footer"
}
.container>*{
  border: 1px solid red;
}
.container>header{
  grid-area: header;
}
.container>aside{
  grid-area: aside;
}
.container>main{
  grid-area: main;
}
.container>.ad{
  grid-area: ad;
}
.container>footer{
  grid-area: footer;
}

6ce45e207f490650fe7a60e608f65c0.png

实践:jsbin.com/podoviduca/…

1592386399540-98a24c5b-e892-4258-b81b-4e1cc90f2a6d.png

grid尤其适合用来做不规则布局