CSS布局相关——定位、flexbox和BFC

正常布局流

浏览器在默认情况下,组织元素的布局方式:

  • 任何元素都被包装成一个盒子,包含内容、内外边距以及边框
  • 块级元素会基于其父元素的书写顺序进行放置,每个块级元素会在上一个元素下面另起一行,它们会被设置好的margin 分隔
  • 内联元素的表现有所不同 --- 它们不会另起一行;只要在其父级块级元素的宽度内有足够的空间,它们与其他内联元素、相邻的文本内容(或者被包裹的)被安排在同一行。如果空间不够,溢出的文本或元素将移到新的一行
  • 如果两个相邻的元素都设置了margin 并且两个margin有重叠,那么更大的设置会被保留,小的则会消失 --- 这被称为外边距叠加

定位(Position)

定位的目的即允许我们通过某种手段覆盖上述正常布局流文档,以按照我们想要的效果来进行排版

静态定位(static)

静态定位是每个元素获取的默认值——它只是意味着“将元素放入它在文档布局流中的正常位置 ——这里没有什么特别的,比如在某个规则中添加position属性,并使其值为static:

.positioned {
  background: yellow;
  position: static;
}

此代码和添加position属性之前没有任何区别,即:静态定位是每个元素的默认行为

相对定位(relative)

相对定位仍可以使该元素占据正常文本流,但是可以通过top、bottom、left和right属性修改它的最终位置,包括让它与页面上的其它元素重叠

.relative{
    position: relative;
    top: 30px;
    left: 30px;
}
image.png

这里的结果表示,应用position: relative的元素相对于其原来所处的位置向下移动了30px,向右移动了30px

  • relative 表现的和 static 一样,除非你添加了一些额外的属性
  • 在一个相对定位(position属性的值为relative)的元素上设置 top 、 right 、bottom 和 left 属性会使其偏离其正常位置。其他的元素的位置则不会受该元素的影响发生位置改变来弥补它偏离后剩下的空隙
绝对定位

与相对定位不同,绝对定位的元素不再存在于正常文本流中。相反,它处于独立于正常文本流的一层,因此后面的元素会填补其空出的位置

.absolute{
    position: absolute;
    top: 30px;
    left: 30px;
}
image.png

需要注意这里的结果,这和relative的结果很不一样,被设置为position: absolute的元素会相对于其父元素(这里是body)产生位置偏移,这里是距离父元素的顶部边框30px,距离父元素的左边框30px

这里有另一个例子,设置父元素的position值为relative会让其设置绝对定位的子元素看起来很不一样:

.relative {
  position: relative;
  width: 600px;
  height: 400px;
}

.absolute {
  position: absolute;
  top: 120px;
  right: 0;
  width: 300px;
  height: 200px;
}

image.png

因此一个元素的绝对定位的具体表现与其父元素的定位方式有很大关系:
如果元素是静态定位的。即如果它是 position: static ,那么它的绝对定位子元素会跳过它直接相对于body元素定位

z-index

当多个元素使用绝对定位时,难免会造成彼此之间的重叠,因此要决定哪些元素在哪些元素的顶部就显得非常重要,这也是为什么我们要设置z-index的原因
这实际上和图层原理很相似,凡是定位的元素都具有z-index的值为auto,实际上是0
如果不设置z-index的值,则元素的原始堆叠顺序是:在html标记中,定义顺序越靠后的元素将堆叠在靠前元素的上面
如果设置了z-index的值,则值越大的元素会叠加在值越小的元素上面

image.png

图中绿色背景框与黄色背景框都被设置成position:absolute,但因为绿色背景框的CSS规则中设置了z-index值:

z-index: 1;

而黄色背景框的z-index值默认为0,所以绿色叠加在了黄色上面

需要注意的是:z-index只接受无单位索引值;你不能指定你想要一个元素是Z轴上23像素—— 它不这样工作。 较高的值将高于较低的值,这取决于您使用的值。 使用2和3将产生与300和40000相同的效果

固定定位

还有一种类型的定位覆盖——fixed。 这与绝对定位(absolute)的工作方式完全相同,只有一个主要区别:绝对定位固定元素是相对于<html>或其最近的定位祖先,而固定定位固定元素则是相对于浏览器视口本身。 这意味着您可以创建固定的有用的UI项目,如持久导航菜单

position:sticky

