CSS2: 定位和布局

458 阅读9分钟

布局的出发点是:如何在一行显示多个div元素。

传统布局共有三种模型:

  • 文档/标准流布局:默认的网页布局模式,块级元素独占一行,行内元素共享一行。
  • 浮动布局:使用float属性,使元素脱离文档流,浮动起来,div+float使用较多
  • 定位布局:通过position属性来定位网页元素的位置。

脱离文档流的方式有 float浮动position:fixedposition:absolute

一、float 浮动布局

1. 浮动

浮动指的是让某个 div 元素脱离文档,浮在文档上面。浮动元素会向左或向右移动,直到它的外边缘碰到包含框或另一个浮动元素为止。

注意:假如div元素A是浮动的,如果A的上一个元素也是浮动元素,那么A元素会跟随在该元素的后边如果一行放不下,A会挤到下一行);如果A的上一个元素是文档流中的元素,那么A的相对垂直位置不改变(A的顶部总是和上一个元素的底部对齐)。

靠近页面边缘的一端是前,远离页面边缘的一端是后。

float: left | right | none (没有使用浮动) | inherit (继承浮动,不支持ie) 
  • 对于块级元素:浮动元素会脱离文档流排列。
  • 对于行内元素:会围绕着浮动元素,例如文字环绕。

2. 清除浮动 clear

浮动之后元素可以理解成横线排列,而清除浮动可以理解为打破横向排列。

clear: none | left | right | both
none:默认值,两边都可以有浮动元素。
left:不允许左边有浮动元素。
right:不允许右边有浮动元素。
both:不允许有浮动对象。

注意:以上的 clear 规则只能影响使用清除的元素本身,不能影响其他元素。

3. BFC

BFC 就是一个完全独立的空间,它规定了内部的渲染区域(块级元素)如何布局,并且不会影响外部区域。

  1. 如何触发BFC(满足其一即可)

    • 根元素<html>
    • 浮动:float 设置除none外的值。
    • 定位:position 设置absolutefixed
    • display:inline-blockflex等。
    • overflow 设置除visible外的值。
    • ......
  2. BFC 的规则

    • BFC 内部的盒子会垂直排列盒子间的垂直距离由margin决定,并且同一个BFC下的margin会折叠(100+100=>100, 100+30=>100)。

    • BFC的区域不会与浮动元素重叠

    • 计算BFC的高度时,内部的浮动元素也参与计算 => 解决高度塌陷问题

  3. BFC 的应用

    • margin 重叠的解决办法:让它们分属不同的BFC。

    • 高度塌陷问题 (子元素均为浮动,则父元素高度为0):overflow:hidden触发BFC。

二、position 定位

position属性用来指定一个元素在网页上的位置,一共有 5 种定位方式。

1.static

默认值,元素的排布就是正常的页面流。

2.relative:默认位置/原位置

relativefixedabsolute 都是相对于基点的定位,差别在于基点的选取不同。

relative 是相对于默认位置偏移,需要搭配方向使用。

relative原本在文档流中占据的空间仍保留,视觉上没有脱离文档流。

.inner {
  position: relative;
  top:20px;  // 距离顶部 20px,向下偏移
}

3. fixed:视窗

fixed 是相对于浏览器窗口偏移,使得元素位置不会随页面滚动而变化。如果不使用方向属性,则初始位置就是元素的默认位置,否则就根据视口重新计算初始位置。

会脱离文档流,原本在文档流中占据的空间不再存在。

4. absolute:父元素

absolute 是相对于父元素偏移,需要搭配方向使用,要求父元素不能是static定位,否则定位的基点会变成html元素也就是整个网页。因此是相对于最近的非static的父元素

会脱离文档流,原本在文档流中占据的空间不再存在。

.outer {
  position:relative;
}
.inner {
  position:absolute;
  top:20px;
}

5. sticky:css3新属性

动态固定效果:在目标区域内就会类似relative定位;在滑动过程中,当该元素距离父元素的距离达到要求时,就会类似 fixed固定定位,例如购物网站的顶部栏,必须搭配方向使用。

三、flex 弹性布局

传统的布局是基于盒装模型,依赖 display + position + float属性,flex 是弹性布局,可以随着页面大小的改变而自适应页面布局。

  1. 块级元素、行内元素都可以使用 flex 布局。
  2. 父元素设置flex布局后,子元素的floatclearvertical-align属性都会失效
  3. 想要应用 flex 布局,那么父容器需要设置 display:flexdisplay:inline-flex,然后子容器根据设置的属性去瓜分、占有父容器的空间。

1. 容器的六大属性

  1. flex-direction:主轴的方向 或者 项目的排列方向。
flex-direction:row(默认) | row-reverse | column | column-reverse;
// 依次为水平自左向右、自右向左,垂直自上而下、自下而上
  1. flex-wrap:当主轴排不下全部项目时,如何换行。
flex-wrap:nowrap(默认,挤着) | wrap | wrap-reverse(第一行在下方);
  1. flex-flow:是前两个属性的简写形式,默认值 row nowrap
  2. justify-content:项目在主轴的对齐方式。
