百度面试题之绝对定位(position属性原理)

330 阅读7分钟

百度面试题之绝对定位

在前端开发中,CSS 的 position 属性是一个非常重要的概念,它决定了元素在页面上的定位方式。本文将详细介绍文档流的概念以及 position 属性中的 relativeabsolute 定位方式,并通过具体的示例来说明它们的工作原理。

文档流

文档流的概念

文档流是指页面上元素按照 HTML 文档的书写顺序从上至下、从左至右排列的方式。每个元素在文档流中都有一个默认的位置。

  • 块级元素:独占一行,如 <div><p><h1> 等。
  • 行内元素:在同一行内显示,如 <span><a><img> 等。

页面绘制的本质

网页的结构由 HTML 标记语言构建,这些标记定义了网页上的各种元素,如文本、图片、视频等。页面绘制的本质是将这些元素转换成屏幕上的像素,以实现视觉上的展示。每个 HTML 元素在页面上都会占据一定的空间,这个空间由其自身的尺寸(宽度和高度)、内边距(padding)、边框(border)以及外边距(margin)共同决定。

文档流中的元素绘制顺序

在文档流中,元素按照它们在 HTML 文档中的顺序依次绘制。例如,假设我们有以下 HTML 结构:

<div id="box1">Box 1</div>
<div id="box2">Box 2</div>

对应的 CSS 代码:

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

#box2 {
    width: 300px;
    height: 300px;
    background-color: darkseagreen;
}

image.png

在这种情况下没有使用任何position属性,根据文档流原理,浏览器会先绘制 #box1,然后再绘制 #box2。每个盒子的大小和位置会根据其 widthheightpaddingbordermargin 属性进行精确计算。

position 的属性原理

static(默认值)

  • 描述:这是元素的默认定位方式。
  • 行为:元素按照正常的文档流进行布局,不会受到 topbottomleft 和 right 属性的影响。

relative 相对定位

相对定位(relative)使得元素相对于其正常位置进行定位。使用 topbottomleftright 属性可以调整元素的位置,但不会改变其他元素的布局。

示例代码
<div id="box1">Box 1</div>
<div id="box2">Box 2</div>

对应的 CSS 代码:

#box1 {
    width: 200px;
    height: 200px;
    margin: 10px;
    background-color: skyblue;
    position: relative;
    top:30px;
    left: 20px;
  }
  #box2 {
    width: 300px;
    height: 300px;
    background-color: darkseagreen;
  }

image.png

在这个例子中,#box1 使用了position:relative相对定位,此时正常位置会根据left top向右移动了 20px,向下移动了 30px。但是没有脱离文档流,#box1 原来的占位(文档流中的位置)不会受到影响,#box2 仍然会按照文档流的顺序紧随其后展示绘制。

absolute 绝对定位

绝对定位(absolute)使得元素相对于最近的非 static 定位的祖先元素进行定位。如果没有这样的祖先元素,则相对于初始包含块(通常是浏览器窗口)进行定位。使用 topbottomleftright 属性可以精确控制元素的位置。

示例代码
    <div id="box1">Box 1</div>
    <div id="box2">Box 2</div>

对应的 CSS 代码:

#parent {
    position: relative;
    width: 500px;
    height: 500px;
    background-color: lightgray;
}

#box1 {
    width: 200px;
    height: 200px;
    background-color: green;
    position: absolute;
    top: 10px;
    left: 20px;
}

#box2 {
    width: 300px;
    height: 300px;
    background-color: blue;
}

image.png

在这个例子中,#box1 使用了 position: absolute;,因此它会相对于最近的非 static 定位的祖先元素 #parent 进行定位,如果找不到这样的祖先元素,那么它将相对于初始包含块(通常是浏览器的视口或 <body> 元素)进行定位。#box1 的位置被设置为距离 #parent 的顶部 10px 和左侧 20px。由于 #box1 离开了文档流,#box2 会直接占据 #box1 原来的文档流位置,首先展示#box2绘制。

sticky 粘性定位

  • 描述:粘性定位。
  • 行为:元素根据用户的滚动位置在相对定位和固定定位之间切换。当元素位于正常文档流中时,表现为相对定位;当用户滚动到特定位置时,元素变为固定定位。