还有一个可用的位置值称为 position: sticky,比起其他位置值要新一些。它基本上是相对位置和固定位置的混合体,它允许被定位的元素表现得像相对定位一样,直到它滚动到某个阈值点(例如,从视口顶部起10像素)为止,此后它就变得固定了。例如,它可用于使导航栏随页面滚动直到特定点,然后粘贴在页面顶部

例子:
https://www.w3school.com.cn/tiy/t.asp?f=css_position_sticky

参考:
https://zh.learnlayout.com/position.html

弹性盒子(FlexBox)

即便大多数情况下,使用float和position属性就能完成大多数布局,但还是有一些情况是这两种属性很难完成、甚至无法完成的,因此引入“弹性盒子”可以更好的帮助我们完成网页的自适应布局

flex模型说明

当一个元素表现为flex框时,它会沿着两个轴来进行布局:


image.png
  • 主轴:是沿着 flex 元素放置的方向延伸的轴(比如页面上的横向的行、纵向的列)。该轴的开始和结束被称为 main start 和 main end

  • 交叉轴:是垂直于 flex 元素放置方向的轴。该轴的开始和结束被称为 cross start 和 cross end

  • 设置了 display: flex 的父元素(被称之为 flex 容器(flex container)。

  • 在 flex 容器中表现为柔性的盒子的元素被称之为 flex 项flex item)元素。

在了解了以上内容之后,即可开始说明flex布局的表现形式以及具体属性

flex父容器属性

要先使用flexbox模型,首先必须先定义flex容器:
html:

<div class="flex-container">
    <div>1</div>
    <div>2</div>
    <div>3</div>
</div>

CSS:

.flex-container {
    display: flex;
}

通过display属性设置为flex,父容器将变得可以随浏览器窗口大小而伸缩


image.png

flex-direction:控制容器堆叠flex项目的方向

垂直从上到下

.flex-container {
  display: flex;
  flex-direction: column;
}
image.png

垂直从下到上

.flex-container {
  display: flex;
  flex-direction: column-reverse;
}
image.png

水平从左到右

.flex-container {
  display: flex;
  flex-direction: row;
}
image.png

水平从右到左

.flex-container {
  display: flex;
  flex-direction: row-reverse;
}
image.png

flex-wrap:控制容器内flex项目换行,默认值为“ nowrap ”

在必要的时候对flex项目进行换行处理

.flex-container {
  display: flex;
  flex-wrap: wrap;
}
image.png

此外该属性取值为wrap-reverse时,父容器将对flex项目进行倒序换行

flex-flow:简写属性,用来同时设置flex-direction和flex-wrap,比如:

.flex-container {
  display: flex;
  flex-flow: row wrap;
}

即相当于设置了 flex-direction:row ,flex-wrap:wrap

justify-content:用于定义flex项目在主轴上的对齐方式,以下说明取值效果:

center:中心对齐


image.png

flex-start:在容器开头对齐


image.png

flex-end:在容器末尾对齐


image.png

space-around:保留flex项目间与父容器边框之间的空隙


image.png

space-between:仅保留flex项目间的空隙


image.png

align-items:用于定义flex项目在交叉轴上的对齐方式

flex-start:交叉轴起点对齐


image.png

flex-end:交叉轴终点对齐


image.png

center:交叉轴中点对齐


image.png

stretch:若项目没有设置高度或设置为auto,flex项目将占满整个容器的高度(默认值)


image.png

baseline:项目的第一行文字的基线对齐


image.png

align-content:定义多轴线对齐方式,如果项目只有一根轴线,则该属性不起作用

flex-start:交叉轴起点对齐
flex-end:交叉轴终点对齐
center:交叉轴中点对齐
stretch:轴线上的项目占满整个交叉轴
space-between:与交叉轴两端对齐,轴线之间的间隔平均分布
space-around:每根轴线两侧的间隔都相等


image.png

完美居中
对flex父容器设置:

.flex-container {
  display: flex;
  height: 300px;
  justify-content: center;
  align-items: center;
}

结果如下:


image.png
子项目属性

order:定义项目的排列顺序,数值越小,排列越靠前

<div class="flex-container">
    <div style="order: 3">1</div>
    <div style="order: 2">2</div>
    <div style="order: 4">3</div> 
    <div style="order: 1">4</div>
</div>
image.png

flex-grow:定义项目的放大比例。默认值为0,即如果存在是剩余空间,也不放大

<div class="flex-container">
    <div style="flex-grow: 1">1</div>
    <div style="flex-grow: 1">2</div>
    <div style="flex-grow: 2">3</div>
</div>
image.png

如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍

flex-shrink:定义项目的缩小比例,默认值为1,即如果空间不足,项目缩小

