tab外翻弧度样式 两种方案 css

183 阅读2分钟

image.png

有这种外翻弧度样式需求么,一种可以满足透明色,另外一种只能全色,具体原理不解释了,懂的都懂

方案一:满足透明色

<template>
  <div class="container">
    <div class="tab-list">
      <div
        v-for="tab in tabList"
        :key="tab.id"
        class="tab-item"
        :class="props.activeTab === tab.id ? 'tab-selected' : ''"
        @click="onTab(tab.id)"
      >
        <div>{{ tab.label }}</div>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
import {
  computed,
  markRaw,
  onMounted,
  reactive,
  onBeforeUnmount,
  ref,
  nextTick,
  watch,
  getCurrentInstance
} from 'vue'
const emit = defineEmits(['tabChangeFun'])
const props = defineProps({
  activeTab: {
    type: Number,
    default: 1
  }
})
const tabList = [  { id: 1, label: '平均分' },  { id: 2, label: '均衡性' }  // { id: '3', label: 'xxx' }]
const onTab = (id: any) => {
  emit('tabChangeFun', id)
}
</script>
<style lang="less" scoped>
@tab-height: 60px;
@primary-color: rgba(210,212,215,0.3);
@tab-bgcolor: rgba(210,212,215,0.3);
@select-tab-bgcolor: rgba(255,255,255,0.75);
@active-Text-color: #181a1c;

.tab-list {
  display: flex;
  position: relative;
  z-index: 2;
  border-radius: 16px 16px 0 0;
  overflow: hidden; // 新增
}

.tab-list {
  display: flex;
  border-radius: 16px 16px 0 0;
  background-color: @tab-bgcolor;

  .tab-item {
    flex: 1;
    height: @tab-height;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 20px;
    color: #626469;
    font-weight: 600;
    position: relative;
  }
  .tab-icon {
    width: 17px;
    height: 17px;
    margin-right: 4px;
  }

  .tab-selected {
    opacity: 1;
    background: @select-tab-bgcolor;
    border-radius: 16px 16px 0 0;
    color: @active-Text-color;
  }
}



.tab-list {
    background:  @tab-bgcolor;

    .tab-item {
      &.tab-selected {
        background: @select-tab-bgcolor;

        /* 设置相对定位 */
        &::before,
        &::after {
          content: '';
          /* 设置空内容 */
          position: absolute;
          /* 设置绝对定位 */
          width: 17px;
          /* 设置宽度 */
          height: 17px;
          /* 设置高度 */
          bottom: 0;
          /* 设置底部对齐 */
          background: @select-tab-bgcolor;
          /* 设置背景色 */
        }

        &::before {
          left: -17px;
          /* 设置左边位置 */
          background: radial-gradient(
            circle at 0 0,
            transparent 17px,
            @select-tab-bgcolor 17px
          );
        }

        &::after {
          right: -17px;
          /* 设置右边位置 */
          background: radial-gradient(
            circle at 17px 0,
            transparent 17px,
            @select-tab-bgcolor 17px
          );
        }
      }
    }
    .tab3::after {
      display: none !important;
    }
  }
</style>

方案二:不能满足透明色,全色可以

<template>
  <div class="container">
    <div class="tab-list">
      <div
        v-for="tab in tabList"
        :key="tab.id"
        class="tab-item"
        :class="props.activeTab === tab.id ? 'tab-selected' : ''"
        @click="onTab(tab.id)"
      >
        <div>{{ tab.label }}</div>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
import {
  computed,
  markRaw,
  onMounted,
  reactive,
  onBeforeUnmount,
  ref,
  nextTick,
  watch,
  getCurrentInstance
} from 'vue'
const emit = defineEmits(['tabChangeFun'])
const props = defineProps({
  activeTab: {
    type: Number,
    default: 1
  }
})
const tabList = [  { id: 1, label: '平均分' },  { id: 2, label: '均衡性' }  // { id: '3', label: 'xxx' }]
const onTab = (id: any) => {
  emit('tabChangeFun', id)
}
</script>
<style lang="less" scoped>
@tab-height: 60px;
@primary-color: #e2e8f8;
@tab-bgcolor: #e2ecf4;
@active-Text-color: #181a1c;

.tab-list {
  display: flex;
  position: relative;
  z-index: 2;
  border-radius: 16px 16px 0 0;
  //   background-color: pink;
  overflow: hidden; // 新增
}

.tab-list {
  display: flex;
  border-radius: 16px 16px 0 0;
  background-color: @tab-bgcolor;

  .tab-item {
    flex: 1;
    height: @tab-height;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 20px;
    // opacity: 0.65;
    color: #626469;
    font-weight: 600;
    position: relative;
  }
  .tab-icon {
    width: 17px;
    height: 17px;
    margin-right: 4px;
  }

  .tab-selected {
    opacity: 1;
    background: #ffffff;
    // 新增
    border-radius: 16px 16px 0 0;
    // 新装置
    // box-shadow: 12px 12px 0 0 blue, -12px 12px 0 0 blue;
    box-shadow:
      16px 16px 0 0 #ffffff,
      -16px 16px 0 0 #ffffff;
    color: @active-Text-color;
  }

  .tab-selected::before {
    content: '';
    position: absolute;
    left: -17px;
    bottom: 0;
    width: 17px;
    height: @tab-height;
    background: #e2ecf4; // 修改
    border-radius: 0 0 16px 0;
  }
  .tab-selected::after {
    content: '';
    position: absolute;
    right: -17px;
    bottom: 0;
    width: 17px;
    height: @tab-height;
    background: #e2ecf4; // 修改
    border-radius: 0 0 0 16px;
  }
}
</style>