vue3使用插槽写一个自定义瀑布列表

发布于:2025-08-13 ⋅ 阅读:(14) ⋅ 点赞:(0)

效果如下:

在这里插入图片描述
在这里插入图片描述

组件

<!-- 

注意:如果要使用这个的话就需要把 父组件里面的高度去掉,就是img标签里的高度: <img :src="item.imgUrl" :alt="item.text" class="item-img" :style="{height:item.height+'px'}"/>  把style去掉

<template>
  <div class="waterfall-container">
    <div
      v-for="(item, index) in props.items"
      :key="index"
      class="waterfall-item"
    >
      <slot :item="item"></slot>
    </div>
  </div>
</template>

<script setup>
import { ref } from "vue";
const props = defineProps({
  items: {
    type: Array,
    default: [],
  },
});
</script>
<style scoped>
.waterfall-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); /* 自动填充列 */
  gap: 10px; /* 项目间隔 */
  padding: 10px;
}

.waterfall-item {
  background-color: #fff;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
}
</style> -->



<template>
  <div class="waterfall-container">
    <div
      v-for="(item, index) in props.items"
      :key="index"
      class="waterfall-item"
      :style="getRandomShadow()"
    >
      <div class="border-container">
        <slot :item="item"></slot>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref } from "vue";
const props = defineProps({
  items: {
    type: Array,
    default: [],
  },
});

function getRandomShadow() {
  const hue = Math.floor(Math.random() * 360);
  const saturation = Math.floor(Math.random() * 30) + 70;
  const lightness = Math.floor(Math.random() * 20) + 60;
  const alpha = 0.3 + Math.random() * 0.3;
  const color = `hsla(${hue}, ${saturation}%, ${lightness}%, ${alpha})`;

  return {
    boxShadow: `0 4px 6px ${color}`,
  };
}
</script>

<style scoped>
.waterfall-container {
  column-count: auto;
  column-width: 250px;
  gap: 10px;
  padding: 10px;
}

.waterfall-item {
  background-color: #fff;
  border-radius: 10px;
  overflow: hidden;
  margin-bottom: 15px;
  break-inside: avoid;
  display: inline-block;
  width: 100%;
  transition: transform 0.3s ease, box-shadow 0.3s ease; /*定义了变换和阴影的过渡动画*/
  transform: translateY(0); /*设置初始位置*/
  will-change: transform, box-shadow; /*提示浏览器这些属性可能会变化,优化性能*/
  position: relative;
  /* 为边框留出空间 */
  padding: 2px;
}

/* 边框容器样式 */
.border-container {
  position: relative;
  z-index: 1;
  padding: 16px;
  border-radius: 8px;
  background: #fff;
  height: 100%;
}

/* 边框流动效果 - 修改实现方式以确保兼容性 */
.waterfall-item::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border-radius: 10px;
  background: linear-gradient(
    90deg,
    #4facfe 0%,
    #00f2fe 25%,
    #84fab0 50%,
    #8fd3f4 75%,
    #4facfe 100%
  );
  background-size: 400% 100%;
  z-index: 0;
  opacity: 0;
  transition: opacity 0.3s ease;
  animation: borderFlow 4s linear infinite;
}

/* 鼠标悬停时的效果 */
.waterfall-item:hover {
  /* 轻微上浮 */
  transform: translateY(-5px);
  /* 增强阴影效果 */
  box-shadow: 0 3px 6px #b3f5c3c0 !important;
  /* 提升层级,确保凸起效果明显 */
  z-index: 10;
}

/* 鼠标悬停时显示边框动画 */
.waterfall-item:hover::after {
  opacity: 1;
}

/* 边框流动动画 */
@keyframes borderFlow {
  0% {
    background-position: 0% 0%;
  }
  100% {
    background-position: 400% 0%;
  }
}
</style>

组件使用

<template>
  <div class="homes GunDongTiao">
    <div class="GunDongTiao" style="width: 100%; height: 700px; overflow: auto">
      <pubu :items="lists" >
        <template #default="{ item }">
          <div class="hoverdiv">

            <img
              :src="item.imgUrl"
              :alt="item.text"
              class="item-img"
              :style="{ height: item.height + 'px' }"
            />
            <p class="item-text">{{ item.text }}--高度:{{ item.height }}</p>
          </div>
        </template>
      </pubu>
    </div>

    <!-- <div class="GunDongTiao display_width">
      <div class="display_ziyuansu" v-for="item in 100" :key="item">
        {{ item }}爱上了和的那份拉萨三大
      </div>
    </div> -->
  </div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import pubu from "./pubu.vue";

