深入CSS(下) | 青训营

64 阅读6分钟

常规流(Normal Flow)

  • 根元素、浮动和绝对定位的元素会脱离常规流

  • 其它元素都在常规流之内(in-flow)

  • 常规流中的盒子,在某种排版上下文中参与布局

行级排版上下文 Inline Formatting Context (IFC)

  • 只包含行级盒子的容器会创建一个IFC

  • IFC 内的排版规则

    • 盒子在一行内水平摆放
    • 一行放不下时,换行显示
    • text-align 决定一行内盒子的水平对齐
    • vertical-align 决定一个盒子在行内的垂直对齐
    • 避开浮动(float)元素*
<div>
  This is a paragraph of text with long word Honorificabilitudinitatibus. Here is an image
  <img src="https://assets.codepen.io/59477/cat.png" alt="cat">
  And <em>Inline Block</em>
</div>

<style>
  div {
    width: 10em;
    //overflow-wrap: break-word;
    background: #411;
  }

  em {
    display: inline-block;
    width: 3em;
    background: #33c;
  }
</style>

<div> 本身是一个块级元素,但<div> 里面都是行级元素——只包含行级盒子的容器会创建一个行级排版上下文,因此,<div>创建了一个行级排版上下文。

display: inline-block<em> 成为一个整体,不会被分割成多行。

image.png

Honorificabilitudinitatibus 是一个整体,不会被拆分,就会超出 <div> 设置的宽度。

可以使用 overflow-wrap: break-word,当单词超出容器时,会被强制换行。

image.png

块级排版上下文 Block Formatting Context (BFC)

  • 某些容器会创建一个BFC

    • 根元素
    • 浮动、绝对定位、inline-block
    • Flex子项和Grid子项
    • overflow 值不是 visible 的块盒
    • display: flow-root;
  • BFC 内的排版规则

    • 盒子从上到下摆放
    • 垂直 margin 合并
    • BFC 内盒子的 margin 不会与外面的合并
    • BFC 不会和浮动元素重叠

常规流里一个盒子内的子级盒子,只能都是块级,或者都是行级。如果都是块级,就从上到下排列;如果都是行级,就从左到右排列。

<span>
  This is a text and
  <div>block</div>
  and other text.
</span>

<style>
  span {
    line-height: 3;
    border: 2px solid red;
    background: coral;
  }

  div {
    line-height: 1.5;
    background: lime;
  }
</style>

image.png

<span>本身是一个行盒,但盒子内又有行盒,又有块盒,此时浏览器会产生一个匿名的块级盒子(只能在 CSS 排版引擎中看到)来包裹橙色的两段文字。

Flex Box

Flex Box 是什么
  • 一种新的排版上下文

  • 它可以控制子级盒子的:

    • 摆放的流向 ( →  ←  ↑  ↓ )
    • 摆放顺序
    • 盒子宽度和高度
    • 水平和垂直方向的对齐
    • 是否允许折行
<div class="container">
  <div class="a">A</div>
  <div class="b">B</div>
  <div class="c">C</div>
</div>
<style>
  .container {
    display: flex;
    border: 2px solid #966;
  }

  .a, .b, .c {
    text-align: center;
    padding: 1em;
  }

  .a {
    background: #fcc;
  }

  .b {
    background: #cfc;
  }

  .c {
    background: #ccf;
  }
</style>

image.png

display: flex:子盒都遵循flex排版上下文的规则。

flex-direction

默认是从左到右。

image.png

对齐

image.png

主轴方向的对齐:justify-content

image.png

默认是 flex-start

  • space-between —— 两端对齐,中间间隔相等,两侧没空格
  • space-around —— 整行分散,两侧空格小,中间空格大
  • space-evenly —— 整行分散,两侧空格与中间空格大小相等

侧轴方向的对齐:align-items

image.png

  • stretch —— 将容器内元素高度撑到与容器一样高
  • baseline —— 基线对齐,容器内所有子元素的基线对齐

align-items 属性设置在容器上,针对某个特定子元素设置对齐使用 align-self

image.png

按序对齐方式 order:给元素设置不同的数字 ,然后按着数字大小 从小到大 排序。

image.png

