前端重构范式之 position

栏目: Html · 发布时间: 5年前

内容简介:本文旨在让你更深入地了解在此之前先让我们来看看 learncss 中文文档中对以上是较为官方的定义,你可以从中获取到关于

本文旨在让你更深入地了解 position ,并为你提供一套使用 position 的范式,为你使用 position 提供一点建议和参考。

在此之前先让我们来看看 learncss 中文文档中对 position 的定义

描述
absolute 生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位。元素的位置通过 “left”, “top”, “right” 以及 “bottom” 属性进行规定。
fixed 生成绝对定位的元素,相对于浏览器窗口进行定位。元素的位置通过 “left”, “top”, “right” 以及 “bottom” 属性进行规定。
relative 生成相对定位的元素,相对于其正常位置进行定位。因此,”left:20” 会向元素的 LEFT 位置添加 20 像素。
static 默认值。没有定位,元素出现在正常的流中(忽略 top, bottom, left, right 或者 z-index 声明)。
inherit 规定应该从父元素继承 position 属性的值。

以上是较为官方的定义,你可以从中获取到关于 position 的一些基本操作,接下来让我们试图从另一个角度来理解 position .

position 是一种描述物体相对位置的艺术,它的核心是「参考坐标系」的选择

正如我们在现实生活中看到的那样,我们需要使用各种不同的「参考坐标系」,来更方便准确地描述我们身边各种物体的相对位置。因为,我们已经知道,如果单纯依靠一个坐标系来描述这个世界上的各个位置,这个世界将变得异常复杂。我们需要使用不同的坐标系,来帮住我们简化对位置的描述。

在我们的网页布局中也是一样,我们不能只采用一个坐标系来对网页中的元素进行定位,那将使得我们的网页变得异常复杂且不易维护。我们需要多个不同的坐标系,来帮助我们对网页进行更好地布局。css中的 position ,就是我们俗称的「定位」,就是定义了这么一套规则,使得我们可以应用不同的坐标系,来对页面中的元素进行更好地布局和管理。

反应在具体的规则当中,就是我们熟知的 static , relative , absolute , fixed 。而它们最本质的区别就在于「参考坐标系」的不同。其他的一系列问题,例如典型的元素层级,都可以归结为 position 所带来的副作用。

到这里,你或许对 position 有了一个不一样的认识,接下来可以尝试着思考以下几个问题

position
position

不知道?没关系,或许以下的文章能够给你一点提示

副作用

首先我们需要讨论的是 position 的副作用,原因很简单,你手中有一个锤子,你总得知道这个锤子能干什么,不能干什么。我们只有像如来佛祖了解悟空那样了解 position ,才能发挥出悟空( position )的真正威力!

要分析 position 的副作用,我们或许可以采用这样的思路:

以下的组件均指开启了 position 定位的元素,这里把它称为组件

  1. 把该组件以及内部的元素作为一个整体,分析 它对外界 或者 外界对它 有什么影响。简称对外的影响
  2. 单独分析该组件,不考虑对外的影响,分析该 position 属性对元素内部的元素会带来什么影响。简称对内的影响
  3. 除了单独分析每个定位属性的副作用,我们还需要考虑不同的定位属性之间的 组合 会带来什么样的副作用,例如最为典型的 relativeabsolute

顺着这个思路,接下来我们来思考不同的 position 属性都会带来什么影响或副作用

副作用 absoluterelative

relativeabsolute 是我们再熟悉不过的一对欢喜冤家,它们两个经常是成对出现,产生的副作用也更多地来自于它们之间的组合。因此在这里将它们放在一起分析。

特性与副作用往往是相伴而生的。我们先来回顾一下,这两个属性各有什么特性?

position:absolute 元素具备的特性如下:

inline-block

鉴于本人的经验限制,下面的副作用例子展示的也只是其中的一部分,如有更好的补充,欢迎在下方评论区中与大家一起分享

position:relative 元素具备的特性如下:

relative
z-index

深度 relative

