一、前言
有的地方会用到直角不等边三角形,此篇记录实现过程及示例应用场景,css代码主要为scss写法,可自行拆解,附代码注释详解
二、圆角tab切换
无间距

有间距

- 圆角盒子+三角盒子组合完成其中一项
- 不等边三角形四个角度分别通过边框的上下左右四个边框其中方向两个组合完成
- 通过平移控制间隔
- 通过css变量控制切换
反方向同理,本次不做演示
xml
<template>
<div class="box">
<div class="tabBox">
<div class="tabBoxLeft" @click="data.tabFlag = 0">
<div class="tabBoxLeftCont">左tab</div>
<div class="tabBoxLeftTriangle"></div>
</div>
<div class="tabBoxRight" @click="data.tabFlag = 1">
<div class="tabBoxRightTriangle"></div>
<div class="tabBoxRightCont">右tab</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive, toRefs, watch, computed } from "vue";
import { useRoute, useRouter } from "vue-router";
const route = useRoute();
const router = useRouter();
const data = reactive({
tabFlag: 0,
});
// 监听tabFlag的变化
watch(
() => data.tabFlag,
(n, o) => {
console.log(n, o);
if (n == 0) {
// 初始色
document.documentElement.style.setProperty("--hlColor", "#fab949");
document.documentElement.style.setProperty("--hlColor1", "#999999");
} else {
// 赋反
document.documentElement.style.setProperty("--hlColor1", "#fab949");
document.documentElement.style.setProperty("--hlColor", "#999999");
}
},
// 首次监听
{ immediate: true }
);
// const { } = toRefs(data)
</script>
<style scoped lang="scss">
.box {
padding: 50px;
}
// 控制左右tab的大盒子
.tabBox {
display: flex;
color: #fff;
text-align: center;
// 左右开启弹性盒子,控制其中的两个盒子
.tabBoxLeft,
.tabBoxRight {
display: flex;
}
// 左右两侧的圆角盒子
.tabBoxLeftCont,
.tabBoxRightCont {
line-height: 50px;
width: 200px;
}
// 左右两侧的三角盒子,边框实线与宽高0为通用属性
.tabBoxLeftTriangle,
.tabBoxRightTriangle {
width: 0;
height: 0;
border-style: solid;
}
// 左侧盒子
.tabBoxLeft {
// x轴平移用于左右盒子间隔,平移距离等于三角形的宽度则为无间隔
// 左右为透明边框,不存在覆盖层级问题
transform: translateX(200px);
// 左侧圆角盒子,使用css变量控制背景色
.tabBoxLeftCont {
background-color: var(--hlColor);
border-radius: 5px 0 0 5px;
}
// 左侧三角盒子,分别通过不同方向的两个边框画三角
// 高度方向边框与左侧圆角盒子等高,且为有色
// 宽度方向边框控制三角形角度,且为无色
// 使用css变量控制背景色
.tabBoxLeftTriangle {
// (上 右 下 左)
border-width: 50px 200px 0px 0px;
border-top-color: var(--hlColor);
border-right-color: transparent;
}
}
// 右侧同理
.tabBoxRight {
.tabBoxRightCont {
background-color: var(--hlColor1);
border-radius: 0 5px 5px 0;
}
.tabBoxRightTriangle {
// (上 右 下 左)
border-width: 0 0 50px 200px;
border-bottom-color: var(--hlColor1);
border-left-color: transparent;
}
}
}
</style>
三、平行四边形tab切换
- 动态类名控制高亮
- 动态样式控制间隔
- 高亮分别控制三个盒子的颜色相关
- 三角盒子通过两个方向边框组合完成,一个有色,一个透明
反方向同理,本次不做演示
xml
<template>
<div class="box">
<div class="tabBox">
<!-- 动态类名控制高亮 -->
<!-- 动态样式控制间隔,20为三角宽度,等于20则为无间隔,小于20则为间隔显示 -->
<div
class="tabItem"
v-for="(item, index) in data.tabList"
:key="index"
@click="data.tabFlag = index"
:class="['tabItem', { currentTabColor: data.tabFlag == index }]"
:style="{
transform: `translateX(${(data.tabList.length - index) * 20}px)`,
}"
>
<div class="tabItemLeft"></div>
<div class="tabItemCont">{{ item }}</div>
<div class="tabItemRihgt"></div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive, toRefs, watch, computed } from "vue";
import { useRoute, useRouter } from "vue-router";
const route = useRoute();
const router = useRouter();
const data = reactive({
tabFlag: 0,
tabList: ["tab1", "tab2", "tab3", "tab4", "tab5"],
});
// const { } = toRefs(data)
</script>
<style scoped lang="scss">
.box {
padding: 50px;
}
// 高亮分别控制三个盒子的颜色相关
.box .tabBox .currentTabColor {
.tabItemCont {
background-color: pink;
}
.tabItemLeft {
border-bottom-color: pink;
}
.tabItemRihgt {
border-left-color: pink;
}
}
// 备用层级方法 此次层级不深,演示为简单层级 层级过深可以直接覆盖
// .currentTabColor {
// .tabItemCont {
// background-color: pink !important;
// }
// .tabItemLeft {
// border-right-color: pink !important;
// }
// .tabItemRihgt {
// border-left-color: pink !important;
// }
// }
// tab盒子
.tabBox {
display: flex;
// tab项盒子
.tabItem {
line-height: 50px;
width: 200px;
text-align: center;
display: flex;
// 内容盒子
.tabItemCont {
background-color: aqua;
width: 100%;
}
// 左右三角通用属性
.tabItemLeft,
.tabItemRihgt {
width: 0;
height: 0;
border-style: solid;
border-width: 0 0 50px 20px;
}
// 左盒子为左下边框两边框组成,左透明,下有色
.tabItemLeft {
border-left-color: transparent;
border-bottom-color: aqua;
}
// 右盒子为左下边框两边框组成,左有色,下透明
.tabItemRihgt {
border-left-color: aqua;
border-bottom-color: transparent;
}
}
}
</style>