从零去理解大厂面官是如何去考量你对position属性的理解!!

488 阅读8分钟

前言

在前端开发领域,CSS 的 position 属性是构建页面布局的关键要素之一,而大厂面试官对其的考量往往涉及多个层面。本文将深入剖析面试官是如何从这个角度来考察应聘者对于这个属性的掌握情况。也会和大家一起共同将知识点嚼碎去理解!

首先我得带大家了解什么是文档流?

文档流是什么?

文档流是浏览器在渲染网页时遵循的一种默认布局规则。在正常的文档流中,元素按照其在 HTML 文档中的先后顺序依次排列,块级元素独占一行,从上到下排列,而行内元素则在一行内从左到右排列,直到该行排满后换行。这种默认的排列方式为页面提供了一种有序的布局结构。

上面提到的块级元素和行内元素有什么区别?

块级元素(Block-level Elements)

  • 布局特性:块级元素通常会以新行开始,并占据其父元素的整个宽度,即使它的实际内容可能没有那么宽。
  • 样式特点:支持设置宽度、高度、对齐方式等样式属性。
  • 应用场景:适用于需要独占一行或多行,或者需要设置固定宽度和高度的布局需求。
  • 常见标签<div><p><h1> 至 <h6><ul><ol><li> 等。

行内元素(Inline Elements)

  • 布局特性:行内元素不会开始新的一行,而是与其他行内元素在同一行内显示,直到遇到换行符或行空间不足时才换行。
  • 样式特点:可以设置颜色、字体等文本样式,但宽度和高度等尺寸属性一般不起作用。
  • 应用场景:适用于文本中的特定部分,如链接、强调文字等,不需要独占一行的情况。
  • 常见标签<span><a><strong><em><img> 等。 光是语言描述大家可能还不够直观,给大家上个代码和演示效果,让大家更好的理解一下!
<!DOCTYPE html>

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>


    <div style="border: 1px solid balck;">div1</div>
    <div style="border: 1px solid red;">div2</div>
    <span>这是一种图片</span>
    <img src="https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/c05fdf5a1930490ea6e7dc90d4ccf39c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5aSn5rW35piv6JOd6ImyYmx1ZQ==:q75.awebp?rk3s=f64ab15b&x-expires=1770715940&x-signature=emnsQ8DsDOc2XQdESe4ZZlq%2FSbc%3D" alt="">
    
</html>

总共有四个标签,按顺序分别是 div 、 div 、span 、img.

image.png 可以看到作为块级元素的div,每个人都独自占了一行,两个块级元素span 和 img他们共同处在一行! 这里的span和图片的底端对齐是因为

span 和 img 都是行内元素,默认情况下它们会在同一行内排列,并且它们的基线(baseline)会对齐。 这是因为行内元素在行盒(line box)中垂直对齐的方式默认是 baseline 对齐, baseline基线一般是指文字和图片的底部。

是不是现在对块级和行级有了初步的了解,今天他并不是我们的重点,我们接着介绍今天的主角position

一起了解position属性!!

position 属性是 CSS 中用于控制元素定位的重要属性。它决定了元素如何相对于其正常位置、父元素或其他元素进行定位。

  1. static(默认值)

    • 元素按照正常的文档流进行布局,不进行特殊定位。
    • 不能设置 toprightbottomleft 和 z-index 属性。
  2. relative

    • 元素相对于其正常位置进行定位。
    • 可以使用 toprightbottom 和 left 属性来调整元素的位置。
    • 不会影响其他元素的位置。
    • 可以设置 z-index 属性来控制堆叠顺序。
  3. absolute

    • 元素相对于最近的非 static 定位的祖先元素进行定位。
    • 如果没有这样的祖先元素,则相对于初始包含块(通常是浏览器窗口)进行定位。
    • 元素完全脱离文档流,不再占据原来的空间。
    • 可以使用 toprightbottom 和 left 属性来调整元素的位置。
    • 可以设置 z-index 属性来控制堆叠顺序。
  4. fixed

    • 元素相对于浏览器窗口进行定位,不受页面滚动影响。
    • 元素完全脱离文档流,不再占据原来的空间。
    • 可以使用 toprightbottom 和 left 属性来调整元素的位置。
    • 可以设置 z-index 属性来控制堆叠顺序。
  5. sticky

    • 元素根据用户的滚动位置进行定位。
    • 在滚动到特定阈值之前,元素表现为 relative 定位。
    • 当滚动超过阈值时,元素变为 fixed 定位。
    • 可以使用 toprightbottom 和 left 属性来设置阈值。
    • 可以设置 z-index 属性来控制堆叠顺序。

通过上文对position属性的介绍我们可以发现 position: absolute 和 position: fixed 的元素会脱离文档流,因此其他元素会忽略它们占据的空间。

这句话不禁引起我们的是思考,什么是脱离文档流?是不是就是不按默认的布局规则去布局,呢不按默认的布局,他是怎么布局呢?