const lists = ref([]);
function getRandomFromArray(...args) {
  // 检查是否有传入参数
  if (args.length === 0) {
    return undefined; // 或抛出错误:throw new Error("请至少传入一个参数");
  }

  // 生成随机索引(0 到 参数数量-1 之间)
  const randomIndex = Math.floor(Math.random() * args.length);

  // 返回随机选中的参数
  return args[randomIndex];
}

function FN_lists() {
  let list = [];
  for (let i = 0; i < 1000; i++) {
    // https://img2.baidu.com/it/u=1083342850,1962599537&fm=253&app=138&f=JPEG?w=800&h=1129
    // https://i.bobopic.com/small/85034916.jpg
    // ttps://b0.bdstatic.com/1fa501a96cecc59b336e0a208a82cc95.jpg

    list.push({
      height: getRandomFromArray(100, 150, 195, 200, 350, 400, 630),
      imgUrl: getRandomFromArray(
      `https://i.bobopic.com/small/85034916.jpg`,
        `https://b0.bdstatic.com/1fa501a96cecc59b336e0a208a82cc95.jpg`,
        `https://img2.baidu.com/it/u=1083342850,1962599537&fm=253&app=138&f=JPEG?w=800&h=1129`,
        "https://img0.baidu.com/it/u=1098659514,4222641721&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800",
        'https://img1.baidu.com/it/u=1363165673,1495198767&fm=253&app=138&f=JPEG?w=800&h=1684',
        'https://pic.rmb.bdstatic.com/bjh/241202/dump/3a3c22dfa42dc54549afe91070056862.png',
        'https://img0.baidu.com/it/u=3135630413,3847935609&fm=253&app=138&f=JPEG?w=800&h=1200',
        'https://img1.baidu.com/it/u=889768745,998862614&fm=253&app=138&f=JPEG?w=800&h=1372',
        'https://img2.baidu.com/it/u=1622597608,1377744426&fm=253&app=138&f=JPEG?w=800&h=1422',
        'https://img1.baidu.com/it/u=1791741031,1284315034&fm=253&app=138&f=JPEG?w=800&h=1199',
        'https://pic.rmb.bdstatic.com/bjh/video/efaacfa961497e635fad1cf9bffabfe3.jpeg?for=bg',
        'https://qcloud.dpfile.com/pc/JYEc5AfZmYfDw2k2rh2SOmEF4OvL5kiNnyVtnsI-p46wy43j2YldXkWVhVrI7Ign.jpg',
        'https://inews.gtimg.com/om_bt/OL3l3PFwZsaPuLsg2GWtQW-Uslu8epudPAYI5WLP5uzFsAA/641',
        'https://p3-pc-sign.douyinpic.com/tos-cn-i-0813c001/ooDrAMEfQIsVoIEc7f2bDflCse1YtAQ0AGAAFi~tplv-dy-aweme-images:q75.webp?biz_tag=aweme_images&from=327834062&lk3s=138a59ce&s=PackSourceEnum_PUBLISH&sc=image&se=false&x-expires=1757570400&x-signature=yiT92FEoALP7a6FinmkvyCGDm2Q%3D'
      ),
      height: getRandomFromArray(100, 150, 195, 200, 350, 400, 630),
      text: `Item ${i + 1}`,
      maxWidth: getRandomFromArray(180, 220, 250, 280),
    });
  }
  return list;
}
onMounted(() => {
  lists.value = FN_lists();
});
</script>

<style scoped>
.homes {
  width: 100vw;
  height: 90vh;
  overflow: auto;
}

.item-img {
  width: 100%;
  height: auto;
  object-fit: cover;
}

.item-text {
  padding: 10px;
  font-size: 14px;
  color: #333;
}

/* 鼠标移入时的效果 */
.hoverdiv:hover .item-img {
  transform: scale(1.1);
}


/* 初始状态样式 */
.hoverdiv .item-text {
  color: #333;
  font-weight: 400;
  transition: none; /* 避免过渡与动画冲突 */
}

/* 鼠标移入时,为目标子元素应用动画 */
.hoverdiv:hover .item-text {
  animation: hoverIn 0.9s ease forwards;
}

