前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >巧用CSS实现折叠手风琴效果

巧用CSS实现折叠手风琴效果

作者头像
心安事随
发布2024-07-29 17:24:46
730
发布2024-07-29 17:24:46
举报
文章被收录于专栏:前端大合集

引言

今天在CodePen[codepen.io] 上面发现了一个使用css实现的一个手风琴效果, 感觉蛮有意思的,于是自己尝试了一下,发现不是特别难, 在编码前把思路整理好,再去实现,就会发现轻松许多.

先看一下效果吧,大家提前玩玩,然后我们在一步一步去实现这个效果. 本文会将一些基础的css顺带讲解到, 并将一些写css相关的设计网站资源进行分享.

效果:

实现

盒子背景是一个渐变色. 并且宽和高是浏览器视口的宽高,那么我们就可以编写我们的css代码.然后手风琴的盒子相对于浏览器视口是水平垂直居中的

  • 子元素相对父元素水平垂直居中,可以使用flex布局. 关于flex 的详细讲解可以查看这篇文章,通过图片和代码的结合,很容易理解. ==> juejin.cn/post/720689….
  • 渐变颜色 , 推荐一个网站,里面有很多预设渐变颜色,而且很好看 ==> www.grabient.com/
  • 浏览器视口的宽高 用 c3新增的宽高大小 vhvw,
    • 1vh 相当于 浏览器视口高度的1%
    • 1vw 相当于 浏览器视口宽度的1%
代码语言:javascript
复制
      * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            /* 子元素水平垂直居中 */
            display: flex;
            justify-content: center;
            align-items: center;
            /* 浏览器视口的宽高 */
            width: 100vw;
            height: 100vh;
            /* 渐变 */
            background-color: #8EC5FC;
            background-image: linear-gradient(62deg, #8EC5FC 0%, #E0C3FC 100%);

        }

这时候打开页面是这样的.

然后我们接着来, 4张图片位于一个大盒子里面.

  • active 类用来将图片撑开的, 后面会通过js 动态添加 和 删除
  • --url 是我们定义的一个css变量,这里定义的话 值就是每个图片在目录的相对路径
代码语言:javascript
复制
    <div class="contain">
        <div class="option active" style="--url:url(./image/1.jpg);" id="item1">
        </div>
        <div class="option" style="--url:url(./image/2.jpg);" id="item2">
        </div>
        <div class="option" style="--url:url(./image/3.jpg);" id="item3">
        </div>
        <div class="option" style="--url:url(./image/4.jpg);" id="item4">
        </div>
    </div>

然后编写css代码

  • 默认图片(也就是option 类)的盒子宽度是很小的, 然后图片居中,平铺,不重复.
  • 添加.active 类的话, 图片盒子的宽度会自动撑开外面大盒子剩余空间 ==> flex-grow属性
代码语言:javascript
复制
        body .contain .option {
            min-width: 80px;
            margin: 10px;
            background: var(--url);
            /* 图片覆盖  平铺*/
            background-size: cover;
            /* 图片位置 */
            background-position: center center;
            background-repeat: no-repeat;
            cursor: pointer;
            border-radius: 10px;
            transition: 0.5s cubic-bezier(0.05, 0.61, 0.41, 0.95);
        }

        .active {
            flex-grow: 10;
        }

flex-grow 是一个CSS属性,用于指定Flexbox布局中flex子项的增长因子。当父容器的空间大于子项所需的总空间时,flex-grow 决定了如何分配额外的空间。

  • flex-grow 的值是一个正数,表示子项的增长能力。
  • 如果所有子项的 flex-grow 总和为1,那么每个子项将根据其 flex-grow 值占剩余空间的比例增长。
  • 如果 flex-grow 值大于1,子项将尝试占据更多空间,相对于 flex-grow 值较小的子项。

例如,如果有三个子项,它们的 flex-grow 分别为1、2和3,那么当父容器有额外空间时,第二个子项将尝试占据第一个子项两倍的空间,第三个子项将尝试占据第一个子项三倍的空间。

在该页面中,主要的作用就是,设置active类的元素, 即设置flex-grow 的元素的宽度将会自动占据父容器余下的空间.

前面的铺垫已经做好了. 剩下就该js出手了.主要需要完成的事情有:

  • 点击哪个盒子,哪个盒子添加.active 类, 其他元素如果有.active,就要移除.

这里我们可以采取事件委托的方式处理点击事件.

事件委托是一种事件处理模式,其中一个事件监听器被添加到父元素上,用于处理其子元素的事件。这样做的好处包括:

  1. 减少内存使用:不需要为每个子元素单独添加事件监听器,只需为父元素添加一个即可。
  2. 动态内容:如果子元素是动态添加或删除的(例如通过用户交互或Ajax),事件委托仍然有效,因为新的子元素会自动继承父元素的事件监听器。
  3. 简化代码:事件委托可以减少代码的复杂性,因为你不需要管理多个事件监听器
代码语言:javascript
复制
        const contain = document.querySelector('.contain') // 手风琴盒子
        const optionList = document.querySelectorAll('.option') // 图片盒子类数组


        contain.addEventListener('click', (e) => {
            // 当e.target 是.option的时候,就会触发,否则不会触发
            if (e.target.classList.contains('option')) {
                optionList.forEach(el => {
                    el.classList.remove('active');
                });
                e.target.classList.add('active');
                e.stopPropagation(); // 阻止事件冒泡
            }
        });

完整代码

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            /* 子元素水平垂直居中 */
            display: flex;
            justify-content: center;
            align-items: center;
            /* 浏览器视口的宽高 */
            width: 100vw;
            height: 100vh;
            /* 渐变 */
            background-color: #8EC5FC;
            background-image: linear-gradient(62deg, #8EC5FC 0%, #E0C3FC 100%);

        }

        body .contain {
            display: flex;
            width: 800px;
            height: 400px;
            /* 子元素的间距 */

        }


        body .contain .option {
            min-width: 80px;
            margin: 10px;
            background: var(--url);
            /* 图片覆盖  平铺*/
            background-size: cover;
            /* 图片位置 */
            background-position: center center;
            background-repeat: no-repeat;
            cursor: pointer;
            border-radius: 10px;
            transition: 0.5s cubic-bezier(0.05, 0.61, 0.41, 0.95);
        }

        .active {
            flex-grow: 10;
        }
    </style>
</head>

<body>
    <div class="contain">
        <div class="option active" style="--url:url(./image/1.jpg);" id="item1">

        </div>
        <div class="option" style="--url:url(./image/2.jpg);" id="item2">

        </div>
        <div class="option" style="--url:url(./image/3.jpg);" id="item3">

        </div>
        <div class="option" style="--url:url(./image/4.jpg);" id="item4">

        </div>
    </div>
    <script>
        const contain = document.querySelector('.contain')
        const optionList = document.querySelectorAll('.option')


        contain.addEventListener('click', (e) => {
            // 当e.target 是.option的时候,就会触发,否则不会触发
            if (e.target.classList.contains('option')) {
                optionList.forEach(el => {
                    el.classList.remove('active');
                });
                e.target.classList.add('active');
                e.stopPropagation(); // 阻止事件冒泡
            }
        });


    </script>
</body>

</html>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-07-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • 实现
  • 完整代码
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档