脱离文档流

绝对定位和相对定位

我们来看两个例子,去理解何为脱离文档流?

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        #box1 {
            width: 200px;
            height: 200px;
            background-color: green;
        }

        #box2 {
            width: 300px;
            height: 300px;
            background-color: yellow;
        }
    </style>
</head>

<body>
    <div id="box1">box1</div>
    <div id="box2">box2</div>
</body>

</html>
image.png

我们写了两个div元素,他们是块级元素,自然各占据一行。 这个时候我们给ID为box1的元素添加一个position属性 设置position:absolue;

   #box1 {
            width: 200px;
            height: 200px;
            background-color: green;
            position:absolue;
        }
image.png 我们发现本该在下面的黄色盒子,怎么跑上来了,而且还被绿色盒子覆盖了一部分!!这个时候我可以高数大家脱离文档流的定义

某些元素在页面布局中不再占据其原本应占的空间,它们的位置和大小不再影响其他元素的布局。当一个元素脱离文档流后,其他元素会像这个元素不存在一样进行布局。我们可以把他理解为飘起来了!

我们这个时候再做一个变式,帮助大家理解一下 我们给ID为box2的元素添加一个position属性 设置position:absolue;并设置 top:20px; left:20px;,ID为box1的元素添加一个position属性 设置position:relative;并设置 margin: 20px;

   #box1 {
            width: 200px;
            height: 200px;
            background-color: green;
            position:relative;
             margin: 20px;
        }
   #box2 {
            width: 200px;
            height: 200px;
            background-color: green;
            position:absolue;
            top: 20px;
            left: 20px;
        }
      

且 html中

<body>
    <div id="box1">
        <div id="box2">box2</div>
    </div>
    
</body>
image.png 这个时候我们再把ID为box1的元素删除`position`属性!

image.png 对比上面两张图片你会发现,第一张图片中 box2 是相对 box1 进行左右偏移的 ,而第二张图片中, 第二张图片是相对初始包含块(即屏幕视口)进行偏移的

这就是需要注意的考点!!!

定位属性为absolue的元素相对于最近的非 static 定位的祖先元素进行定位。如果没有这样的祖先元素,则相对于初始包含块(通常是浏览器窗口)进行定位。

介绍一下固定定位,继续给代码示例理解!

固定定位

       #box1 {
            width: 200px;
            height: 200px;
            background-color: green;
            position: fixed;
            top: 200px;
            left: 90px;
        }

        #box2 {
            width: 300px;
            height: 2000px;
            background-color: yellow;
        }
  
    结构如下
    <div id="box1">box1</div>
    <div id="box2">box2</div

你会发现 box1 依然会覆盖 box2,并且当你滚动页面时,box1 会固定在屏幕的某个位置,不受页面滚动的影响。

动画.gif

粘性定位

最后,我们来看看粘性定位的效果。position: sticky 是一种特殊的定位方式,它结合了 relativefixed 的特性。当元素的滚动位置达到某个阈值时,它会固定在某个位置,类似于 fixed 定位,但在滚动回原来的位置时,它又会恢复到 relative 定位。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Sticky Navigation Example</title>
    <style>
        nav {
            background-color: #333;
            color: white;
            padding: 10px;
            position: sticky;
            top: 0;
        }

        p {
            height: 1000px;
            background-color: #ccc;
        }
    </style>
</head>

<body>
    <nav>
        <a href="#">Home</a>
        <a href="#">About</a>
        <a href="#">Contact</a>
    </nav>
    <p>这是一些页面内容,用于使页面可以滚动,当滚动到导航栏接近顶部时,导航栏会固定在顶部。</p>
</body>

</html>

动画.gif

注意混淆

相信会有很多人觉得可以fixed模拟sticky的问题,他们不是一样吗?其实是不可以的!

  • 从视觉效果上看,在某些简单的情况下,fixed似乎可以实现类似sticky的效果。但实际上,它们的行为逻辑是不同的。

  • 如果使用fixed来模拟sticky,会出现元素一开始就脱离文档流的情况。这可能导致页面布局在一开始就出现不符合预期的空白区域或者元素重叠等问题。

  • 例如,在一个有图文混排的页面中,如果用fixed来模拟导航栏的sticky效果,导航栏一开始就固定在顶部,那么原本在导航栏下方的内容可能会向上移动,占据导航栏原本在文档流中的位置,导致布局混乱。而sticky定位可以避免这种一开始就破坏文档流的问题,只有在合适的滚动位置才改变定位方式。当sticky定位的元素在滚动到指定位置后 “粘住” 时,它会脱离文档流,表现得和fixed定位类似。

结尾

到此你应该完全理解了 position 属性 暗藏的玄机,知其然知其所以然,希望这些简单的示例能帮助你更好地理解 position 属性的不同值及其效果。如果有任何疑问或需要进一步解释的地方,请随时留言交流。😊