/* 鼠标移出时,为目标子元素应用反向动画 */
.hoverdiv:not(:hover) .item-text {
  animation: hoverOut 0.9s ease forwards;
}

/* 移入动画:先移动 → 再变粗 → 最后变色 */
@keyframes hoverIn {
  0% {
    font-weight: 400;
    color: #333;
  }
  33% {
    font-weight: 400;
    color: #4eeaf5;
  }
  66% {
    font-weight: 600; /* 完成变粗 */
    color: #f54e4e;
  }
  100% {
    font-weight: 600;
    color: #f88bb5; /* 完成变色 */
    text-align: center;
  }
}

/* 移出动画:先恢复颜色 → 再恢复字重 → 最后恢复位置 */
@keyframes hoverOut {
  0% {
    font-weight: 600;
    color: #f88bb5;
  }
  33% {
    font-weight: 600;
    color: #f54e4e; /* 完成颜色恢复 */
  }
  66% {
    font-weight: 400; /* 完成字重恢复 */
    color: #4eeaf5;
  }
  100% {
    font-weight: 400;
    color: #333;
    text-align: left;

  }
}

/* display布局的时候子元素没有固定的宽高的情况下居中 */
.display_width {
  width: 100%;
  height: 100px;
  overflow: auto;
  border: 1px solid #36d;
  box-sizing: border-box;
  padding: 0 10px;
  column-count: auto;
  column-width: 150px;
  display: flex;
  flex-flow: row;
  flex-direction: row;
  align-items: center;
  flex-wrap: nowrap;
  gap: 10px;
}
.display_ziyuansu {
  height: 60px;
  border: 1px solid #36d;
  box-sizing: border-box;
  padding: 10px 20px;
  flex-grow: 0;
  flex-shrink: 0;
  line-height: 40px;
}

/* 滚动条样式 */
.GunDongTiao::-webkit-scrollbar {
  width: 5px;
  height: 5px;
}

.GunDongTiao::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 10px;
}

.GunDongTiao::-webkit-scrollbar-thumb {
  background: #888;
  border-radius: 10px;
}

.GunDongTiao::-webkit-scrollbar-thumb:hover {
  background: #8ac4e6;
}
</style>

这个是添加了一些其它效果的基本样式

子组件

<template>
  <div class="waterfall-container">
    <div
      v-for="(item, index) in props.items"
      :key="index"
      class="waterfall-item"
      :style="getRandomShadow()"
    >
      <div class="border-container">
        <slot :item="item"></slot>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref } from "vue";
const props = defineProps({
  items: {
    type: Array,
    default: [],
  },
});

function getRandomShadow() {
  const hue = Math.floor(Math.random() * 360);
  const saturation = Math.floor(Math.random() * 30) + 70;
  const lightness = Math.floor(Math.random() * 20) + 60;
  const alpha = 0.3 + Math.random() * 0.3;
  const color = `hsla(${hue}, ${saturation}%, ${lightness}%, ${alpha})`;

  return {
    boxShadow: `0 4px 6px ${color}`,
  };
}
</script>

<style scoped>
.waterfall-container {
  column-count: auto;
  column-width: 250px;
  gap: 10px;
  padding: 10px;
}

.waterfall-item {
  background-color: #fff;
  border-radius: 10px;
  overflow: hidden;
  margin-bottom: 15px;
  break-inside: avoid;
  display: inline-block;
  width: 100%;
  transition: transform 0.3s ease, box-shadow 0.3s ease; /*定义了变换和阴影的过渡动画*/
  transform: translateY(0); /*设置初始位置*/
  will-change: transform, box-shadow; /*提示浏览器这些属性可能会变化,优化性能*/
  position: relative;
  /* 为边框留出空间 */
  padding: 2px;
}

/* 边框容器样式 */
.border-container {
  position: relative;
  z-index: 1;
  padding: 6px;
  border-radius: 8px;
  background: #fff;
  height: 100%;
}

/* 边框流动效果 - 修改实现方式以确保兼容性 */
.waterfall-item::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border-radius: 10px;
  background: linear-gradient(
    90deg,
    #4facfe 0%,
    #00f2fe 25%,
    #84fab0 50%,
    #8fd3f4 75%,
    #4facfe 100%
  );
  background-size: 400% 100%;
  z-index: 0;
  opacity: 0;
  transition: opacity 0.3s ease;
  animation: borderFlow 4s linear infinite;
}

