Sass 管理复杂的 z-index
z-index
本身就是一个棘手的事情,在一个复杂的布局中管理 z-index
的顺序(层级)更是困难。不同的 层叠顺序和内容,要跟踪他们的数字增加是很难的事情——而且他们来自CSS文件,忘了他吧!因为 z-index
可以造就一个UI元素可见或不可见,使您的网站的用户界面工作秩序是很微妙的。
因为 z-index
值跟上下文有关系,一旦你开始使用它,它可以很容易为其他元素先显示(如果元素需要)。在网站上查找 z-index: 99999
规则,它并少见,但使用臭名昭著的99999实属无耐之举。它经常被误用,认为让元素可以高于一切元素,但 z-index
并不总是那么简单。它也不是完全可扩展:你有什么东西是要放在最顶上的?
另一种策略是 两位数递增z-index
的值,让你有足够的空间给其他元素插入值,但并没有解决如何跟踪 z-index
值的问题,当你想在他们之间添加值时,它不能很好的扩展。
每个实例提出了一个问题:
- 为什么这个元素有这样的
z-index
值?所有其他元素上下文关系是什么? - 有顺序的上下文中插入
z-index
合适?如果我增加一项,哪个会受影响? - 如果添加一个元素的层叠顺序,其中
z-index
的值我必须增加?
使用Sass管理顺序
使用Sass的列表来控制上述所有因素是非常容易的。让我们以 Behance 主页做为一个例子:
我们需要管理的顺序包括项目遮罩层、过滤器栏、位置搜索弹出窗、下拉菜单和导航。按这个顺序,从下到上。我们可以创建一个Sass的列表,如下:
$elements: project-covers, sorting-bar, modals, navigation;
在这个列表中,我们希望我们的元素的出现,从低到高。数组的顺序表示元素的z-index
值。我们使用Sass的index()
函数将z-index
的值分配给每个元素。
例如:
.project-cover {
z-index: index($elements, project-covers);
}
这将输出:
.project-cover {
z-index: 1;
}
这是因为project-cover
是列表中的第一个元素,他的索引值是1,z-index
顺序中最低的元素。让我们用Sass给列表中其他元素指定z-index
值:
.sorting-bar {
z-index: index($elements, sorting-bar);
}
.modal {
z-index: index($elements, modals);
}
.navigation {
z-index: index($elements, navigation);
}
现在编译出来的CSS看起来像这样:
.project-cover {
z-index: 1;
}
.sorting-bar {
z-index: 2;
}
.modal {
z-index: 3;
}
.navigation {
z-index: 4;
}
现在你可以将类名应用到相应的元素上。但是,如果我们想要给一个元素添加到现有的层叠顺序中呢?假设用户鼠标悬停在一个用户名上会弹出一个提示框(tooltip
),他的位置在 project-cover
上面,但在其他元素的下面。
在乏味的CSS中,我们需要重新更新sorting-bar
、modal
和navigation
的z-index
的值。使用Sass,我们只需要为新元素更新列表:
$elements: project-covers, user-tooltip, sorting-bar, modals, navigation;
因为sorting-bar
、modal
和navigation
的z-index
的值在列表中已发生变化(以前他们的z-index
的值是2,3,4,现在变成了3,4,5)。我们编译出来的CSS会自动调整他们的z-index
值,用以新的位置。我们只需要在Sass中添加下面的代码:
.user-tooltip {
z-index: index($elements, user-tooltip);
}
这个时候,编译出来的CSS如下:
.user-tooltip {
z-index: 2;
}
.sorting-bar {
z-index: 3;
}
.modal {
z-index: 4;
}
.navigation {
z-index: 5;
}
通过层叠上下文顺序解决方案
假设我们的布局更复杂,有多个层叠的上下文和层叠顺序。(请记住,要让z-index
起作用,需要确保position
的值不是static
,这就是新创建一个层叠的内容,只要将层叠顺序值指定所有元素的父元素上。)在这种情况下,一个列表可能不够使用。我们需要创建多个列表,每个列表会被认为是一个上下文。
$elements: project-covers, user-tooltip, sorting-bar, modals, navigation;
$modal-elements: fields, form-controls, errors, autocomplete-dropdown;
.modal {
z-index: index($elements, modals);
.field {
z-index: index($modal-elements, fields);
}
.form-controls {
z-index: index($modal-elements, form-controls);
}
.error {
z-index: index($modal-elements, errors);
}
.autocomplete-dropdown {
z-index: index($modal-elements, autocomplete-dropdown);
}
} /* .modal */
编译出来的CSS:
.modal {
z-index: 4;
}
.modal .field {
z-index: 1;
}
.modal .form-controls {
z-index: 2;
}
.modal .error {
z-index: 3;
}
.modal .autocomplete-dropdown {
z-index: 4;
}
跨网站解决方案
这种技术最主要的要求就是坚持维护。任何硬性的z-index
值都可能危及到那些列表的完整性。正因为如此,你会发现,你可能在一个网站会有多个页面要定义z-index
的值。最简单的方案就是创建一个局部的文件,包括整个网站的列表,然后就可以在需要的地方使用。(你可能有了这样的局部文件,比如用来存储网站颜色,字体等变量——这是类似的一个做法)。
_ZINDEX.SCSS
$elements: project-covers, user-tooltip, sorting-bar, modals, navigation;
$modal-elements: fields, form-controls, errors, autocomplete-dropdown;
MYPAGE.SCSS
@import '_zindex.scss'
.modal {
z-index: index($elements, modals);
}
每个页面修改或合并全局的列表也是可能的。你导入你的那部分,然后使用Sass的 列表函数(或者更高级的功能)修改你需要的部分。例如:
import '_zindex.scss'
$modal-elements: append($modal-elements, close-button);
$elements: insert-nth($elements, sidebar-filters, 3);
.modal .close-button {
z-index: index($modal-elements, close-button);
}
.sidebar-filter {
z-index: index($elements, sidebar-filter);
}
这个Sass会在modal-elements
列表最后面插入一个close-buttons
和在elements
列表第三个顺序中插入sidear-filters
,而且不会影响其他页面使用的_z-index.scss
。
错误的报告
经常检查代码中的错误,以避免造成错误。例如你想给不在你列表中的项设置z-index
值,你可能会发现一个意想不到的输出:
.objects {
z-index: index($elements, thing-not-in-my-list);
}
.objects {
z-index: false;
}
因为false
不是z-index
的有效值,我们不希望他出现在我们编译出来的代码中。我们可以自定义一个函数,使用Sass的@warn
,在一开始就告诉我们东西是否出了问题。
@function z($list, $element) {
$z-index: index($list, $element);
@if $z-index {
@return $z-index;
}
@warn 'There is no item "#{$element}" in this list; choose one of: #{$list}';
@return null;
}
这个函数接受 index()
相同的参数,但在返回值之前他会检查我们要求的东西是否存在列表中。如果该值存在,他就会返回index()
的索引值,就像刚才一样。如果该值不存在,他会发现两件事:
- 会输出警告信息,告诉你选项不在列表中,并且会将列表打印出来,以供你做出选择
- 将会返回
null
值,告诉Sass不会打印出相应的规则
而不是以下无效的CSS:
.objects {
z-index: false;
}
z-index
的值一直不会打印出来。如果他在你的规则中是唯一的一个规则,那么Sass甚至会做出不打印的选择,从而最大限度的减少不必要的输出。
结论
跟踪上下文的层叠顺序,使用CSS是非常难的,但使用预处理程序使它变得更容易。有许多方法可以处理它,但我们看到这里的做法是最简单的,需要最少的维护。而且由于Sass的列表和函数如此强大,你必须扩大这项技术,因为你需要更好的掌握他们。
相关资源
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论