在很多商城app中,有一个功能是选中按钮后,右下角会显示一个三角形,然后三角形中有一个勾,提示用户已经选中了此选项,但在很多组件中是没有提供这个的,下面我们来实现这个功能,效果如下:
template部分(使用Vue+Vant组件):
<div class="order-header-type">
<div class="type">
<div class="type-content">
<van-button
type="default"
size="large"
:class="orderStore.orderType === '堂食' ? 'select' : ''"
@click="clickType('堂食')"
>
<!-- <template #icon><van-icon name="shop-o" /> </template> -->
堂食</van-button
>
<van-button
type="default"
size="large"
:class="orderStore.orderType === '外带' ? 'select' : ''"
@click="clickType('外带')"
>外带</van-button
>
</div>
</div>
</div>
script部分(Vue3.2+TS):
import { useorderStore } from "@/store/modules/module.js";
const orderStore = useorderStore();
const clickType = (str: string) => {
orderStore.orderType = str;
};
css部分(这里使用的是less预处理器)
.order-header-type {
.type {
display: flex;
.type-content {
display: flex;
width: 100vw;
height: 5vh;
.select {
position: relative;
text-align: left;
color: #00aaff;
border: 0.5vw solid #ff335f;
overflow: hidden;
::before {
content: "";
position: absolute;
right: -3vw;
bottom: -3vw;
width: 6vw;
height: 6vw;
background-color: #ff335f;
transform: rotate(45deg);
}
::after {
content: "";
width: 1vw;
height: 4vw;
position: absolute;
right: 0vw;
bottom: 0vw;
border: 0.5vw solid #fff;
border-top-color: transparent;
border-left-color: transparent;
transform: rotate(45deg);
z-index: 999;
}
}
}
}
}
<van-button
type="default"
size="large"
:class="orderStore.orderType === '堂食' ? 'select' : ''"
@click="clickType('堂食')"
>
首先看到这一段,在组件部分:class="orderStore.orderType === '堂食' ? 'select' : ''"
,这句话的意思就是当orderStore.orderType
等于堂食时,class设为select,否则设为空。
对应到css的select部分,当选中时,为其渲染边框,颜色提示选中,然后渲染右下角的三角形和勾采用的是伪类元素:::before 和::after
给元素设置伪元素的时候,必须设置其content属性,浏览器才会将这些元素插入到选择的元素中。该值可以设置为空字符串:content: “”,这里我们采取了这种方案。
这里可以看到首先渲染一个right: -3vw;bottom: -3vw;width: 6vw;height: 6vw;
的矩阵,颜色设计为红色,然后将这个矩阵旋转45度:transform: rotate(45deg);
,这样在按钮当中就只会留下一个三角形。
然后渲染一个width: 1vw;height: 4vw;border: 0.5vw solid #fff;
的矩阵框,使用border-top-color: transparent;border-left-color: transparent;
移除矩阵上部和下部的边框,如下所示:
最后同样使用transform: rotate(45deg);
将其旋转45度,成功达到效果:
在这里的::before和::after只代表渲染的顺序,先渲染红色三角再渲染勾能保证勾不会被遮盖,当然这里可以设计z-index: 999;
直接渲染勾到最高层,如此再更换::before和::after也无妨了。
伪元素还可以用来做破碎图片占位
当用户网络出现问题的时候,可能会造成某些图片的访问失败,从而浏览器将显示一张损坏的图片,极其影响界面美观,比如:
<img class="img" src="图片路径">
因为src没有指代明确到地址,所以渲染时找不到图片,会显示:
我们可以使用伪元素,在渲染图片之前,使用::before进行占位:
.img{
display: inline-block;
width: 256px; height: 192px;
color: transparent;
position: relative;
overflow: hidden;
}
img::before {
background-color: #f0f0f0;
border: #aaaaaa;
display: block;
height: 100%;
content: "";
text-align: center;
}