/* 鼠标悬停时的效果 */
.waterfall-item:hover {
  /* 轻微上浮 */
  transform: translateY(-5px);
  /* 增强阴影效果 */
  box-shadow: 0 3px 6px #b3f5c3c0 !important;
  /* 提升层级,确保凸起效果明显 */
  z-index: 10;
}

/* 鼠标悬停时显示边框动画 */
.waterfall-item:hover::after {
  opacity: 1;
}

/* 边框流动动画 */
@keyframes borderFlow {
  0% {
    background-position: 0% 0%;
  }
  100% {
    background-position: 400% 0%;
  }
}
</style>

两个不同的应用

在这里插入图片描述

<template>
  <div class="homes GunDongTiao">
    <pubu :items="lists">
      <template #default="{ item }">
        <div class="hoverdiv">
          <!-- 占位容器 -->
          <div class="placeholder-container" :style="{ height: item.height + 'px' }">
            <!-- 蒙版 -->
            <div class="item-mask"></div>
            <!-- 标题文字 -->
            <div class="item-text">
              <span class="text-inner">{{ item.text }}</span>
            </div>
          </div>
        </div>
      </template>
    </pubu>
  </div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import pubu from "./pubu.vue";

const lists = ref([]);

function getRandomFromArray(...args) {
  if (args.length === 0) return undefined;
  const randomIndex = Math.floor(Math.random() * args.length);
  return args[randomIndex];
}

function generateLists() {
  let list = [];
  // 不再需要图片地址数组
  
  for (let i = 0; i < 14; i++) {
    list.push({
      height: getRandomFromArray(100, 150, 195, 200, 350, 400, 630),
      text: `内容块 ${i + 1}`,
      maxWidth: getRandomFromArray(180, 220, 250, 280),
    });
  }
  return list;
}

onMounted(() => {
  lists.value = generateLists();
});
</script>

<style scoped>
.homes {
  width: 100vw;
  min-height: 100vh;
  padding: 20px;
  overflow: auto;
  background: #0f172a;
  box-sizing: border-box;
}

.hoverdiv {
  position: relative;
  border-radius: 16px;
  overflow: hidden;
  cursor: pointer;
}

/* 占位容器样式 */
.placeholder-container {
  width: 100%;
  background: #1e293b; /* 占位背景色 */
  border-radius: 16px;
  position: relative;
}

/* 蒙版样式 */
.item-mask {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(15, 23, 42, 0.95),
    rgba(139, 92, 246, 0.7)
  );
  opacity: 0;
  transition: opacity 0.4s ease;
  z-index: 1;
}

/* 标题文字样式 */
.item-text {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  padding: 15px;
  font-size: 18px;
  color: #ffffff;
  text-shadow: 0 0 10px rgba(255, 255, 255, 0.9),
    0 0 20px rgba(139, 92, 246, 0.8);
  white-space: nowrap;
  opacity: 0;
  z-index: 2;
  transition: opacity 0.3s ease 0.05s;
}
.text-inner::after {
  content: "";
  position: absolute;
  bottom: -5px;
  left: 0;
  width: 0;
  height: 2px;
  background: linear-gradient(90deg, #ff00ff, #00ffff);
  transition: width 0.3s ease 0.1s;
}

/* 鼠标悬停效果 - 只保留蒙版和文字显示 */
.hoverdiv:hover .item-mask {
  opacity: 1;
}

.hoverdiv:hover .item-text {
  opacity: 1;
}
.hoverdiv:hover .text-inner::after {
  width: 100%;
}
/* 滚动条样式保留 */
.GunDongTiao::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.GunDongTiao::-webkit-scrollbar-track {
  background: rgba(30, 41, 59, 0.5);
  border-radius: 10px;
}

.GunDongTiao::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, #8b5cf6, #4f46e5);
  border-radius: 10px;
  transition: all 0.3s ease;
}

.GunDongTiao::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(180deg, #a78bfa, #6366f1);
}
</style>

在这里插入图片描述

