Day05 - Flex 实现可伸缩的图片墙 中文指南

简介:

Day05 - Flex 实现可伸缩的图片墙 中文指南

作者:©liyuechun
简介:JavaScript30 是 Wes Bos 推出的一个 30 天挑战。项目免费提供了 30 个视频教程、30 个挑战的起始文档和 30 个挑战解决方案源代码。目的是帮助人们用纯 JavaScript 来写东西,不借助框架和库,也不使用编译器和引用。现在你看到的是这系列指南的第 5 篇。完整指南在 从零到壹全栈部落。

实现效果

点击任意一张图片,图片展开,同时从图片上下两方分别移入文字。点击已经展开的图片后,图片被压缩,同时该图片上下两端的文字被挤走。

HTML源码

  <div class="panels">
    <div class="panel panel1">
      <p>Hey</p>
      <p>Let's</p>
      <p>Dance</p>
    </div>
    <div class="panel panel2">
      <p>Give</p>
      <p>Take</p>
      <p>Receive</p>
    </div>
    <div class="panel panel3">
      <p>Experience</p>
      <p>It</p>
      <p>Today</p>
    </div>
    <div class="panel panel4">
      <p>Give</p>
      <p>All</p>
      <p>You can</p>
    </div>
    <div class="panel panel5">
      <p>Life</p>
      <p>In</p>
      <p>Motion</p>
    </div>
  </div>

初始文档的 DOM 结构:以 .panels 为父 div 之下,有 5 个类名为 .panel 的 div,这 5 个各含有 3 个子 p 标签。而相应的 CSS 样式中,动画时间等特性已经设定好,只需要完成不同状态下的页面布局以及事件监听即可。