Flexibility
  • 可以设置子项的弹性:当容器有剩余空间时,会伸展;容器空间不够时,会收缩。

  • flex-grow 有剩余空间时的伸展能力

  • flex-shrink 容器空间不足时收缩的能力

  • flex-basis 没有伸展或收缩时的基础长度(默认为设置的 width大小,一般不设置 flex-basis

  • flex-grow

  <div class="container">
    <div class="a">A</div>
    <div class="b">B</div>
    <div class="c">C</div>
  </div>

  <style>
    .container {
      display: flex;
    }

    .a, .b, .c {
      width: 100px;
    }

    .a {
      flex-grow: 2;
    }

    .b {
      flex-grow: 1;
    }
  </style>

整个容器减去原先没拉伸时的大小(即300px),剩下的容器空间按照 2 :1 ,分配给 A 和 B。并非指 A :B 是 2 :1。

.a, .b, .c {
    width: 400px;
  }

  .a {
    flex-shrink: 0;
  }
</style>

整个容器无法含下三个元素共1200px,A 不进行压缩,B、C根据剩下的容器空间一分为二

flex-grow、flex-shrink、flex-basis可以缩写为flex 属性

image.png

Grid 布局

Grid 布局是二维的布局方式

image.png

display:grid

image.png

划分网格 grid-template
grid-template-columns: 100px 100px 200px;
grid-template-rows: 100px 100px

三列两行:列宽分别为 100px,100px,200px;行高均为 100px。

grid-template-columns: 30% 30% auto;
grid-template-rows: 100px auto

auto:自动充满

三列两行:列宽分别为30%,30%,40%;行高分别为 100 px,高度-100px。

grid-template-columns: 100px 1fr 1fr;
grid-template-rows: 100px 1fr

fr:fraction,表示一份

三列两行;第一列列宽为 100px,剩下的宽度第二列、第三列各占一份;第一行高度为 100px,剩下的高度第二行占一份。

网格线 grid line:

image.png

网格区域 grid area:

image.png

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

也可以写成

.a {
  grid-area: 1/1/3/3;
}

浮动(Float)

用于实现文字环绕效果。

<section>
  <img src="https://p4.ssl.qhimg.com/t017aec0e7edc961740.jpg" width="300" alt="mojave" />
  <p>莫哈韦沙漠不仅纬度较高,而且温度要稍微低些,是命名该公园的短叶丝兰——约书亚树的特殊栖息地。约书亚树以从茂密的森林到远远间隔的实例等各种形式出现。除了约书亚树森林之外,该公园的西部包括加州沙漠里发现的最有趣的地质外观。
  </p>
</section>

<style>
  img {
    float: left;
  }

  p {
    font-size: 20px;
    line-height: 1.8;
  }
</style>

image.png

定位(Position)

position 属性

  • static:默认值,非定位元素(静态的,参与流常规流中的布局)

  • relative:相对自身原本位置偏移,不脱离文档流(原先空间依旧被占有,对其它元素没有影响)

image.png

  • absolute:绝对定位,相对非 static 祖先元素定位 (整个容器不会预留原先的空间,其他元素当作它不存在进行排版) image.png

  • fixed:相对于视口绝对定位(脱离了常规的文档流)

<h1>页面标题</h1>
<div class="container">
  <div class="box"></div>
  <p>段落内容段落内容 1</p>
  <p>段落内容段落内容 2</p>
  <p>段落内容段落内容 3</p>
  <p>段落内容段落内容 4</p>
</div>

<style>
  .container {
    background: lightblue;
  }

  .box {
    position: absolute;
    top: 0;
    left: 0;
    width: 100px;
    height: 100px;
    background: red;
  }
</style>

image.png

container 、<body>都是 static 的定位(未设置即默认 static),因此 box 根据页面的边缘进行定位。

<nav>
  <a href="#">首页</a>
  <a href="#">导航1</a>
  <a href="#">导航2</a>
</nav>
<main>
  <section>1</section>
  <section>2</section>
  <section>3</section>
  <section>4</section>
  <section>5</section>
</main>
<a href="#" class="go-top">返回顶部</a>

<style>
  nav {
    position: fixed;
    line-height: 3;
    background: rgba(0, 0, 0, 0.3);
    width: 100%;
  }
  
  .go-top {
    position: fixed;
    right: 1em;
    bottom: 1em;
    color: #fff;
  }

  nav a {
    padding: 0 1em;
    color: rgba(255, 255, 255, 0.7);
  }

  nav a:hover {
    color: #fff;
  }

  body {
    margin: 0;
    font-size: 14px;
  }

  a {
    color: #fff;
    text-decoration: none;
  }

  section {
    height: 22vh;
    color: #fff;
    text-align: center;
    font-size: 5em;
    line-height: 22vh;
  }

  section:nth-child(1) {
    background: #F44336;
  }

  section:nth-child(2) {
    background: #3F51B5;
  }

  section:nth-child(3) {
    background: #FFC107;
  }

  section:nth-child(4) {
    background: #607D8B;
  }

  section:nth-child(5) {
    background: #4CAF50;
  }
</style>

image.png

页面滚动,导航栏 <nav> 和 返回顶部 go-top相对页面是固定的。

学习建议

  • 充分利用 MDN 和 M3C CSS 规范
  • 保持好奇心,善用浏览器的开发者工具
  • 持续学习, CSS 新特性还在不断出现

学习心得:

常规流是页面中大多数元素的默认排版方式,而浮动和绝对定位则可以用于特殊的布局需求,比如文字环绕和图层叠放。Flex Box和Grid布局可以灵活地定义子元素在行和列中的排列方式,使页面布局更加简洁和灵活。在实际开发中,灵活运用常规流、浮动、绝对定位、Flex Box和Grid布局,可以提升用户体验和交互效果。