<template>
  <div class="homes GunDongTiao">
    <pubu :items="lists">
      <template #default="{ item }">
        <div class="hoverdiv">
          <img
            :src="item.imgUrl"
            :alt="item.text"
            class="item-img"
            :style="{ height: item.height + 'px' }"
          />
          <!-- 蒙版 -->
          <div class="item-mask"></div>
          <!-- 标题文字 -->
          <div class="item-text">
            {{ item.text }}
          </div>
        </div>
      </template>
    </pubu>

    <!-- <div class="GunDongTiao display_width">
      <div class="display_ziyuansu" v-for="item in 100" :key="item">
        {{ item }}爱上了和的那份拉萨三大
      </div>
    </div> -->
  </div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import pubu from "./pubu.vue";

const lists = ref([]);
function getRandomFromArray(...args) {
  // 检查是否有传入参数
  if (args.length === 0) {
    return undefined; // 或抛出错误:throw new Error("请至少传入一个参数");
  }

  // 生成随机索引(0 到 参数数量-1 之间)
  const randomIndex = Math.floor(Math.random() * args.length);

  // 返回随机选中的参数
  return args[randomIndex];
}

function FN_lists() {
  let list = [];
  const imgs = [
   `https://i.bobopic.com/small/85034916.jpg`,
        `https://b0.bdstatic.com/1fa501a96cecc59b336e0a208a82cc95.jpg`,
        `https://img2.baidu.com/it/u=1083342850,1962599537&fm=253&app=138&f=JPEG?w=800&h=1129`,
        "https://img0.baidu.com/it/u=1098659514,4222641721&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800",
        "https://img1.baidu.com/it/u=1363165673,1495198767&fm=253&app=138&f=JPEG?w=800&h=1684",
        "https://pic.rmb.bdstatic.com/bjh/241202/dump/3a3c22dfa42dc54549afe91070056862.png",
        "https://img0.baidu.com/it/u=3135630413,3847935609&fm=253&app=138&f=JPEG?w=800&h=1200",
        "https://img1.baidu.com/it/u=889768745,998862614&fm=253&app=138&f=JPEG?w=800&h=1372",
        "https://img2.baidu.com/it/u=1622597608,1377744426&fm=253&app=138&f=JPEG?w=800&h=1422",
        "https://img1.baidu.com/it/u=1791741031,1284315034&fm=253&app=138&f=JPEG?w=800&h=1199",
        "https://pic.rmb.bdstatic.com/bjh/video/efaacfa961497e635fad1cf9bffabfe3.jpeg?for=bg",
        "https://qcloud.dpfile.com/pc/JYEc5AfZmYfDw2k2rh2SOmEF4OvL5kiNnyVtnsI-p46wy43j2YldXkWVhVrI7Ign.jpg",
        "https://inews.gtimg.com/om_bt/OL3l3PFwZsaPuLsg2GWtQW-Uslu8epudPAYI5WLP5uzFsAA/641",
        "https://p3-pc-sign.douyinpic.com/tos-cn-i-0813c001/ooDrAMEfQIsVoIEc7f2bDflCse1YtAQ0AGAAFi~tplv-dy-aweme-images:q75.webp?biz_tag=aweme_images&from=327834062&lk3s=138a59ce&s=PackSourceEnum_PUBLISH&sc=image&se=false&x-expires=1757570400&x-signature=yiT92FEoALP7a6FinmkvyCGDm2Q%3D"
  ];
  for (let i = 0; i < 1000; i++) {
    // https://img2.baidu.com/it/u=1083342850,1962599537&fm=253&app=138&f=JPEG?w=800&h=1129
    // https://i.bobopic.com/small/85034916.jpg
    // ttps://b0.bdstatic.com/1fa501a96cecc59b336e0a208a82cc95.jpg

    list.push({
      height: getRandomFromArray(100, 150, 195, 200, 350, 400, 630),
      imgUrl: getRandomFromArray(
        `https://i.bobopic.com/small/85034916.jpg`,
        `https://b0.bdstatic.com/1fa501a96cecc59b336e0a208a82cc95.jpg`,
        `https://img2.baidu.com/it/u=1083342850,1962599537&fm=253&app=138&f=JPEG?w=800&h=1129`,
        "https://img0.baidu.com/it/u=1098659514,4222641721&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800",
        "https://img1.baidu.com/it/u=1363165673,1495198767&fm=253&app=138&f=JPEG?w=800&h=1684",
        "https://pic.rmb.bdstatic.com/bjh/241202/dump/3a3c22dfa42dc54549afe91070056862.png",
        "https://img0.baidu.com/it/u=3135630413,3847935609&fm=253&app=138&f=JPEG?w=800&h=1200",
        "https://img1.baidu.com/it/u=889768745,998862614&fm=253&app=138&f=JPEG?w=800&h=1372",
        "https://img2.baidu.com/it/u=1622597608,1377744426&fm=253&app=138&f=JPEG?w=800&h=1422",
        "https://img1.baidu.com/it/u=1791741031,1284315034&fm=253&app=138&f=JPEG?w=800&h=1199",
        "https://pic.rmb.bdstatic.com/bjh/video/efaacfa961497e635fad1cf9bffabfe3.jpeg?for=bg",
        "https://qcloud.dpfile.com/pc/JYEc5AfZmYfDw2k2rh2SOmEF4OvL5kiNnyVtnsI-p46wy43j2YldXkWVhVrI7Ign.jpg",
        "https://inews.gtimg.com/om_bt/OL3l3PFwZsaPuLsg2GWtQW-Uslu8epudPAYI5WLP5uzFsAA/641",
        "https://p3-pc-sign.douyinpic.com/tos-cn-i-0813c001/ooDrAMEfQIsVoIEc7f2bDflCse1YtAQ0AGAAFi~tplv-dy-aweme-images:q75.webp?biz_tag=aweme_images&from=327834062&lk3s=138a59ce&s=PackSourceEnum_PUBLISH&sc=image&se=false&x-expires=1757570400&x-signature=yiT92FEoALP7a6FinmkvyCGDm2Q%3D"
      ),
      height: getRandomFromArray(100, 150, 195, 200, 350, 400, 630),
      text: `图片 ${i + 1}`,
      maxWidth: getRandomFromArray(180, 220, 250, 280),
    });
  }
  return list;
}
onMounted(() => {
  lists.value = FN_lists();
});
</script>

