源本科技 | 码上会

画卷折叠效果

2026/01/26
10
0

题目

使用 HTML 和 CSS 实现一个具有折叠动画效果的画卷展示。当鼠标悬停在画作上时,画作的不同部分会以不同的角度翻折,产生立体感和动态视觉效果。

说明

这个练习题旨在通过 CSS 实现一个具有视觉冲击力的画卷折叠效果。具体要求如下:

  • 展示一幅图片,并将其分割成四个部分(每个span元素代表一部分)

  • 当鼠标悬停在画布上时,各个部分应根据其位置(奇数或偶数)以不同的角度翻折

  • 图片背景需要设置为指定的图片,并且每部分显示不同区域的图片内容

  • 使用伪 3D 效果增强视觉体验,如阴影、边框等

该效果主要依赖于:

  • CSS 变量(--i)用于控制背景图片的位置偏移

  • transform属性进行旋转、倾斜等操作创建折叠效果

  • box-shadow添加内阴影,增加立体感

  • 过渡效果(transition)使变换更加平滑自然

运行示例

  1. 页面初始状态:显示一幅被分成四块的图片,每块有白色边框,整体向左下角倾斜一定角度

  2. 鼠标悬停时:奇数块向上翻折,偶数块向下翻折,同时各块出现内阴影,模拟出立体的折叠效果

  3. 悬停结束后:所有块恢复原状


👈点击左箭头查看答案(一定要在自己思考并实现后再看参考答案哦!)

规律分析

  1. 结构设计

    • 使用div作为容器,包含四个span子元素,每个子元素表示图片的一部分

    • 利用 CSS 变量var(--i)动态调整背景位置,使得每个span显示图片的不同区域

  2. 动画原理

    • 通过hover伪类触发变换效果

    • 奇数和偶数子元素分别应用不同的skewY值来制造相反方向的折叠效果

    • box-shadowinset参数用于创建内部阴影,强化折叠的立体感

  3. 样式细节

    • 边界处额外添加了 5px 宽的白色边框,增强分隔感

    • transition保证了变换过程中的流畅性

程序实现

<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <title>画卷折叠效果</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      body {
        display: flex;
        justify-content: center;
        align-items: center;
        min-height: 100vh;
        background: #444;
      }
      div {
        width: 640px;
        height: 360px;
        display: flex;
        transition: 0.5s;
        transform: rotate(-25deg) skew(25deg) translate(0,0);
      }
      div:hover {
        transform: rotate(-25deg) skew(-25deg) translate(0,-20px);
      }
      div span {
        list-style: none;
        width: 25%;
        background: url('001.jpg');
        background-position: calc(-160px * var(--i));
        background-size: cover;
        height: 100%;
        transition: .5s;
        border-top: 5px solid #fff;
        border-bottom: 5px solid #fff;
      }
      div:hover span:nth-child(odd) {
        transform: skewY(25deg);
        box-shadow: inset 20px 0 50px rgba(0,0,0,.5);
      }
      div:hover span:nth-child(even) {
        transform: skewY(-25deg);
        box-shadow: inset 20px 0 50px rgba(0,0,0,.5);
      }
      div span:first-child {
        border-left: 5px solid #fff;
      }
      div span:last-child {
        border-right: 5px solid #fff;
      }
    </style>
  </head>
  <body>
    <div>
      <span style="--i:0;"></span>
      <span style="--i:1;"></span>
      <span style="--i:2;"></span>
      <span style="--i:3;"></span>
    </div>
  </body>
</html>