我真的懂position了吗?

我真的懂position了吗?

前言

近期笔者在面试的时候,突然注意到一个问题,前端的知识体系比较驳杂,没有说特别系统性的学习,就拿个我自己举个例子,学习前端知识一开始可能从视频->文档->博客,这样其实很多东西被我们遗漏。很多知识其实是零零散散的补充。这样就导致一些概念会缺失。

在我近期的面试中我就遇到一个几个问题

  • relative根据什么进行定位的?

  • absolute根据什么进行定位的?

    如果祖先元素没有relative根据什么定位?

  • fixed根据什么定位?

这几个题目其实很简单,大家都知道根据什么进行定位,但是如果描述起来可能不尽人意。

后来我进行了了解才知道了一些底层的知识,仿佛打开了新世界,原来还有这么多概念我们不知道的

例如以下概念,我做前端开发两三年了还是第一次听到

  • 包含块、最初包含块

  • position是根据最近祖先元素的relative进行定位的吗? 这个答案只答对了部分

    标准答案是: 根据最近非static的块级祖先元素但又有特殊情况(下面会讲解到),是不是很震惊

  • 粘性布局sticky 有了解吗,这个属性一直很容易被忽略掉

几个让我错不及防的面试题

以下几个问题确实是笔者近期,面试中遇到的问题,平时很难注意到的几个细节。拿出来给大家分享一下

relative根据什么进行定位的?

relative(我的理解):是根据自身原来的位置进行偏移

relative(引用自mdn文档): 该关键字下,元素先放置在未添加定位时的位置,再在不改变页面布局的前提下调整元素位置(因此会在此元素未添加定位时所在位置留下空白)。position:relative 对 table-*-group, table-row, table-column, table-cell, table-caption 元素无效。

absolute根据什么进行定位的?

absolute:根据最近非Static定位的祖先元素进行偏移,如果没有则根据最初包含块(又或者理解为html元素)进行偏移

我原来一直以为absolute是以relative进行定位了,没想到是非Static

来看一个例子:

如果是fixed的盒子absolute也会根据它进行定位吗? 如果是的情况,absolute岂不是也有fixed的效果

代码如下:

css 复制代码
    <div class="box1">
        <div class="box2"></div>
    </div>
   .box1 {
        position: fixed;
        background: red;
        width: 100px;
        height: 100px;
        left: 50px;
    }
    .box2 {
        position: absolute;
        background: yellow;
        width: 100px;
        height: 100px;
        left: 50px;
    }

答案是肯定的,当absolute根据fixed去定位,同样也有固定的效果,因为absolute要根据fixed元素进行偏移

fixed根据什么定位?

fixed:是根据当前的视图窗口(即屏幕视口(viewport))进行定位

div的高度会受到font-size的影响吗?

答案是:不会的,因为指定了高度了,如果heightauto,那么就会影响

auto的情况

div的高度会受到line-height的影响吗?

line-height与font-size一样,当div设置固定的高度的时候,就是固定多大

什么是包含块?

是不是第一次听到这个概念,做前端两年了第一次听到这个词

那么什么是包含块呢,引用MDN的概念

包含块就是这个元素最近的祖先块元素的内容区域,但也不是总是这样。

简单理解:通常的情况下,包含块就是元素父元素的内容区,但是有的情况下不是。这句话可以这样子理解

那么什么情况下不是呢?

