CSS

CSS布局-文档流

This entry is part 8 of the seriesenjoy-css

CSS中有多种布局方式,常用的有Position LayoutFlexbox LayoutGrid Layout。在介绍上面提到的三种常用布局方式之外,我们先要掌握Document Flow(文档流)。

文档流是指HTML元素在页面中的默认布局方式,是Web页面布局的基础概念之一。理解文档流对于掌握CSS布局至关重要,因为它影响着元素如何在页面上排列以及它们之间的关系。

在文档流中有两种主要的元素类型:

  • 块级元素(block): 在文档流中,块级元素会占据整个可用宽度,自上而下 排列,并且后续元素紧跟其下方。例如,<div><p><h1>等都是块级元素。
  • 内联元素(inline): 与块级元素不同,内联元素只占据必要的宽度,不会导致换行。它们通常出现在同一行内自左向右 排列,除非遇到换行符或其他特殊情况。例如,<span><a><img>等都是内联元素

我们可以使用display属性来指定元素的显示类型:

css
/* 将<a>标签从 inline转换为block */
a.nav-link {
display: block
}

除此之外还有一个值内联块(inline-block),它有点像介于blockinline之间的结合体,我们会在文章的最后介绍它。

内联元素 VS 块级元素

HTMLINLINEVSBLOCKELEMENT
<Inline Element>
  • 宽高只受内容影响, 无法指定
  • span
  • 自左向右排列,可换行
  • spanbutton
  • 不能包含块级元素
  • span
    div
  • 无法设置margin-top和margin-bottom
  • span
    <Inline Element>
  • 默认占用全部宽度,宽高可指定
  • div
  • 自上向下排列
  • div
    h1
  • 既可以包含块元素也可以包含内联元素
  • p

  • 可以设置margin-top和margin-bottom
  • div

    内联元素注意事项

    关于内联元素有些场景我们需要了解一下,比如下面的案例

    Code Playground
    <style>
    div {
      outline: 2px dashed black;
    }
    </style>
    <div>
      <img
        src="https://blog.slashspaces.com/images/panda.jpg"
        height="100"
        alt="panda photo"
      />
    </div>

    <img>的高度只有100px,而其父元素<div>的高度却是106.5px, 多出来像素是从哪冒出来的呢?

    其实,浏览器会将内联元素视作文本,文本与文本之间无论是上下还是左右都是需要一定间隙的,否则就会显得过于拥挤。

    弄清楚原因后解决这个问题就很简单了, 以下两种方法都能解决:

    • <img>设置为display: block
    • <div>line-height设为0
    Code Playground
    <style>
    div {
      outline: 2px dashed black;
      line-height: 0;
    }
    </style>
    <div>
      <img
        src="https://blog.slashspaces.com/images/panda.jpg"
        height="100"
        alt="panda photo"
      />
    </div>

    内联元素之间的间距

    另外一个需要注意的点就是,内联元素之间是存在间距的,请注意下面案例中三副图之间的间距

    Code Playground
    <style>
    div {
      outline: 2px dashed black;
    }
    </style>
    <div>
      <img
        src="https://blog.slashspaces.com/images/panda.jpg"
        width="100"
        alt="panda photo"
      />
        <img
        src="https://blog.slashspaces.com/images/panda.jpg"
        width="100"
        alt="panda photo"
      />
        <img
        src="https://blog.slashspaces.com/images/panda.jpg"
        width="100"
        alt="panda photo"
      />
    </div>

    这是由元素之间的空白引起的,当你在HTML源代码中编写多个内联元素时,如果它们之间有换行或空格,这些空白就会被视为文本节点的一部分,并且会在渲染时显示出来。这就是为什么即使没有明确添加空格或其他可见字符,你仍然可能看到元素之间有一定的间距。

    如何解决这个问题呢?最直接的解决方案是在源代码中移除元素之间的所有换行和空格。这意味着将所有相关的标签放在同一行上,如下所示

    Code Playground
    <style>
    div {
      outline: 2px dashed black;
    }
    </style>
    <div>
      <img
        src="https://blog.slashspaces.com/images/panda.jpg"
        width="100"
        alt="panda photo"
      /><img
        src="https://blog.slashspaces.com/images/panda.jpg"
        width="100"
        alt="panda photo"
      /><img
        src="https://blog.slashspaces.com/images/panda.jpg"
        width="100"
        alt="panda photo"
      />
    </div>

    但这中处理方法的可读性和维护性很差,更好的处理方法是使用Flexbox,这个我们会在后续章节中介绍。

    内联元素可以换行

    内联元素最重要的特性就是:可以换行

    下面是一个<p>标签内包含一段<strong>

    This is a paragraph with some very bolded words in it.

    如果我们给<strong>加上border, 你会发现内联元素会产生一个非矩形的形状

    This is a paragraph with some very bolded words in it.

    这有助于解释,为什么有些CSS属性在内联元素上不生效。试想以下,在这种形状上设置margin-topmargin-bottom有什么意义?

    内联块(inline-block)

    你可能听过一句谚语披着羊皮的狼,类似的我们可以把inline-block看作披着inline皮的block

    inline-blockinline元素一样,在文档流中自左向右排列,但同时又像block元素一样,可以设置widthheightmargin-top以及margin-bottom

    Code Playground
    <style>
    p {
      outline: 1px dashed black;
    }
    strong {
      display: inline-block;
      background: red;
      color: white;
      width: 100px;
      text-align: center;
      margin-top: 32px;
    }
    </style>
    <p>
      <strong>Warning:</strong> Something error!
    </p>

    尝试移除display: inline-block声明,看看有什么变化。

    Questions? Let's chat

    discord logoOPEN DISCORD
    6423
    members online
    previous article
    CSS基础-盒模型

    A TypeScript Full Stack Blog

    Share articles about Typescript, React, Next.js, Node.js and Css from time to time.
    No spam, unsubscribe at any time.