Skip to content

CSS 深入

浮动

  • 浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样。

  • 请看下图,当把框 1 向右浮动时,它脱离文档流并且向右移动,直到它的右边缘碰到包含框的右边缘:

  • 再请看下图,当框 1 向左浮动时,它脱离文档流并且向左移动,直到它的左边缘碰到包含框的左边缘。因为它不再处于文档流中,所以它不占据空间,实际上覆盖住了框 2,使框 2 从视图中消失。

  • 如果把所有三个框都向左移动,那么框 1 向左浮动直到碰到包含框,另外两个框向左浮动直到碰到前一个浮动框。

如下图所示,如果包含框太窄,无法容纳水平排列的三个浮动元素,那么其它浮动块向下移动,直到有足够的空间。如果浮动元素的高度不同,那么当它们向下移动时可能被其它浮动元素“卡住”:

clear 属性:规定元素的哪一侧不允许其他浮动元素。它的取值如下:

取值描述
left在左侧不允许浮动元素。
right在右侧不允许浮动元素。
both在左右两侧均不允许浮动元素。
none默认值。允许浮动元素出现在两侧。
inherit规定应该从父元素继承 clear 属性的值。

小结

float

clear

定位

  • static, 静态定位(默认)。依据文档流定位

  • absolute,绝对定位。以父元素为基准,脱离文档流

  • relative,相对定位。以原位置为基准,不脱离文档流

  • fixed,固定定位。以浏览器窗口为基准,脱离文档流

  • sticky,粘性定位。以浏览器窗口为基准,不脱离文档流

弹性盒布局

页面布局方式

  1. 浮动

  2. 弹性盒布局

  3. 网格布局

  4. 定位布局

  5. 表格布局

弹性盒布局

一个元素的 display 属性值设置为 flex,那么这个元素中的子元素,就会遵循弹性布局的规则。

css
display:flex /*flex是flexible box的缩写*/

此时,这个元素就是一个弹性布局容器(弹性容器),它内部的子元素,将只按照弹性布局的规则来排列和对齐,以前的float、clear、块状与内联、vertical-align属性都不能用了。

重要概念:主轴与侧轴

弹性布局中的一个重要概念:主轴与侧轴:

弹性盒子中默认存在两根轴,一个是水平方向的主轴,一个是垂直方向的侧轴。

注意点:

  1. 主轴的开始位置叫做 main start、 结束位置叫做 main end;
  2. 侧轴的开始位置叫做 cross start、结束位置叫做 cross end;
  3. 侧轴永远垂直于主轴;

flex-direction 主轴方向

flex-direction 属性就是用来设置主轴方向的。

flex-wrap 自动换行

由于弹性布局中的子元素能自动伸缩,所以,当父容器此次小于子元素整体尺寸时,子元素不会自动换行,而是自动收缩。

那么,如果想要让子元素自动换行,可以使用flex-wrap:wrap

justify-content 主轴(水平)对齐

以主轴方向为例:子元素水平方向排列后,默认依次靠左排列。如果想让子元素居中、居右等,那么就可以设置 justify-content 样式。值有五种:

  1. flex-start(默认):左对齐。
  2. flex-end:右对齐。
  3. center:居中。
  4. space-between:两端对齐,子元素之间间距都相等。
  5. space-around:每个子元素两侧的间距相等。所以子元素之间间距比子元素到边框 间距大一倍。

align-items 侧轴(垂直)对齐

以主轴方向为例:子元素水平方向排列后,如果想让子元素垂直居中,那么就可以设置 align-items 样式。常用值有三种:

  1. flex-start(默认):上对齐。
  2. flex-end:下对齐。
  3. center:居中

align-content 多行对齐

再来看 align-content 样式:align-content 样式对单行没有效果,对多行有效果,而且是将多行作为一个整体附加效果的。

flex 缩放比例

如果想让每个子元素所占空间不一致,那么可以使用 flex 给子元素分配空间。 使用 flex 时要注意一下两点:

  1. flex 样式是设置在子元素上的。
  2. 如果设置了 flex,那就说明要给子元素按比例分配空间,因此 width 与 height 就失效了。

flex-grow 扩大比例

flex-grow属性定义有多余的空间时,弹性元素的扩大比例