如果我们单独分析 absolute 的副作用,我们会把它简单地归结为脱离文档流,从而导致两个最为明显的副作用:改变布局和覆盖。

但是我认为这属于它本身具备的特性,并不是它的副作用。我觉得在现实应用中真正存在的副作用在于 relativeabsolute 的共同应用所造成的问题,在这里我把它称作「深度 relative 」。

所谓的「深度 relative 」,指的是 relative 包裹的组件处于较深的层级,也就是被包裹的比较深,导致其中的 absolute 组件要想不被其他元素覆盖,需要一级一级地往f父元素设置 z-index 或者排查 overflow 属性。这个问题最关键的核心就是 relative 组件层级太深。

这里讲得可能有点抽象,让我们一起来看一个例子:

前端重构范式之 position

这是我在实际项目开发中遇到的一个典型的例子。简单来讲,就是点击重选按钮,在指定的位置跳出图标选择框,并且在窗口滚动时依然有效。具体效果如下图所示:

前端重构范式之 position

就是这么一个简单的例子,当然以上是已经实现好的效果。如果你没有遇到过类似的问题,你会觉得这个问题很简单,使用 relativeabsolute 就能轻松解决。但是,在这里先卖个关子,以上的效果是使用 fixed 实现的。

我们首先使用我们典型的 relativeabsolute 来实现以上的效果,我们可以得到如下的效果:

前端重构范式之 position

首先你会发现一个最为明显的问题,就是图标选择框被其他元素盖住了,这个时候的原因就很多样了,或许是因为它所在的祖先元素的元素层级没有人家高,又或许是因为祖先元素设置了 overflow:hidden 等等。这个时候如果我们依然要坚持使用 relativeabsolute 的解决方案,那我们通常会采取的解决方案就是,一级一级的网上排查 overflow:hidden 又或者是设置 z-index ,直到解决问题为止。

z-index

说到 z-index ,这里可以简单下使用方法。它仅在 positon 属性不为 static 时起作用。从 position 从基础可以了解到 absolutefixed 会让元素脱离文档流,这两个修饰的元素默认层级自然比文档流的要高,然而 relative 则不会脱离文档流,但当它设置了 TRBL 时它也会覆盖文档流,其默认层级自然也是比后者要高的, 脱离文档流和层级的概念不能混淆

同级原则

所谓同级,顾名思义,也就是同级间层级的比较,一个元素 position 不为 static 后,如果不给它的 z-index 设定值,默认为0,由下图可以看到,A 元素设定了 z-index 为0,B元素未设定,E 元素设定了 z-index 为负数,按照顺序 B 覆盖住了 A,而E则被A盖住。往后则是 z-index 大的把小的覆盖。

前端重构范式之 position

在此仅展示结构,css 代码则省去。

<divid="1"style="position: absolute;z-index: 0">A</div>
<divid="2"style="position: absolute">B</div>
<divid="3"style="position: absolute;z-index: 1">C</div>
<divid="4"style="position: absolute;z-index: 2">D</div>
<divid="5"style="position: absolute;z-index: -1">E</div>

多级原则

看到这个标题,你可能会问,这是啥意思?其实很简单,它的意思是,要比较的元素不再是简单的同级概念,而是其中一个或两者都有祖先元素。看看下面这个代码:

<divid="1"style="position:relative;z-index:2;">
  <divid="1-1"style="position:relative;z-index:1;">A</div>
</div>

<divid="2"style="position:relative;z-index:1;">
  <divid="2-1"style="position:relative;z-index:999;">B</div>
</div>

效果图:

前端重构范式之 position

可见,A、B父元素的层级影响了相应的子元素的层级,就算 B 的 z-index 设的再大,它的父元素的 z-index 总是小于 A 的父元素的 z-index 值,这时候不论 A 的 z-index 怎么变化,元素 A 就会像图中一样一直压着 B,这就是从父原则。不过这里要划一下重点,这里的父元素不一定要同级,换句话说,两个元素间的层级比较,是 相应的的同级祖先元素各自往下找到第一个 position 不为 static 的的两个元素之间的比较 。举个栗子,结构改成下面这个结构,实现效果是一样的。