<div class="flex-container">
    <div>1</div>
    <div>2</div>
    <div style="flex-shrink: 0">3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
    <div>7</div>
    <div>8</div>
    <div>9</div>
    <div>10</div>
</div>
image.png

如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小

flex-basis:属性规定 flex 项目的初始长度

<div class="flex-container">
    <div>1</div>
    <div>2</div>
    <div style="flex-basis:200px">3</div>
    <div>4</div>
</div>
image.png

第三个弹性项目的初始长度为 200 像素

flex简写属性

flex 属性是 flex-grow、flex-shrink 和 flex-basis 属性的简写属性
比如:

<div class="flex-container">
  <div>1</div>
  <div>2</div>
  <div style="flex: 0 0 200px">3</div>
  <div>4</div>
</div>

使第三个弹性项目不可增长(0),不可收缩(0),且初始长度为 200 像素

align-self
  • align-self 属性规定弹性容器内所选项目的对齐方式
  • align-self 属性将覆盖容器的 align-items 属性所设置的默认对齐方式
  • 允许单个项目有与其他项目不一样的对齐方式,可覆盖align-item值,默认为auto,表示继承父元素的align-item属性,如果没有父元素,则等同于stretch

BFC

不要试图去讲解 BFC 的定义!!

如何说明 BFC ,举例子!!不要试图去讲定义!

具有 BFC 特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器所没有的一些特性

通俗一点来讲,可以把 BFC 理解为一个封闭的大箱子,箱子内部的元素无论如何翻江倒海,都不会影响到外部

如何触发BFC

只要元素满足下面任一条件即可触发 BFC 特性:

  • body 根元素
  • 浮动元素:float 除 none 以外的值
  • 绝对定位元素:position (absolute、fixed)
  • display 为 inline-block、table-cells、flex
  • overflow 除了 visible 以外的值 (hidden、auto、scroll)
具体应用

避免外边距折叠
同一个 BFC 下外边距会发生折叠,既然如此,把它们分别放到两个BFC里就行了
html:

<div class="container">
    <p></p>
</div>
<div class="container">
    <p></p>
</div>

CSS:

.container {
    overflow: hidden;
}
p {
    width: 100px;
    height: 100px;
    background: lightblue;
    margin: 100px;
}

这时,两个盒子的边距变成了200px;


image.png

BFC可以包含浮动元素(清除浮动)
清除浮动的手法之一:

<div style="border: 1px solid #000;overflow: hidden">
    <div style="width: 100px;height: 100px;background: #eee;float: left;"></div>
</div>

BFC可以阻止元素被浮动元素覆盖
设置float的文字环绕效果:

<div style="height: 100px;width: 100px;float: left;background: lightblue">我是一个左浮动的元素</div>
<div style="width: 200px; height: 200px;background: #eee">我是一个没有设置浮动, 也没有触发 BFC 元素, width: 200px; height:200px; background: #eee;</div>
image.png

这时候其实第二个元素有部分被浮动元素所覆盖,(但是文本信息不会被浮动元素所覆盖) 如果想避免元素被覆盖,可触第二个元素的 BFC 特性,在第二个元素中加入 overflow: hidden,就会变成:


image.png

这个方法可以用来实现两列自适应布局,效果不错,这时候左边的宽度固定,右边的内容自适应宽度

参考:
https://zhuanlan.zhihu.com/p/25321647

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,099评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,473评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,229评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,570评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,427评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,335评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,737评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,392评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,693评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,730评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,512评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,349评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,750评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,017评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,290评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,706评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,904评论 2 335

推荐阅读更多精彩内容

  • 1. 浮动元素有什么特征?对父容器、其他浮动元素、普通元素、文字分别有什么影响? 浮动元素脱离普通文档流,浮动元素...
    怎么昵称阅读 425评论 0 0
  • display:float 浮动详解 在我刚开始学习CSS的时候,看到浮动这个概念,只知道是让一个盒子向左或向右移...
    闰土在流浪阅读 1,148评论 0 6
  • 目录 标准盒模型和怪异盒模型 link标签和import标签的区别 flex布局 BFC 垂直居中的方法 块元素和...
    Grandperhaps阅读 414评论 0 4
  • 1.1CSS 基础与选择器初识 | CSS 1. CSS 加载方式有几种? CSS样式加载一共有四种方式: 1、行...
    没糖_cristalle阅读 680评论 0 0
  • 1.两种盒模型 盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(borde...
    zhenghongmo阅读 60评论 0 0