义CSS样式时,经常出现两个或更多样式规则应用在同一元素上的情况。此时CSS就会根据样式规则的权重,优先显示权重最高的样式。CSS优先级指的就是CSS样式规则的权重。在网页制作中,CSS为每个基础选择器都指定了不同的权重,方便我们添加样式代码。为了深入理解CSS优先级,我们通过一段示例代码进行分析。CSS样式代码如下:
p{ color:red;} /*标签样式*/
.blue{ color:green;} /*class样式*/
theader{ color:blue;} /*id样式*/
CSS样式代码对应的HTML结构为:
<p class="blue" id="header">
帮帮我,我到底显示什么颜色?
</p>
在上面的示例代码中,使用不同的选择器对同一个元素设置文本颜色,这时浏览器会根据CSS选择器的优先级规则解析CSS样式。为了便于判断元素的优先级,CSS为每一种基础选择器都分配了一个权重,我们可以通过虚拟数值的方式为这些基础选择器匹配权重。假设标签选择器具有权重为1.类选择器具有权重则为10,id选择器具有权重则为l00。这样id选择器“#header”就具有最大的优先级,因此文本显示为蓝色。
对于由多个基础选择器构成的复合选择器(并集选择器除外),其权重可以理解为这些基础选择器权重的叠加。例如,下面的CSS代码。
p strong{color:black} /*权重为:1+1*/
strong.blue{color:green;} /*权重为:1+10*/
.father strong{color:yellow} /*权重为:10+1*/
p.father strong{color:orange;} /*权重为:1+10+1*/
p.father .blue{color:gold;} /*权重为:1+10+10*/
theader strong{color:pink;} /*权重为:100+1*/
#header strong.blue{color:red;} /*权重为:100+1+10*/
对应的HTML结构为:
<p class="father" id="header">
<strong class="blue">文本的颜色</strong>
</p>
这时,CsS代码中的“#header strong.blue”选择器的权重最高,文本颜色将显示为红色。此外,在考虑权重时,我们还需要注意一些特殊的情况。
(1)继承样式的权重为0
在嵌套结构中、h不管父元素样式的权重多大,被子元素继承时,它的权重都为0,也就是说子元素定义的样式会覆盖继承来的样式。例如,下面的CSS样式代码。
strong{color:red;}
#header{color:green;}
CSS样式代码对应的HTML结构如下:
<p id="header" class="blue">
<strong>继承样式不如自己定义的权重大</strong>
</p>
在上面的代码中,虽然“#header”具有权重100,但被标签继承时权重为0。而“strong”选择器的权重虽然仅为1,但它大于继承样式的权重,所以页面中的文本显示为红色。
(2)行内样式优先
应用style属性的元素,其行内样式的权重非常高。换算为数值,我们可以理解为远大于100。因此行内样式拥有比上面提到的选择器都高的优先级。
(3)权重相同时,CSS的优先级遵循就近原则
也就是说,靠近元素的样式具有最大的优先级,或者说按照代码排列上下顺序,排在最下边的样式优先级最大。例如,下面为外部定义的CSS示例代码。
/*CSS文档,文件名为style_red.css*/
#header{color:red;} /*外部样式*/
对应的HTML结构代码如下:
<title>CSS优先级</title>
<link rel="stylesheet"href="style_red.css"type="text/css"/> /*引入外部
定义的CSS代码*/
<style type="text/css">
#header{color:gray;}
</style>
</head>
<body>
/*内嵌式样式*/
<p id="header">权重相同时,就近优先</p>
</body>
在上面的示例代码中,第2行代码通过外链式引入CSS样式,该样式设置文本样式显示为红色。第3~5行代码通过内嵌式引入CSS样式,该样式设置文本样式显示为灰色。
上面的页面被解析后,段落文本将显示为灰色,即内嵌式样式优先。这是因为内嵌样式比外链式样式更靠近HTML.元素。同样的道理,如果同时引用两个外部样式表,则排在下面的样式表具有较大的优先级。如果此时将内嵌样式更改为:
p{color:gray;} /*内嵌式样式*/
此时外链式的id选择器和嵌入式的标签选择器权重不同,“#header”的权重更高,文字将显示为外部样式定义的红色。
(4)CSS定义“limportant”命令,会被赋予最大的优先级
当CSS定义了“limportant”命令后,将不再考虑权重和位置关系,使用“limportant”的标签都具有最大优先级。例如,下面的示例代码。
#header{color:red!important;}
应用此样式的段落文本显示为红色,因为“limportant”命令的样式拥有最大的优先级。需要注意的是,“limportant”命令必须位于属性值和分号之间,否则无效。
复合选择器的权重为组成它的基础选择器权重的叠加,但是这种叠加并不是简单的数字之和。下面通过一个案例来具体说明,如例1所示。
例1 examplel1.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>复合选择器权重的叠加</title>
<style type="text/css">
.inner{text-decoration:line-through;}/*类选择器定义删除线,权重为10*/
div div div div div div div div div div div{text-decoration:underline;}
/*后代选择器定义下画线,权重为11个1的叠加*/
</style>
</head>
<body>
<div>
<div><div><div><div><div><div><div><div><div>
<div class="inner">文本的样式</div>
</div></div></div></div></div></div></div></div></div>
</div>
</body>
</html>
例1共使用了11对<div>标签,它们层层嵌套。第15行代码我们对最里层的<div>定义类名“inner”。第7、8行代码,使用类选择器和后代选择器分别定义最里层div的样式。此时浏览器中文本的样式到底如何显示呢?如果仅仅将基础选择器的权重相加,后代选择器(包含11层div)的权重为11,大于类选择器“.inner”的权重10,文本将添加下画线。
运行例1,效果如下所示。
在上图中,文本并没有像预期的那样添加下画线,而显示了类选择器“.inner”定义的删除线。可见,无论在外层添加多少个标签,复合选择器的权重无论为多少个<div>标签选择器的叠加,其权重都不会高于类选择器。同理,复合选择器的权重无论为多少个类选择器和标签选择器的叠加,其权重都不会高于i选择器。
前在项目的过程中遇到了一个问题,某个 div 希望始终显示在最上面,而在之后的元素都显示在它之下,当时设置了 z-index 也没有效果,不知道什么原因,因此找了一下 CSS 相关资料,解决了这个问题的同时,也学习了很多知识,特此和大家分享一下。
屏幕是一个二维平面,然而 HTML 元素却是排列在三维坐标系中, x 为水平方向, y 为垂直方向, z为屏幕由内向外方向,我们在看屏幕的时候是沿着 z 轴方向从外向内的。由此,元素在用户视角就形成了层叠的关系,某个元素可能覆盖了其他元素也可能被其他元素覆盖;
这里有几个重要的概念:层叠上下文 (堆叠上下文, Stacking Context)、层叠等级 (层叠水平, Stacking Level)、层叠顺序 (层叠次序, 堆叠顺序, Stacking Order)、z-index、BFC(块级格式化上下文,Block Formatting Context),这些概念共同决定了你看到元素的位置,下面我们就围绕着这几个概念来一起学习一下。
声明:
1. 层叠上下文 (Stacking Context)
层叠上下文 (堆叠上下文, Stacking Context),是 HTML 中一个三维的概念。在 CSS2.1 规范中,每个元素的位置是三维的,当元素发生层叠,这时它可能覆盖了其他元素或者被其他元素覆盖;排在 z 轴越靠上的位置,距离屏幕观察者越近。
文章 <关于z-index 那些你不知道的事> 有一个很好的比喻,这里引用一下;
可以想象一张桌子,上面有一堆物品,这张桌子就代表着一个层叠上下文。如果在第一张桌子旁还有第二张桌子,那第二张桌子就代表着另一个层叠上下文。现在想象在第一张桌子上有四个小方块,他们都直接放在桌子上。在这四个小方块之上有一片玻璃,而在玻璃片上有一盘水果。这些方块、玻璃片、水果盘,各自都代表着层叠上下文中一个不同的层叠层,而这个层叠上下文就是桌子。
每一个网页都像一个房间,这个房间就是 <html></html>,其他层叠上下文就像这个房间里的桌子,HTML 标签中的一切都被置于这个房间中。
当给一个元素的 position 值赋为 fixed 或 sticky 值时,你就创建了一个新的层叠上下文,其中有着独立于页面上其他层叠上下文和层叠层的层叠层,这就相当于你把另一张桌子带到了房间里。
层叠上下文 1 (Stacking Context 1)是由文档根元素形成的, 层叠上下文 2 和 3 (Stacking Context 2, 3) 都是层叠上下文 1 (Stacking Context 1) 上的层叠层。他们各自也都形成了新的层叠上下文,其中包含着新的层叠上下文。
在层叠上下文中,其子元素按照上面解释的规则进行层叠。形成层叠上下文的方法有:
总结:
2. 层叠等级 (Stacking Level)
层叠等级 (层叠水平, Stacking Level) 决定了在同一个层叠上下文中,元素在 z 轴上的显示的顺序;
对于普通元素的层叠水平探讨只局限于在当前层叠上下文中:
层叠上下文本身是一个强力的「层叠结界」,普通的元素水平是无法突破这个结界和结界外的元素去较量层叠水平的。
— CSS 世界
另外,层叠等级并不一定由 z-index 决定,只有定位元素的层叠等级才由 z-index 决定,其他类型元素的层叠等级由层叠顺序、他们在 HTML 中出现的顺序、他们的祖先元素的层叠等级一同决定,详细的规则见下面层叠顺序的介绍。
3. z-index
在 CSS 2.1 中, 所有的盒模型元素都处于三维坐标系中。除了我们常用的横坐标和纵坐标, 盒模型元素还可以沿着「z 轴」层叠摆放,当他们相互覆盖时,z 轴顺序就变得十分重要。
-- CSS 2.1 Section 9.9.1 - Layered presentation
z-index 只适用于定位的元素,对非定位元素无效,它可以被设置为正整数、负整数、 0、 auto,如果一个定位元素没有设置 z-index,那么默认为 auto;
元素的 z-index 值只在同一个层叠上下文中有意义。如果父级层叠上下文的层叠等级低于另一个层叠上下文的,那么它 z-index 设的再高也没用。所以如果你遇到 z-index 值设了很大,但是不起作用的话,就去看看它的父级层叠上下文是否被其他层叠上下文盖住了。
4. 层叠顺序 (Stacking Order)
层叠顺序 (层叠次序, 堆叠顺序, Stacking Order) 描述的是元素在同一个层叠上下文中的顺序规则(之前的层叠上下文和层叠等级是概念),从层叠的底部开始,共有七种层叠顺序:
第 7 级顺序的元素会显示在之前顺序元素的上方,也就是看起来覆盖了更低级的元素:
除层叠顺序优先级规则之外,还有一条后来居上规则:同一个层叠顺序的元素按照在 HTML 里出现的顺序依次层叠。这两个规则共同决定浏览器元素在文档中是如何层叠的。
5. 文档流 (Document Flow)
5.1 常规流 (Normal flow)
5.2 浮动 (Floats)
5.3 绝对定位 (Absolute positioning)
6. BFC (Block Formatting Context)
6.1 什么是 BFC
BFC (Block Formatting Context) 块级格式化上下文,是用于布局块级盒子的一块渲染区域,相对应的还有 IFC(Inline Formatting Context)内联格式化上下文,不是本文重点,读者可以自行查阅相关知识。
BFC 是 Web 页面 CSS 视觉渲染的一部分,用于决定块盒子的布局及浮动相互影响范围的一个区域。
— MDN - 块格式化上下文
一个 BFC 的范围包含创建该上下文元素的所有子元素,但不包括创建了新 BFC 的子元素的内部元素。这从另一方角度说明,一个元素不能同时存在于两个 BFC 中。因为如果一个元素能够同时处于两个 BFC 中,那么就意味着这个元素能与两个 BFC 中的元素发生作用,就违反了 BFC 的隔离作用。
触发 BFC 的方式有:
注意: display:table 也可以生成 BFC 的原因在于 Table 会默认生成一个匿名的 table-cell,是这个匿名的 table-cell 生成了 BFC。
6.2 用法
1. 阻止相邻元素的 margin 合并
属于同一个 BFC 的两个相邻块级子元素的上下 margin 会发生重叠,(设置 writing-mode:tb-rl时,水平 margin 会发生重叠)。所以当两个相邻块级子元素分属于不同的 BFC 时可以阻止 margin 重叠。可以给任一个相邻块级盒子的外面包一个 div,通过改变此 div 的属性使两个原盒子分属于两个不同的 BFC,以此来阻止 margin 重叠。
代码和预览参见:Codepen - 使用BFC阻止margin合并:https://codepen.io/SHERlocked93/pen/eVOevN
2. 阻止元素被浮动元素覆盖
一个正常文档流的块级元素可能被一个 float 元素覆盖,挤占正常文档流,因此可以设置一个元素的 float、 display、 position 值等方式触发 BFC,以阻止被浮动盒子覆盖。
代码和预览参见:Codepen - 使用BFC阻止元素被浮动元素覆盖:https://codepen.io/SHERlocked93/pen/pazdzB
3. 包含浮动元素
通过改变包含浮动子元素的父盒子的属性值,触发 BFC,以此来包含子元素的浮动盒子。
代码和预览参见:Codepen - 使用BFC包含浮动元素:https://codepen.io/SHERlocked93/pen/OQLOqG
7. 实战
下面一起来看几个例子实战一下,帮助理解。
7.1 普通情况
三个 relative 定位的 div 块中各有 absolute 的不同颜色的 span.red、 span.green、 span.blue,它们都设置了 position:absolute;
代码和预览参见:Codepen - 普通情况:https://codepen.io/SHERlocked93/pen/aaPord
那么当没有元素包含 z-index 属性时,这个例子中的元素按照如下顺序层叠(从底到顶顺序):
红绿蓝都属于 z-index 为 auto 的定位元素,因此按照 7 层层叠顺序规则来说同属于层叠顺序第 6 级,所以按 HTML 中的出现顺序层叠:红->绿->蓝
7.2 在相同层叠上下文的父元素内的情况
红绿位于一个 div.first-box 下,蓝位于 div.second-box 下,红绿蓝都设置了 position:absolute, first-box 与 second-box 都设置了 position:relative;
代码和预览参见:Codepen - 父元素不同但都位于根元素下:https://codepen.io/SHERlocked93/pen/RYENBw
这个例子中,红蓝绿元素的父元素 first-box 与 second-box 都没有生成新的层叠上下文,都属于根层叠上下文中的元素,且都是层叠顺序第 6 级,所以按 HTML 中的出现顺序层叠:红->绿->蓝
7.3 给子元素增加 z-index
红绿位于一个 div.first-box 下,蓝黄位于 div.second-box 下,红绿蓝都设置了 position:absolute,如果这时给绿加一个属性 z-index:1,那么此时 .green 位于最上面;
如果再在 .second-box 下 .green 后加一个绝对定位的 span.gold,设置 z-index:-1,那么它将位于红绿蓝的下面;
代码和预览参见:Codepen - 设置了z-index:https://codepen.io/SHERlocked93/pen/gdZOrK
这个例子中,红蓝绿黄元素的父元素中都没有生成新的层叠上下文,都属于根层叠上下文中的元素
所以这个例子中的从底到高显示的顺序就是:黄->红->蓝->绿
7.4 在不同层叠上下文的父元素内的情况
红绿位于一个 div.first-box 下,蓝位于 div.second-box 下,红绿蓝都设置了 position:absolute,如果 first-box 的 z-index 设置的比 second-box 的大,那么此时无论蓝的 z-index 设置的多大 z-index:999,蓝都位于红绿的下面;如果我们只更改红绿的 z-index 值,由于这两个元素都在父元素 first-box 产生的层叠上下文中,此时谁的 z-index 值大,谁在上面;
代码和预览参见:Codepen - 不同层叠上下文的父元素:https://codepen.io/SHERlocked93/pen/gdZbOJ
这个例子中,红绿蓝都属于设置了 z-index 的定位元素,不过他们的父元素创建了新的层叠上下文;
所以这个例子中从低到到显示的顺序:蓝->红->绿
(我遇到的的情况就属于这个例子类似情形)
7.5 给子元素设置 opacity
红绿位于 div.first-box 下,蓝位于 div.second-box 下,红绿蓝都设置了 position:absolute,绿设置了 z-index:1,那么此时绿位于红蓝的最上面;
如果此时给 first-box 设置 opacity:.99,这时无论红绿的 z-index 设置的多大 z-index:999,蓝都位于红绿的上面;
如果再在 .second-box 下 .green 后加一个 span.gold,设置 z-index:-1,那么它将位于红绿蓝的下面;
代码和预览参见:Codepen - opacity的影响:https://codepen.io/SHERlocked93/pen/GXPRWB
之前已经介绍了,设置 opacity 也可以形成层叠上下文,因此:
所以这个例子中从低到到显示的顺序:黄->红->绿->蓝
关注微信公众号:安徽思恒信息科技有限公司,了解更多技术内容……
演示地址: https://sortablejs.github.io/Sortable/
Github:https://github.com/SortableJS/Sortable
SortableJS是一款用于在现代浏览器和触摸设备上的拖拽插件,不需要jQuery,但支持jQuery,支持Meteor,AngularJS,React,Polymer,Vue,Knockout和任何CSS库,例如Bootstrap。
通过npm
npm install sortablejs --save
通过bower
bower install --save sortablejs
<ul id="items"> <li>item 1</li> <li>item 2</li> <li>item 3</li> </ul> var el = document.getElementById('items'); var sortable = Sortable.create(el);
备注:不仅仅是可以使用ul/li,比如div等
根据官网文档简单介绍下:
string:命名,个人建议用元素id就行,用处是为了设置可以拖放容器时使用 array:[name,pull,put] name:同string的方法, pull:pull用来定义从这个列表容器移动出去的设置,true/false/'clone'/function true:列表容器内的列表单元可以被移出; false:列表容器内的列表单元不可以被移出; 'clone':列表单元移出,移动的为该元素的副本; function:用来进行pull的函数判断,可以进行复杂逻辑,在函数中return false/true来判断是否移出; put:put用来定义往这个列表容器放置列表单元的的设置,true/false/['foo','bar']/function true:列表容器可以从其他列表容器内放入列表单元; false:与true相反; ['foo','bar']:这个可以是一个字符串或者是字符串的数组,代表的是group配置项里定义的name值; function:用来进行put的函数判断,可以进行复杂逻辑,在函数中return false/true来判断是否放入;
move 事件对象:
获取或设置选项
对于集合中的每个元素,通过测试元素本身并遍历DOM树中的祖先来获取与选择器匹配的第一个元素
序列化可排序的列表单元的data-id(可通过配置项中dataIdAttr修改)放入一个数组,并返回这个数组中
通过自定义列表单元的data-id的数组对列表单元进行排序
保存当前排序
完全销毁可拖拽功能
SortableJS在某些场景下非常有用,它是一个很好用的前端拖拽解决方案,合理的使用将会带来某些意想不到的惊喜,比如让某些不可拖拽模态框,变成可拖拽模态(没有实践过),喜欢折腾的小伙伴可以收藏学习了,本人翻译功底实在有限,如果对你有帮助,请点个关注吧!谢谢!
*请认真填写需求信息,我们会在24小时内与您取得联系。