<divid="1"style="position:relative;z-index:2;">
  <divid="1-1"style="position:relative;z-index:1;">A</div>
</div>

<div>
  <divid="2"style="position:relative;z-index:1;">
  	<divid="2-1"style="position:relative;z-index:999;">B</div>
  </div>
</div>

以上讲了这么多,你或许觉得怎么这么繁琐,要考虑这儿考虑那儿的,也会发现即使你用这种方法达到了你想要的效果,它也并不能从根本上解决问题。我一个简单的小组件,你却需要我去影响那么多父级元素,谁知道会造成什么意想之外的情况。除了这个,设置过多的 z-index 会导致页面层级管理的混乱,使得页面很难管理,所有有一个原则,要么对 z-index 做明文的规定,要么就少用层级过深的 z-index

我这里有一种较好的解决方案,就是「 fixed 组件」。如果你有更好的解决方案,欢迎在下方评论区中进行分享。

fixed组件

我们都知道当元素设置了 position:fixed 之后,该元素将具备以下的特性:

  1. 永远相对于浏览器窗口进行定位
  2. 固定在浏览器窗口的某个位置,不随滚动条滚动
  3. 脱离文档流

以上是我们众所周知的一些特性,其实根据以上的特性,我们还可以推出以下这些特性:

  1. 单独使用 fixed 属性,不需要再开启父元素的定位,使得,减少了很多的z-index属性的设置

在下面的例子中,我们只对「图标组件」设置了 position:fixed 定位,页面中的其他大部分都是 position:static 组件,因此可以很轻松的解决原来的覆盖问题,也不会影响其他布局,更不会造成 z-index 管理混乱的问题。

前端重构范式之 position

  1. 使用js控制 fixed 组件的 margin ,我们可以实现, fixed组件 相对于父元素进行定位

通常我们在应用 fixed 组件的时候,都要解决 fixed 组件的滚动问题。通常 fixed 组件不会随着滚动条的滚动而滚动,但是我们拥有强大的js,我们可以通过为 fixed 组件设置一个固定的 margin-top ,然后通过js动态的控制这个值,使得它可以相对父元素进行滚动。因为我们都知道, margin 属性调节的是 box 之间的距离, fixed 组件脱了文档流,但它依然是一个box,因此我们可以使用margin来调节 fixed 组件与父元素之间的相对位置。

就拿上面的例子而言,具体代码如下所示:

前端重构范式之 position

前端重构范式之 position

副作用 fixed

fixed 失效

在固定定位元素的父元素上应用transform属性,固定定位的元素会相对于父元素来定位

具体可参考以下这篇博文,简单来说就是 transform 属性会对 fixed 组件造成影响

Eric’s Archived Thoughts: Un-fixing Fixed Elements with CSS Transforms

范式

讲了这个多关于 position 的副作用,我想到这里你或许也早已经有了一套自己的范式,其实里面的很多细节我们都已经在前面提到过。在这里我将分享一套属于我自己的 position 范式,学才疏浅,请不要见怪

  1. 相对于具体元素的小组件可以采用 relative + absolute 或者「 fixed 组件」的解决方案。如果组件层级较深,推荐使用「 fixed 组件」的方式来进行定位;具体可以参照上面提到过的图标选择框的例子。
  2. 相对于浏览器窗口固定的小组件,推荐是用 fixed 定位,例如右下角的小弹窗,固定的底部导航
  3. 要尽量减少 z-index 的嵌套使用
  4. 在使用 fixed 定位时,要留意 transform 属性对它的影响

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Two Scoops of Django

Two Scoops of Django

Daniel Greenfeld、Audrey M. Roy / CreateSpace Independent Publishing Platform / 2013-4-16 / USD 29.95

Two Scoops of Django: Best Practices For Django 1.5 is chock-full of material that will help you with your Django projects. We'll introduce you to various tips, tricks, patterns, code snippets, and......一起来看看 《Two Scoops of Django》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

随机密码生成器
随机密码生成器

多种字符组合密码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具