<style scoped>
.homes {
  width: 100vw;
  min-height: 100vh;
  padding: 20px;
  overflow: auto;
  background-color: #f8f9fa;
  box-sizing: border-box;
}
/* 卡片容器样式 */
.hoverdiv {
  position: relative;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 12px #00000014;
  transition: transform 0.4s ease, box-shadow 0.4s ease;
  cursor: pointer;
}

/* 图片样式与动画 */
.item-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

/* 蒙版样式与动画 */
.item-mask {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, #000000b3 0%, #ff79a366 100%);
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}

/* 文本样式与动画 */
.item-text {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, 100px);
  padding: 12px;
  font-size: 16px;
  color: #ffffff;
  text-shadow: 0 2px 4px #00000033;
  white-space: nowrap;
  opacity: 0;
  transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  transition-delay: 0.1s;
}

/* 鼠标悬停效果 */
.hoverdiv:hover {
  transform: translateY(-6px);
  box-shadow: 0 12px 20px #0000001f;
}

.hoverdiv:hover .item-img {
  transform: scale(1.12);
}

.hoverdiv:hover .item-mask {
  opacity: 1;
  transform: translateY(0);
}

.hoverdiv:hover .item-text {
  opacity: 1;
  transform: translate(-50%, -50%);
  animation: textPulse 1.5s ease-in-out infinite alternate;
}

/* 文本脉动动画 */
@keyframes textPulse {
  from {
    letter-spacing: 0;
    font-weight: 400;
  }
  to {
    letter-spacing: 0.5px;
    font-weight: 500;
  }
}

/* display布局的时候子元素没有固定的宽高的情况下居中 */
.display_width {
  width: 100%;
  height: 100px;
  overflow: auto;
  border: 1px solid #36d;
  box-sizing: border-box;
  padding: 0 10px;
  column-count: auto;
  column-width: 150px;
  display: flex;
  flex-flow: row;
  flex-direction: row;
  align-items: center;
  flex-wrap: nowrap;
  gap: 10px;
}
.display_ziyuansu {
  height: 60px;
  border: 1px solid #36d;
  box-sizing: border-box;
  padding: 10px 20px;
  flex-grow: 0;
  flex-shrink: 0;
  line-height: 40px;
}

/* 滚动条样式 */
.GunDongTiao::-webkit-scrollbar {
  width: 5px;
  height: 5px;
}

.GunDongTiao::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 10px;
}

.GunDongTiao::-webkit-scrollbar-thumb {
  background: #888;
  border-radius: 10px;
}

.GunDongTiao::-webkit-scrollbar-thumb:hover {
  background: #8ac4e6;
}
</style>