justify-content: flex-start(默认) | flex-end | center | space-between | space-around;
// 左对齐;右对齐;居中;
// 两端对齐、项目间隔相等、与边框相切;
// 项目两侧间隔相等,项目之间的间隔是项目与边框之间间隔的2倍
  1. align-items:项目在交叉轴的对齐方式。
align-items:flex-start | flex-end | center | baseline | stretch(默认);
// 与交叉轴的起始线、终线、中线对齐
// 与项目的第一行文字的基线对齐
// 占满整个容器的高度
  1. align-content:多根轴线的对齐方式。
align-content:flex-start | flex-end | center | space-between | space-around | stretch;
// 与交叉轴的起始线、终线、中线对齐 
// 与交叉轴两端对齐,~ || 每根轴线两侧的间隔相等,~
// 默认值,轴线占满交叉轴

2. 项目的六大属性

  1. order:项目的排列顺序。
order: // 默认0,数值越小,排列越靠前
  1. flex-grow:项目的放大比例。
flex-grow: // 默认0,不放大(剩余空间)
  1. flex-shrink:项目的缩小比例。
flex-shrink: // 默认1,如果空间不足,项目会缩小
  1. flex-basis:在分配多余空间之前,项目占据的主轴空间。可以设置为类似width的值,此时项目将占据固定空间。
flex-basis:优先级大于width
  1. flex :前三者的简写,默认0 1 auto
flex: <flex-grow>| <flex-shrink> | <flex-basis> 
auto(1 1 auto)
none(0 0 auto)
11 1 0):自适应
  1. align-self:可以设置单个项目与其他项目不一样的对齐方式。

四、grid 网格布局

Flex 布局是轴线布局,看作是一维的,而Grid布局则是将容器划分为 行和列,指定项目所在的单元格,看作是二维布局。Grid 布局远比 Flex 布局强大,是最强大的CSS布局方案。

1. 容器的属性

  1. grid-template-rows / grid-template-columns

    定义每一行的行高、每一列的列宽。可以使用百分比。

  2. grid-row-gap / grid-column-gap / grid-gap

    设置行间距、列间距,以及两者的合并简写形式。

  3. grid-auto-flow

    划分网格后,容器中的子元素的排列顺序。row是先行后列,column是先列后行。

  4. justify-items / align-items / place-items

    单元格中内容的水平位置(左中右)、单元格中内容的垂直位置(上中下)。

justify-items: start | end | center | stretch;
align-items: start | end | center | stretch;
  1. justify-content / align-content / place-content

    整个内容区域(全部单元格)在容器中的水平位置(左中右)、整个内容区域的垂直位置(上中下)。

  2. grid-auto-rows / grid-auto-columns

    当某个项目的指定位置在现有网格的外部时,使用这两个属性可以让浏览器自动创建多余网格的行高和列宽。

2. 项目的属性

  1. grid-row-start / grid-row-end / grid-column-start / grid-column-end / grid-row / grid-column

    指定项目的四个边框分别定位在哪根网格线。以及两者的合并简写。

  2. justify-self / align-self / place-self

    justify-items用法完全一样,也是设置单元格内容的水平位置,但只作用于单个项目。

Grid布局兼容性也较差,只支持高版本的浏览器

flex布局只要不是兼容IE浏览器就没问题,将老版本display:box、过渡版本display:flex box 和新版本display:flex混在一起使用兼容性较好。

div+css的兼容性是最好的。

五、居中布局

以下三种方式不论是针对行内元素还是块级元素,均可以实现水平居中、垂直居中、水平垂直均居中;不需要固定子元素的宽高

1. 水平垂直都居中

  1. flex布局
.outer {
  display:flex;
  justify-content:center;  // 仅水平居中
  align-items:center;      // 仅垂直居中
}
  1. Grid布局 同 Flex,兼容性较差。
.outer {
  display:grid;
  justify-items:center;  // 仅水平居中
  align-items:center;      // 仅垂直居中
}
  1. absolute + transform(css3新特性) translate(向右移动,向下移动)
.outer {
  position:relative;
}
.inner {
  position:absolute;
  left:50%;
  top:50%;
  transform:translate(-50%, -50%);  // (0,-50%)垂直居中
}
  • top:50%translate(0, -50%) 搭配是垂直居中;
  • left:50%translate(-50%, 0)搭配是水平居中。

2. 块级元素水平居中

除了上面3种,下面这种必须要设置宽高,也就是为块级元素或内联块级元素

.inner {
    width: 50px;
    height:50px;
    margin:0 auto;  // 左右距离 auto
}

块级元素垂直居中也是上面3种。

3. 行内元素水平居中

.outer {
    text-align:center;
}

4. 行内元素垂直居中:仅适用于单行文本

line-height 的值等于 height 值。

.outer {
    width:100px;
    height:120px;
    line-height:120px;
}

参考文章

  1. CSS定位详解
  2. flex布局
  3. flex-grow,flex-shrink,flex-basis
  4. Grid布局
  5. CSS浮动(float,clear)通俗讲解
  6. 居中方法总结