示例代码
     body {
            margin: 0;
            font-family: Arial, sans-serif;
        }
        .section {
            height: 25vh; /* 每个部分的高度为视口的四分之一高度 */
            padding: 20px;
            box-sizing: border-box;
        }
        .section h2 { /* 绑定 section标签里面的h2标签*/
            position: sticky;
            top: 10px;
            background-color:skyblue;
            padding: 10px;
            margin: 0;
            border-bottom: 1px solid #ddd;
        }
        .section:nth-child(odd) {
            background-color:indianred; /*奇数部分为浅红色*/
        }

对应的 CSS 代码:

<div class="section">
        <h2>部分 1</h2>
        <p>这里是部分 1 的内容。</p>
    </div>
    <div class="section">
        <h2>部分 2</h2>
        <p>这里是部分 2 的内容。</p>
    </div>
    <div class="section">
        <h2>部分 3</h2>
        <p>这里是部分 3 的内容。</p>
    </div>
    <div class="section">
        <h2>部分 4</h2>
        <p>这里是部分 4 的内容。</p>
    </div>

image.png

在这个例子中:

  • .section:每个部分的高度设置为视口高度(height: 100vh;),以便用户可以滚动查看每个部分。padding 和 box-sizing 用于确保内容有足够的内边距。
  • .section h2:使用 position: sticky; 将标题固定在页面顶部。top: 0; 确保标题在滚动到顶部时固定住。background-colorpaddingmargin 和 border-bottom 用于美化标题。
  • .section:nth-child(odd) :奇数部分的背景颜色设置为浅红色,以便区分不同的部分。

fixed 固定定位

  • 描述:固定定位。
  • 行为:元素相对于浏览器窗口进行定位,不会随页面滚动而移动。使用 topbottomleft 和 right 属性可以精确控制元素的位置。
示例代码
    <div class="navbar">
        导航栏
    </div>
    <div class="content">
        <h1>欢迎来到我的网站</h1>
        <p>这里是主要内容。你可以向下滚动页面,看看导航栏是否保持在顶部。</p>
        <p>这里是主要内容。你可以向下滚动页面,看看导航栏是否保持在顶部。</p>
        <p>这里是主要内容。你可以向下滚动页面,看看导航栏是否保持在顶部。</p>
        <p>这里是主要内容。你可以向下滚动页面,看看导航栏是否保持在顶部。</p>
        <p>这里是主要内容。你可以向下滚动页面,看看导航栏是否保持在顶部。</p>
        <p>这里是主要内容。你可以向下滚动页面,看看导航栏是否保持在顶部。</p>
        <p>这里是主要内容。你可以向下滚动页面,看看导航栏是否保持在顶部。</p>
        <p>这里是主要内容。你可以向下滚动页面,看看导航栏是否保持在顶部。</p>
    </div>

对应的 CSS 代码:

     body {
            margin: 0;
            font-family: Arial, sans-serif;
        }
        .navbar {
            position: fixed;
            top: 10px;
            width: 100%;
            background-color: #333;
            color: white;
            padding: 10px 0;
            text-align: center;
        }
        .content {
            margin-top: 60px; /* 避免内容被固定导航栏遮挡 */
            padding: 20px;
        }

盒模型:

image.png

在这个例子中:

image.png

  • .navbar:使用 position: fixed; 将导航栏固定在页面顶部。top: 10px; 确保导航栏始终位于距顶部10px的位置,width: 100%; 使其占据整个一行。
  • .content:为了防止内容被固定导航栏遮挡,设置了 margin-top: 60px;,使内容从导航栏下方开始显示。

总结

  • 文档流:元素按照 HTML 文档的顺序从上至下、从左至右排列。每个元素在文档流中都有一个默认的位置。
  • static:适用于大多数普通布局,不需要特殊定位的情况。
  • 相对定位(relative :元素相对于其正常位置进行定位,不会改变其他元素的布局。
  • 绝对定位(absolute :元素相对于最近的非 static 定位的祖先元素进行定位,会离开文档流。
  • fixed:常用于创建导航栏、浮动按钮等需要固定在页面某个位置的元素。
  • sticky:常用于创建在滚动时固定在某个位置的导航栏或侧边栏。 理解这些概念对于前端开发人员来说非常重要,尤其是在进行复杂的布局设计时。希望本文能帮助你更好地理解和使用 position 属性。如果有更多问题或需要进一步的示例,请随时提问。