Search K
Appearance
昨天在公司项目开发过程中,遇到一个样式问题,下面我按发现问题
-解决问题
的过程描述一下。
发现问题
如果所示,需求是点击下拉框出现标签选择的下拉列表,然后在弹框底部新增标签的操作,新增标签的左侧是一个颜色选择下拉框。所以问题归根结底就是element-ui的弹框嵌套
问题。
组件代码写完,我发现长这样:
是的,内层弹框被外层弹框挡住了。
解决问题
第一时间想到的是内层弹框z-index比外层小,打开dev-tool一看,果然如此,一顿操作把z-index改大后,看起来很完美:
发现问题
然后我点击选择其中一个颜色,什么?把我外层弹框都关了???
解决问题
第一时间我想到的是事件冒泡导致点击事件冒泡到上层弹框了,于是写代码阻止了事件冒泡,结果没什么卵用。
再看看dom结构,发现弹框dom节点都被渲染到了body层,因为两个弹框都在body下了,所以是同级结构,不存在事件冒泡的问题。
想起来element-ui默认是把弹框渲染到body底部的,所以下拉框组件应该是有个属性取消它的默认渲染行为,让内层正常渲染到外层弹框里面。于是代码加上了popper-append-to-body={false}
(不要觉得代码奇怪,这里用了jsx)
<el-select
value={this.tagColor}
slot="prepend"
placeholder="请选择"
popper-class="color_popper"
popper-append-to-body={false}
onInput={val => {
this.tagColor = val;
}}
>
...
</el-select>
<el-select
value={this.tagColor}
slot="prepend"
placeholder="请选择"
popper-class="color_popper"
popper-append-to-body={false}
onInput={val => {
this.tagColor = val;
}}
>
...
</el-select>
结果内层下拉框不见了!!!
再看看样式,原来弹框的定位是absolute,而且在全局样式改成了position: absolute!important;
。
解决方案本来也很简单,外层保持absolute,内层改成fixed就可以了,但问题就在于两个弹框都是全局position: absolute!important;
,我是用组件提供的popper-class
属性去改定位也没用,因为优先级没有全局高。
<el-select
...
popper-class="color_popper"
>
...
</el-select>
<el-select
...
popper-class="color_popper"
>
...
</el-select>
.color_popper {
position: fixed!important; // 没用,优先级没有全局的 position: absolute!important; 高
}
.color_popper {
position: fixed!important; // 没用,优先级没有全局的 position: absolute!important; 高
}
这时候比较考验我们对css优先级熟悉程度了,其实css选择器上可以在弹框类名前面加多一层父节点的css类名,这样就会提升你的优先级:
.create_bar .color_popper {
position: fixed!important;
}
.create_bar .color_popper {
position: fixed!important;
}
至此,问题完美解决。
absolute
、fixed
会合理使用。!important
尽量少用。