CSS布局

203 阅读5分钟

1.布局是什么

布局是通过将页面分成一块一块,按左中右,上中下等排列。

2.布局分类

  • 固定宽度布局,一般宽度为960/1000/1024px。
  • 不固定宽度布局,主要靠文档流的原理布局。
  • 响应式布局,PC上固定宽度,手机上不固定宽度。

3.布局套路

4.Float布局

步骤:

  • 1.子元素上加上float:left和width
  • 2.在父元素上加.clearfix
举例说明:
<header>
    <div class="class1">页面元素1</div>
    <div class="class2">页面元素2</div>
</header>

对于这两个元素,默认是分别占一行,在加上各自的class样式后:

header {
    border: 1px solid green;
}

.class1 {
    border: 1px solid red;
    height: 40px;
    width: 100px;
    float: left;
}

.class2 {
    border: 1px solid green;
    height: 40px;
    width: 100px;
    float: left;
}

页面显示为如下三部分:

注意:由于header内的两个div通过float脱离了文档流,故header的高度为0,但是在给header 增加如下样式后:

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

可以看到header重新把两个div包裹进去了。

4.1 负margin技巧

\quad 对于一些特殊情况,可以采用负margin的方法解决问题,比如:

<div class="clearfix imgList">
    <div class="imgClass"></div>
    <div class="imgClass"></div>
    <div class="imgClass"></div>
    <div class="imgClass"></div>
</div>

css代码:

.imgList{
    width: 800px;
    outline: 1px solid red;
    margin-left: auto;
    margin-right: auto;
}

.imgList .imgClass {
    width: 191px;
    height: 200px;
    background: black;
    float: left;
    margin-top: 10px;
    margin-bottom: 10px;
    margin-right: 12px;
}

在宽度为800px的div中放四个宽度为191px,间距为12px的方块,按道理应该是正好能放下的,但是实际情况确实这样的: 如果不减少margin的值的话,这时候就可以用到负margin来解决了。在中间加上一层div:

<div class="imgList">
    <div class="clearfix x">
        <div class="imgClass"></div>
        <div class="imgClass"></div>
        <div class="imgClass"></div>
        <div class="imgClass"></div>
    </div>
</div>

对x设置负margin:

.x {
    margin-right: -12px;
}

可以看到,四个方块成功放进width:800px的div中。

其他经验:

  • 1.多个块级元素并列,最后一个不设置width。
  • 2.不需要做响应式布局,因为float布局是专门针对ie系统的。
  • 3.border调试法的时候,由于border会占两像素,所以可以使用outline添加外边框。

5.Flex布局

Flex布局分为containeritems :

5.1 container样式:
  • 使用display:flex 或者display:inline-flex将布局布置为flex布局,二者区别与前面相同。
  • 使用flex-direction修改items主轴的流动方向:
  • 使用flex-wrap设置是否要换行:

  • 使用justify-content设置主轴对齐方式:
  • 使用align-items设置次轴(默认是纵轴)对齐方式:

  • 使用align-content设置多行内容的对齐方式:

5.2 items样式
  • 使用order改变排列顺序,示例:
<div class="flexParent">
    <div class="flexClass">1</div>
    <div class="flexClass">2</div>
    <div class="flexClass">3</div>
    <div class="flexClass">4</div>
    <div class="flexClass">5</div>
</div>

css:

.flexParent{
    display: flex;
}

.flexClass{
    border: 1px solid black;
    width: 100px;
    height: 100px;
    background: hsl(0, 80%, 50%);
}

.flexClass:first-child{
    order: 5;
}
.flexClass:nth-child(2){
    order: 4;
}
.flexClass:nth-child(3){
    order: 3;
}
.flexClass:nth-child(4){
    order: 2;
}
.flexClass:last-child{
    order: 1;
}

修改顺序后:

  • 使用flex-grow用于分配多余的空间
.flexParent{
    display: flex;
    width: 500px;
    border: 1px solid black;
}

.flexClass{
    border: 1px solid black;
    background: hsl(0, 80%, 50%);
    flex-grow: 1;
}

在给flexParent加上宽度并给flexClass加上flex-grow后,那么多余的空间会平均分配到各个部分: 如果设置另外一个孩子的flex-grow:

