supports规则
故事前景:
实现一个如下图的布局:
看到这个设计图,各路摸鱼大神纷纷劝我使用图片,然后控制点击区域,简单方便,用图一分钟,摸鱼两小时。
沉思三秒钟之后,我考虑到了以下三点:
用户体验较差(用户点击区域有限)
图片需要一个请求(浪费性能)
太简单的做法(我不干)
于是,我就开始了我的做法:
首先,我准备了四个层级的元素:
准备一个外层盒子,用来旋转角度;
内层盒子需要创建一个根据宽度自适应高度的正方形盒子,并相对定位;
定位元素下生成一个绝对定位元素,宽高100%;
绝对定位元素下四个方向;
// layout <div class="outBox"> <div class="innerBox"> <p class="center"></p> <ul class="absoluteEle"> <li class="direction" v-for="(item,i) of dirList" :key="i" > {{item}} </li> </ul> </div> </div> // style .outBox{ transform: rotateZ(45deg); } .innerBox{ overflow: hidden; border-radius: 50%; padding: 50%; position: relative; } .center{ position: absolute; width: 38%; height: 38%; color: #fff; background: #fff; left: 31%; top: 31%; overflow: hidden; z-index: 1; border-radius: 50%; } .absoluteEle{ position: absolute; width: 100%; height: 100%; left: 0; top: 0; display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; grid-row-gap: 20px; grid-column-gap: 20px; } .direction{ width: 100%; height: 100%; box-sizing: border-box; } .absoluteEle > li:nth-child(2n) { margin-right: 0; } .absoluteEle > li:nth-child(3), .absoluteEle > li:nth-child(4) { margin-top: 20px; }复制代码
得到如下样式:
好像还不错,改改颜色放个箭头就perfect了,而且用户点击范围也更加精准!
于是我信心满满的提交测试... ...
安卓很完美,苹果高版本也不错,测试到低版本的苹果手机时,测试那平平无奇的脸上皱起了眉头,仿佛一下苍老十岁<( ̄▽ ̄)/
接下来就开始了我(小伙砸)与测试的巅峰对决:
测试:小伙砸,你这页面有问题啊,点了没效果啊,咋回事啊?
小伙砸:不可能,我测试了好多次都没问题的!
测试:小伙砸,你别犟,眼见为实(将iphone12mini递给了我);
小伙砸接过手机开始调试...
测试不屑的看着我
咦,咋点不了,我赶紧将页面恢复到测试状态,我丢,这页面咋这样
好家伙,身经百战的我如定海神针一般,表面稳如老狗,内心也稳如泰山!!!
这绝对是哪个属性没起作用咯,待小伙砸测试一番... ...
我一眼扫过代码,发现display:grid这个属性语法较新,应该是它了;然后我就开始了代码更改,也引来了@supports规则的使用:
// style(代码修改) .absoluteEle{ position: absolute; width: 100%; height: 100%; left: 0; top: 0; /* 新增 */ display: flex; flex-wrap: wrap; } .direction{ box-sizing: border-box; /* 新增 */ width: calc(~"50% - 10px"); height: calc(~"50% - 10px"); margin: 0 20px 0 0; } @supports (display:grid){ .absoluteEle{ display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; grid-row-gap: 20px; grid-column-gap: 20px; } .direction{ width: 100%; height: 100%; margin:0; } }复制代码
再提交测试,ok,perfect!
既然提到了@supports(),那就记录学习一下这个规则吧!!!
@supports规则是从Edge12浏览器开始支持的,所以根本没有IE浏览器什么事情。
声明语法
先通过一个示例看看@supports的语法:
@supports (display:grid){ .grid{ display:grid; } }复制代码
这段代码意思简单明了,如果浏览器支持display:grid,则匹配.grid类名的元素设置为display:grid;
@supports规则还支持使用操作符进行判断,这些操作符分别为not、and和or,分别表示否定、并且和或者。
来看这些操作符实现简单的逻辑判断:
/* 支持网格布局 */ @supports (display:grid){ } /* 不支持网格布局 */ @supports not (display:grid){ } /* 同时支持网格布局和弹性布局 */ @supports (display:grid) and (display:flex){ } /* 支持网格布局或者弹性布局 */ @supports (display:grid) or (display:flex){ } /* 同时支持网格布局和弹性布局和transform */ @supports (display:grid) and (display:flex) and (transform: none){ } /* 支持网格布局或者弹性布局或者transform */ @supports (display:grid) or (display:flex) or (transform: none){ }复制代码
但是,若是遇到复杂逻辑判断,还是一知半解的使用这些函数语法就会出现问题,来看几个依葫芦画瓢的示例:
1. @supports (display:flex) and not (display:grid) {} //支持弹性布局并且不支持网格布局 2. @supports not (display:grid) and (display:flex) {} //不支持网格布局并且支持弹性布局复制代码
想要学会@supports的条件判断语法,级联、嵌套,必须要多花亿点点时间来深入理解其规则!
我们先定义一个数据类型,命名为<[name]>,用来表示括号里面的条件,然后将条件拆出来看:
(display:flex) == <支持弹性布局> not (display:grid) == <不支持网格布局> (支持网格布局) and (支持弹性布局) and (支持transform) == <var> (支持网格布局) or (支持弹性布局) or (支持transform) == <var>复制代码
每个条件都可以理解为一个变量,套用以上规则,来判断支持弹性布局,但不支持网格布局这样的条件实在太简单:@supports (<支持弹性布局>) and (<不支持网格布局>) { }
得到正确写法:@supports (display:flex) and (not (display:grid)) { }
选择器语法
来看两个示例:
@supports (--var:blue) { } @supports selector(:default) { }复制代码
以上示例在实际项目中实用性较低,这里不再记录。。。
作者:target酱
链接:https://juejin.cn/post/7024451085389529124