flex-grow的值始终是一个数字,负数无效,0 为不扩大

flex-shrink 缩小比例

flex-shrink属性定义不足以放下所有弹性元素时,弹性元素的缩小比例

flex-shrink的值始终是一个数字,负数无效

flex-basis 弹性基准

flex-basis属性定义弹性元素的初始或默认尺寸

栅格布局

栅格布局,也叫网格布局。对比浮动和弹性盒,网格布局是更普适的布局系统。

基本的栅格术语

  • 栅格线(Grid line)

  • 栅格轨道(Grid track)

  • 栅格区域(Grid area)

  • 栅格单元(Grid cell)

快速入门

创建栅格容器

创建栅格的第一步是定义栅格容器。这与定位所用的容纳块弹性盒布局中的弹性容器的作用很像: 栅格容器器为其中的内容定义一个格格式化上下文

放置栅格线

案例一

html
<div class="grid">
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
</div>
css
.grid-cell {
    background: gray;
    margin: 5px;
}
.grid {
    height: 500px;
    display: grid;
    grid-template-columns: 200px 50% 100px;
}

案例二

html
<div class="grid">
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
</div>
css
.grid-cell {
    background: gray;
    margin: 5px;
}
.grid {
    display: grid;
    grid-template-columns: [start col-a] 200px [col-b] 50% [col-c] 100px [stop end last];
    grid-template-rows: [start masthead] 3em [content] minmax(3em, 100%) [footer] 2em [stop end];
}

案例三

html
<div class="grid">
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
</div>
css
.grid-cell {
    background: gray;
    margin: 5px;
}
.grid {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
}

案例四

html
<div class="grid">
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
    <div class="grid-cell"></div>
</div>
css
.grid-cell {
    background: gray;
    margin: 5px;
}
.grid {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
}

使用区域

本节将使用不同的栅格技术,实现双飞燕布局,样式统一,html代码统一

  • 统一样式

  • 统一 html

    html
    <div class="grid">
        <div class="grid-cell nav">nav</div>
        <div class="grid-cell aside-left">aside-left</div>
        <div class="grid-cell main">main</div>
        <div class="grid-cell aside-right">aside-right</div>
        <div class="grid-cell footer">footer</div>
    </div>

网格线区域

匿名网格线
css
.grid {
    display: grid;
    grid-template-columns: 200px 1fr 200px;
    grid-template-rows: 80px 1fr 80px;
}
.grid-cell {
    background: gray;
    margin: 5px;
}
.nav {
    grid-column-start: 1;
    grid-column-end: 4;
}
.footer {
    grid-column: 1/4;
}
命名网格线
css
.grid {
    display: grid;
    grid-template-columns: [start] 200px 1fr 200px [end
    grid-template-rows: 80px 1fr 80px;
}
.grid-cell {
    background: gray;
    margin: 5px;
}
.nav {
    grid-column-start: start;
    grid-column-end: end;
}
.footer {
    grid-column: start/end;
}

命名区域

css
.grid {
    display: grid;
    grid-template-areas:
            "nav    nav    nav"
            "left   main   right"
            "footer footer footer";
    grid-template-columns: 200px 1fr 200px;
    grid-template-rows: 80px 1fr 80px;
}
.grid-cell {
    background: gray;
    margin: 5px;
}
.nav {
    grid-area: nav;
}
.footer {
    grid-area: footer;
}

使用栏距

目前所见的栅格元素大都挤在一起,元素之间的间隔是通过margin设置的。除此之外,可通过设置栏距解决此问题。

以双飞燕布局为例,以下省略css代码及效果图

css
.grid {
    display: grid;
    grid-template-areas:
            "nav    nav    nav"
            "left   main   right"
            "footer footer footer";
    grid-template-columns: 200px 1fr 200px;
    grid-template-rows: 80px 1fr 80px;
    grid-row-gap: 40px;
    grid-column-gap: 40px;
}
.grid-cell {
    background: gray;
}
.nav {
    grid-area: nav;
}
.footer {
    grid-area: footer;
}

总结

常见布局练习

Standard

圣杯布局 - Holy Grail

双飞燕布局 - Double Swing

CSS属性参考

以下内容摘自《CSS 实战手册》第四版——附录 A