弧边选项卡

66 阅读3分钟
  1. 其实我更想去找UI切图,充当背景图搞定
  2. 一方面切图确实可以解决这类问题,但另一方面切图自然而然占据了打包体积,包括http资源的请求,最主要定制化受限,如果切图自带弧边的阴影,而且如果连带主体内容都进入那样真就很麻烦
  3. 作为前端小朋友,自然而然用代码方式实现更加优雅
  4. 预览地址

什么是弧边选项卡

  • 弧边选项卡的案例我下面截两张图,应该就一目了然了

  • 12306车票 1.jpg

  • 个人所得税 2.jpg

如何实现

这里需要说一个css3特性radial-gradient,从MDN上拷贝一段话是这么说的

radial-gradient()  CSS 函数创建一个图像,该图像由从原点辐射的两种或多种颜色之间的渐进过渡组成,其形状可以是圆形或椭圆形。函数的结果是 <gradient> 数据类型的对象,此对象是一种特殊的 <image> 类型。

/* 在容器中心的渐变,从红色开始,变成蓝色,最后变成绿色 */
radial-gradient(circle at center, red 0, blue, green 100%)

实现效果

微信截图_20240327145257.gif

代码

<div class="outer">

  <div class="g-container">
    <div class="g-item  g-inner active"></div>
    <div class="g-item  g-after"></div>
    <div class="g-inner-text">选项卡1</div>
    <div class="g-after-text">选项卡2</div>

  </div>

  <div class="content-box">
    <div class="content">这是选项卡1的内容</div>
    <div class="content hide">这是选项卡2的内容</div>
  </div>
</div>
.outer {
  --active-color: #fff;
  --default-color: #eee;
  margin: 20px auto;
  filter: drop-shadow(0 0 10px rgba(0, 0, 0, 0.1));
  width: 300px;
  border-radius: 10px;
  overflow: hidden;
}

.g-container {
  position: relative;
  width: 300px;
  height: 50px;
  border-radius: 10px 10px 0 0;
  overflow: hidden;
  cursor: pointer;
  background: var(--default-color);
}
.g-item {
  position: absolute;
  width: 150px;
  height: 50px;
  background: var(--default-color);
  transition: all 0.3s linear;
}
.g-inner {
  top: 0;
  left: 0;
  border-radius: 0 20px 0 20px;
  transform: perspective(40px) scaleX(1.4) scaleY(1.5) rotateX(20deg)
    translate(-10px, 0);
  transform-origin: 50% 100%;
}
.g-inner.active,
.g-after.active {
  background: var(--active-color);
  z-index: 10;
}
.g-inner.active::before {
  background: radial-gradient(
    circle at 100% 0,
    transparent,
    transparent 9.5px,
    var(--active-color) 10px,
    var(--active-color)
  );
}
.g-inner::before {
  content: "";
  position: absolute;
  right: -10px;
  width: 10px;
  height: 10px;
  top: 40px;
  background: radial-gradient(
    circle at 100% 0,
    transparent,
    transparent 9.5px,
    var(--default-color) 10px,
    var(--default-color)
  );
}
.g-after {
  top: 0;
  right: 0;
  border-radius: 20px 0 20px 0;
  transform: perspective(40px) scaleX(1.4) scaleY(1.5) rotateX(20deg);
  transform-origin: 50% 100%;
}

.g-after.active::before {
  background: radial-gradient(
    circle at 0 0,
    transparent,
    transparent 9.5px,
    var(--active-color) 10px,
    var(--active-color)
  );
}
.g-after::before {
  content: "";
  position: absolute;
  left: -10px;
  top: 40px;
  width: 10px;
  height: 10px;
  background: radial-gradient(
    circle at 0 0,
    transparent,
    transparent 9.5px,
    var(--default-color) 10px,
    var(--default-color)
  );
}
.g-inner-text,
.g-after-text {
  position: absolute;
  width: 150px;
  height: 50px;
  line-height: 50px;
  text-align: center;
}
.g-inner-text {
  top: 0;
  left: 0;
  z-index: 10;
}
.g-after-text {
  top: 0;
  right: 0;
  z-index: 10;
}

.content-box {
  width: 100%;
  background: #fff;
  transition: all 0.3s linear;
}

.content-box .content {
  padding: 20px;
  box-sizing: border-box;
  width: 100%;
}

.content-box .content.hide {
  display: none;
}

const oContaoner = document.querySelector(".g-container");

const leftItem = document.querySelector(".g-inner");
const rightItem = document.querySelector(".g-after");

const allContantNodes = document.querySelectorAll(".content");

function setContentDisplayStatus(_index) {
  [...allContantNodes].forEach((c, index) => {
    !c.classList.contains("hide") && c.classList.add("hide");

    if (index === _index) {
      c.classList.remove("hide");
    }
  });
}

oContaoner.addEventListener(
  "click",
  (e) => {
    if (e.target.classList.contains("g-inner-text")) {
      !leftItem.classList.contains("active") &&
        leftItem.classList.add("active");
      rightItem.classList.remove("active");
      setContentDisplayStatus(0);
    } else {
      !rightItem.classList.contains("active") &&
        rightItem.classList.add("active");
      leftItem.classList.remove("active");
      setContentDisplayStatus(1);
    }
  },
  false
);

参考

  1. css实现弧边选项卡_css上凸弧形效果-CSDN博客