CSS 源码

  <style>
    html {
      box-sizing: border-box;
      background: #ffc600;
      font-family:'helvetica neue';
      font-size: 20px;
      font-weight: 200;
    }
    body {
      margin: 0;
    }
    *, *:before, *:after {
      box-sizing: inherit;
    }

    .panels {
      min-height:100vh;
      overflow: hidden;
      display: flex;
    }

    .panel {
      background:#6B0F9C;
      box-shadow:inset 0 0 0 5px rgba(255,255,255,0.1);
      color:white;
      text-align: center;
      align-items:center;
      /* Safari transitionend event.propertyName === flex */
      /* Chrome + FF transitionend event.propertyName === flex-grow */
      transition:
        font-size 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
        flex 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
        background 0.2s;
      font-size: 20px;
      background-size:cover;
      background-position:center;
      flex: 1;
      justify-content: center;
      display: flex;
      flex-direction: column;
    }


    .panel1 { background-image:url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500); }
    .panel2 { background-image:url(https://source.unsplash.com/1CD3fd8kHnE/1500x1500); }
    .panel3 { background-image:url(https://images.unsplash.com/photo-1465188162913-8fb5709d6d57?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&w=1500&h=1500&fit=crop&s=967e8a713a4e395260793fc8c802901d); }
    .panel4 { background-image:url(https://source.unsplash.com/ITjiVXcwVng/1500x1500); }
    .panel5 { background-image:url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500); }

    /* Flex Items */
    .panel > * {
      margin:0;
      width: 100%;
      transition:transform 0.5s;
      flex: 1 0 auto;
      display:flex;
      justify-content: center;
      align-items: center;
    }

    .panel > *:first-child { transform: translateY(-100%); }
    .panel.open-active > *:first-child { transform: translateY(0); }
    .panel > *:last-child { transform: translateY(100%); }
    .panel.open-active > *:last-child { transform: translateY(0); }

    .panel p {
      text-transform: uppercase;
      font-family: 'Amatic SC', cursive;
      text-shadow:0 0 4px rgba(0, 0, 0, 0.72), 0 0 14px rgba(0, 0, 0, 0.45);
      font-size: 2em;
    }
    .panel p:nth-child(2) {
      font-size: 4em;
    }

    .panel.open {
      flex: 5;
      font-size:40px;
    }

  </style>

CSS 在这个过程中占了重点,运用 flex 可以使各个元素按一定比例占据页面。在调试的时候,可以把边框显示出来方便查看效果。(border: 1px solid #f00;)

  1. 将 .panels 设置为 display:flex
  2. 设定每个子 panel 的 flex 值为 1
  3. 针对每个子 panel,设为 display:flex,设置其 flex 主轴方向
  4. 控制 .panle 的子元素 <p> 中的文字垂直、水平居中(单独看每个 panel,其中的文字也可以用 flex 的思路来使其三等分后居中)

    1. 设置为 display:flex
    2. 设置 flex 值
    3. 设置其子元素的布局方式:垂直水平居中(沿主轴、侧轴居中)
  5. 设定点击图片后文字移动的样式
  6. 设定点击图片展开后的图片的 flex 值

重要:不了解CSS和Flex的童鞋必看。

JS源码

  <script>
    const panels = document.querySelectorAll('.panel');

    function toggleOpen() {
      console.log('Hello');
      this.classList.toggle('open');
    }

    function toggleActive(e) {
      console.log(e.propertyName);
      if (e.propertyName.includes('flex')) {
        this.classList.toggle('open-active');
      }
    }

    panels.forEach(panel => panel.addEventListener('click', toggleOpen));
    panels.forEach(panel => panel.addEventListener('transitionend', toggleActive));
  </script>
  1. 获取所有类名为 panel 的元素
  2. 为其添加 click 事件监听,编写触发事件调用的函数(给触发的 DOM 元素添加/去掉样式,实现拉伸/压缩的效果)
  3. 为其添加 transitionend 事件监听,编写调用的函数(添加/去掉样式,实现文字的飞入/飞出效果)

源码下载

Github Source Code

春哥简介

简介: 资深讲师,全栈工程师;区块链、高可用架构技术爱好者。
个人博客:http://liyuechun.org
新浪微博:黎跃春-追时间的人
github:http://github.com/liyuechun

技术交流

  • 区块链技术交流QQ群:348924182
  • 「区块链部落」官方公众号

相关文章
|
9月前
|
人工智能 负载均衡 安全
探秘 AgentRun|流量一大就瘫痪?如何解决AI 模型调用之痛
阿里云函数计算AgentRun全新发布,推出“探秘AgentRun”系列,聚焦企业落地Agent的模型稳定性、安全与治理难题。通过统一模型管理、多模型接入、高可用治理策略(主备切换、负载均衡、智能路由等),实现生产级可靠调用。支持无代码快速搭建与高代码深度定制,助力Agentic AI高效进入生产环境。欢迎加入钉钉群134570017218交流体验。
|
算法 前端开发 数据可视化
数据结构与算法在前端开发中的实际应用
本文将探讨数据结构与算法在前端开发中的实际应用,重点介绍在处理大规模数据、优化性能和提升用户体验方面的具体场景和解决方案。
613 15
|
4月前
|
缓存 人工智能 安全
90% 的人不知道 Claude Code 还有插件系统!官方从未公开的 6 大组件深度拆解
本文深度拆解 Claude Code 插件系统的 6 大核心组件:Skills、Hooks、Agents、MCP、规则文件与配置系统,帮你快速上手插件开发与管理。
605 1
|
5月前
|
人工智能 API
90%的提示词方法正在失效:GPT-5.5发布后的真相
GPT-5.5发布后,传统提示词工程正快速失效:过度细化步骤反降效,OpenAI关停微调API,Karpathy宣告“提示词工程已死”。新范式转向Context与Harness Engineering——用Agent架构(Model+Harness)替代手写提示,聚焦目标定义、上下文编排与错误拦截机制。
467 1
|
5月前
|
开发框架 .NET Windows
dotnet-hosting-2.2.8-win安装步骤详解(附IIS部署与AspNetCoreModule配置)
`dotnet-hosting-2.2.8-win.exe`是.NET Core 2.2托管捆绑包安装程序,专为Windows服务器/开发机设计。安装后,IIS即可托管ASP.NET Core应用,内置运行时与AspNetCoreModule/V2模块。需先启用IIS,再以管理员身份运行安装。
|
7月前
|
SQL 程序员 数据处理
优化Python循环:从10秒到0.1秒的性能调优
本文以小李优化三百万行日志处理为例,详解Python循环性能瓶颈及七步调优法:精简循环体、预提方法、改用列表推导式、map/filter组合、避免重复转换、引入pandas等高效工具,最终将耗时从10秒降至0.1秒级。强调“先写对,再写快”,兼顾性能与可维护性。(239字)
406 8
|
7月前
|
JSON Shell API
淘宝 API(taobao.item.get) Python 调用 + 解析 + 数据反馈参考
下面给你一套可直接运行的淘宝 API Python 调用 + 解析 + 数据反馈参考,以最常用的 ** 商品详情(taobao.item.get)和商品搜索(taobao.item.search)** 为例,包含完整签名、请求、JSON 返回、解析代码与字段说明。
|
存储 安全 算法
【软件设计师备考 专题 】数据库的控制功能(并发控制、恢复、安全性、完整性)
【软件设计师备考 专题 】数据库的控制功能(并发控制、恢复、安全性、完整性)
575 0
|
人工智能 小程序 API
【一步步开发AI运动小程序】十七、如何识别用户上传视频中的人体、运动、动作、姿态?
【云智AI运动识别小程序插件】提供人体、运动、姿态检测的AI能力,支持本地原生识别,无需后台服务,具有速度快、体验好、易集成等优点。本文介绍如何使用该插件实现用户上传视频的运动识别,包括视频解码抽帧和人体识别的实现方法。
|
编解码 人工智能 自然语言处理

热门文章

最新文章