当我们使用position的时候包含块可能会发生改变,下面分为四种情况

  • positon值为static、relative、sticky的元素,包含块可能由它的最近的祖先块元素

    这个情况可以直接理解为,包含块就是当前元素的父元素内容区域(这里需要注意的是父元素必须是块元素)

    例如:以下代码,显然label的高度和宽度分别是250px50px

    css 复制代码
        <div class="box">
            <p class="label">这是一个p标签</p>
        </div>
        .box {
            width: 500px;
            background: deepskyblue;
            height: 100px;
        }
    
        .label {
            width: 50%;
            height: 50%;
            background: red;
        }

    结果也如我们所预料的。那么如果设置box的display为inline呢。

    css 复制代码
        body {
            height: 1000px;
        }
        .box {
            width: 500px;
            background: deepskyblue;
            height: 100px;
            display: inline;
        }
        .label {
            width: 50%;
            height: 50%;
            background: red;
        }

    这里因为把box设置为了inline此时已经不是块元素,所以label的宽度会基于祖先的块元素label标签网上找box不是块元素,继续找body是块元素,那么宽度就基于body的50%进行计算,最后得出我们的结果。

  • positon值为absolute,包含块就是由它的最近的 position 的值不是 static,这个上面已经解释过了

  • position值为fixed,在连续媒体的情况下 (continuous media) 包含块是 viewport ,在分页媒体 (paged media) 下的情况下包含块是分页区域 (page area),简单理解当前视图窗口

  • 如果 position 属性是absolutefixed包含块也可能是由满足以下条件的最近父级元素的内边距区的边缘组成的:

    1. transformperspective 的值不是 none
    2. will-change 的值是 transformperspective
    3. filter 的值不是 nonewill-change 的值是 filter(只在 Firefox 下生效)。
    4. contain 的值是 paint(例如:contain: paint;
    5. backdrop-filter 的值不是 none(例如:backdrop-filter: blur(10px);

    这个可以理解为,如果说当前元素position:absolutefixed的时候,那么他的父元素,包含了1-5其中的任意一条,那么这个元素就会根据这个父元素进行偏移

    例如:如下结构,按理说应该是针对box进行绝对定位,但是因为box1设置了transform属性,所以对根据box1进行绝对定位

    css 复制代码
        <div class="box">
            <div class="box1">
                <div class="box2"></div>
            </div>
        </div>
       .box {
            width: 100%;
            height: 100%;
            position: relative;
        }
    
        .box1 {
            background: red;
            width: 100px;
            height: 100px;
            left: 50px;
            transform: rotate(0deg);
            padding-top: 100px;
        }
    
        .box2 {
            position: absolute;
            background: yellow;
            width: 100px;
            height: 100px;
            left: 50px;
            top: 0px;
        }

    结果如下:从图中可以看到,box2并没有根据boxrelative进行绝对定位,而是根据box1

粘性布局 postion:sticky

粘性布局 position: sticky

上次在面试的时候,被问到这个问题,突然蒙了,粘性布局有这个东西吗?

在面试官的提醒下我才记起来sticky的属性,这个属性在很容易被忽略掉,对于position,我们常用的属性主要有:relative、absolute、fixed、static,那么接下就来认识一下sticky

position: sticky 粘性定位是相对定位和固定定位的结合体,这句话比较拗口,可以这样理解,当我们设置条件不满足的时候,它是相对定位,当条件满足时它是固定定位

应用场景通常是用来制作移动端的吸顶效果

什么是吸顶效果?

例如:以下,当我们内容超过屏幕的时候,向下滚动,希望顶部的分类栏,无论滚动到哪里都可以看到的,那么我们通常会采取两种解决方式

  • fixed 这个可能是我们最常用
  • 另外一种方式就是sticky

那么接下我们来看一下fixed方式实现的效果:

css 复制代码
    .tabs {
        width: 100%;
        display: flex;
        height: 30px;
        position: fixed;
        top: 40px; /* 这里的top值是顶部标题的高度 */
    }

那么如果是stcky的效果呢

css 复制代码
    .tabs {
        width: 100%;
        display: flex;
        height: 30px;
        position: sticky;
        top: 40px;
    }

显示sticky也可以实现一样的效果,这不是跟fixed一样吗?

那我要使用fixed,干嘛还要去了解sticky

来看看这种情况

如果是采用fixed,那么此时我的元素可能会被覆盖掉,如果不想被覆盖,那么也只能设置fixed属性

如果设置完,此时这个内容就已经变成固定定位了无论什么时候都会固定在顶部

效果如下

如果是sticky的话显然,还是可以满足

使用sticky的时候需要注意:

  • sticky仅能在父元素中生效
  • 父元素不能为
  • 必须执行top、bottom、left、right其中任意一个值,sticky才会生效,不然就是相对定位
  • 低版本IE不兼容

往前文章推荐

2023年金九银十面经,假的今年没有金九银十

关于我的人生(假如我工作13年就能得到3w个花西币)

相关推荐
谈谈叭14 分钟前
Javascript中的深浅拷贝以及实现方法
开发语言·javascript·ecmascript
优雅永不过时·37 分钟前
Three.js 原生 实现 react-three-fiber drei 的 磨砂反射的效果
前端·javascript·react.js·webgl·threejs·three
爱编程的鱼1 小时前
javascript用来干嘛的?赋予网站灵魂的语言
开发语言·javascript·ecmascript
神夜大侠3 小时前
VUE 实现公告无缝循环滚动
前端·javascript·vue.js
明辉光焱3 小时前
【Electron】Electron Forge如何支持Element plus?
前端·javascript·vue.js·electron·node.js
柯南二号4 小时前
HarmonyOS ArkTS 下拉列表组件
前端·javascript·数据库·harmonyos·arkts
wyy72934 小时前
v-html 富文本中图片使用element-ui image-viewer组件实现预览,并且阻止滚动条
前端·ui·html
前端郭德纲4 小时前
ES6的Iterator 和 for...of 循环
前端·ecmascript·es6
究极无敌暴龙战神X4 小时前
前端学习之ES6+
开发语言·javascript·ecmascript
王解4 小时前
【模块化大作战】Webpack如何搞定CommonJS与ES6混战(3)
前端·webpack·es6