.flexClass:nth-child(2){
    order: 4;
    flex-grow: 2;
}

那么该部分所占的比例也会增加。

  • 使用flex-shirk设置空间不足时,各部分收缩的比例,与flex-grow同理。flex-shrink默认是1,设置为0时,可以防止该部分缩小。

  • 使用flex-basis设置基准宽度,默认是auto,与width同理。前面三者可以简写为:flex:flex-grow flex-shirk flex-basis用空格分开,比如:flex: 1 0 100px

  • 使用align-self可以使得某个item定制align-items,举例: 5个方框,默认是flex-start对齐的,当修改第一个孩子的align-self对齐方式时:

.flexClass:first-child{
    order: 5;
    height: 100px;
    flex-shrink: 100;
    align-self: flex-end;
}

样式改为:

最后,可在 flexboxfroggy.com/ 在小游戏中练习flex布局。

6.经验

  • 永远不要将widthheight写死,可以使用min(max)-width | min(max)-height做成响应式的,或者使用% | vw(屏幕宽度的百分比) | vh(屏幕高度的百分比)
  • flex布局基本可以完成所有的需求。

7.Grid布局-二维布局

\quad Grid布局和flex布局一样,也分为containeritems。通过在父元素上增加:`

{
   display:grid | inline-grid;
}
7.1 grid-template-columns | rows设置Grid布局的行和列

CSS:

.gridParent {
    display: grid;
    border: 1px solid red;
    grid-template-columns: 40px 50px auto 50px 40px;
    grid-template-rows: 25% 100px auto;
}

根据线的编号,可以设置item的范围:

<div class="gridParent">
    <div class="gridClass a">1</div>
    <div class="gridClass b">2</div>
    <div class="gridClass c">3</div>
    <div class="gridClass d">4</div>
    <div class="gridClass e">5</div>
</div>
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

.gridParent {
    display: grid;
    background: hsl(0,80%,50%);
    grid-template-columns: 50px 50px auto 50px 50px;
    grid-template-rows: 100px 100px auto;
}

.a {
    grid-column-start: 1;
    grid-column-end: 3;
    grid-row-start: 1;
    grid-row-end: 3;
    background: hsl(30,80%,50%);
}

.b {
    background: hsl(60,80%,50%);
}

.c {
    background: hsl(90,80%,50%);
}

.d {
    background: hsl(170,80%,50%);
}

.e {
    background: hsl(200,80%,50%);
}

结果: 可以看到,第一个方块跨了两行两列。

  • 使用grid-column: start-line/endline简写grid-column-start+grid-column-end,grid-row同理。
  • 使用grid-column-end | start: span 2;设置跨越的行数,grid-row同理。
  • 使用grid-area简写grid-column+grid-column,grid-area属性接受4个由'/'分开的值:grid-row-start, grid-column-start, grid-row-end, 最后是grid-column-end

于此同时,还可以使用fr分区:

.gridParent1 {
    display: grid;
    grid-template-columns: 1fr 2fr auto 1fr 1fr;
    grid-template-rows: 1fr 1fr auto;
}

可以同样实现类似前面的效果。

7.2 grid-template-areas分区(最牛逼的写法)

在定义好如下布局后:

<div class="container">
    <header></header>
    <main></main>
    <aside></aside>
    <div class="content"></div>
    <footer></footer>
</div>

在CSS中使用grid-template-areas实现分区:

.container > * {
    border: 1px solid red;
}

.container {
    display: grid;
    min-height: 100vh;
    grid-template-rows: 60px auto 60px;
    grid-template-columns: 100px auto 100px;
    grid-template-areas:
            "header header header"
            "aside main content"
            "footer footer footer"
}

.container > header {
    grid-area: header;
}

.container > main {
    grid-area: main;
}

.container > aside {
    grid-area: aside;
}

.container > .content {
    grid-area: content;
}
.container > footer {
    grid-area: footer;
}

可以看到,很简单的就实现了页面的基本布局,而且非常直观。

7.3 设置间隙
  • grid-gap :设置列与列,行与行之间的间隙
  • grid-column-gap:设置横向间距(列与列)之间
  • grid-row-gap:设置纵向间距(行与行)之间
7.4 grid布局也可以通过order改变排序顺序

Grid布局小游戏: cssgridgarden.com/#zh-cn

参考文档