CSS3最强裁剪-实现GTA5封面

4,200 阅读13分钟

0.前情提要

介绍:我们 上一章 基本介绍 gird布局的基本使用,我们现在使用grid布局+clip-path裁剪来进行实现 GTA5封面,不熟悉 grid布局 可以查看我的上一章文章,我们先看实现效果

完成上面这种效果 首先需要clip-path 知识 本章知识将 带你复习 gird布局 和学习 clip-path 的基本使用

1.clip-path

1.介绍clip-path

​ 首先我要知道clip-path 是啥 它是实现裁剪元素,裁剪成我们想要的任意形状 如: 三角 形 五角星 菱形 不规则的形状 等,

下面的图形 就是通过clip-path 实现的,这个属性的出现不用我们在去拼接元素实现图形

img

2.clip弃用原因

其实在clip-path 出现之前还有一个裁剪属性 是clip 这个属性也是可以进行裁剪 但是他只能用于 绝对定位元素 已经弃用,

我们在这里不做过多赘述, 详情可以查看 MDN

3.兼容性

主流浏览器的支持情况

  • Chrome:全面支持 clip-path,包括最新版本和相对较早的版本。
  • Firefox:支持 clip-path,并且支持大多数剪切路径形状和 SVG 路径。
  • Safari:从 Safari 10 开始支持 clip-path,但具体支持情况可能取决于具体的版本。
  • Edge:最新版本的 Edge (基于 Chromium) 支持 clip-path,而较早的 Edge (非 Chromium) 支持较差。
  • Opera:和 Chrome 类似,Opera 支持 clip-path

移动浏览器支持

  • iOS Safari:支持 clip-path,但建议测试特定版本的兼容性,因为支持情况可能有所不同。
  • Android 浏览器:Chrome for Android 和 Firefox for Android 通常对 clip-path 的支持较好,但建议在不同的设备上进行测试。

浏览兼容详情 点击查看

4.基本使用

它的属性有:inset circle ellipse polygon path

说明
inset裁剪出一个矩形
circle裁剪出一个圆形
ellipse裁剪出一个椭圆
polygon裁剪出一个多边形
path裁剪出一个任意形状(使用一个可选的 SVG 填充规则和一个 SVG 路径定义)。
1.inset
1.设置参数 1-2 值
  • clip-path: inset(30px); 控制裁剪矩形整体大小 clip-path: inset(30px 50px); 第一个参数控制上下两侧参数 第二个参数控制矩形左右两侧参数

<!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>
      .content {
        width: 100%;
        display: flex;
        margin: 20% auto;
        justify-content: center;
        align-items: center;
      }
      .box {
        width: 200px;
        height: 200px;
        background-color: red;
        margin-right: 40px;
        clip-path: inset(30px);
      }
      .box1 {
        width: 200px;
        height: 200px;
        background-color: red;
        clip-path: inset(30px 50px);
      }
    </style>
  </head>
  <body>
    <div class="content">
      <div class="box"></div>
      <div class="box1"></div>
    </div>
  </body>
</html>

2.设置参数 3 - 4 值
  • clip-path: inset(100px 30px 50px); 第一个参数控制上测参数 第二个参数控制左右两侧参数 第三个参数控制下侧参数 clip-path: insetinset(20px 89px 50px 40px); 第一个参数控制上测参数 第二个参数控制右两侧参数 第三个参数控制下侧参数 第四个参数控制左侧参数
      .box {
        clip-path: inset(30px 20px 50px);
      }
      .box1 {
        clip-path: inset(20px 30px 50px 40px);
      }
3.使用round
  • round 类似于 border-redius
  • 叶子形状 第一个参数控制 整体大小 第二个参数将角变成round 第三个参数控制左上角 和右下角 第四个参数控制右上角 和左下角
clip-path: inset(10px round 152px 5px);
  • 扇形 第一个参数控制 整体大小 第二个参数将角变成round 第三个参数控制左上角 第四个参数控制右上角 和左下角 第五个参数控制 右下角
clip-path: inset(10px round 20px 10px 150px); 
 clip-path: inset(10px 20px 10px 30px round 20px);  // 控制四边圆角为20px
  • 注意:round 不能放到第一个, round 后面必须跟跟值 , 使用了round 不能输入负数否则无效
   clip-path: inset(round 10px); // 错误写法
   clip-path: inset(10px round ); // 错误写法
2.circle
  • circle 裁剪出一个圆

  • 第一个参数可以是 数值 也可以是 closest-sidefarthest-side

  • 第二个参数 at 关键字 后面控制圆的中心位置 有x轴y轴 默认圆中心 center center

1.基本使用
      .box {
        width: 200px;
        height: 200px;
        background-color: #ffb700;
        margin-right: 40px;
        clip-path: circle(50px);
    }
2.控制圆心
  • at 关键字后面 设置圆心位置 可以 是方向值 可以是 数字值
    <style>
      .content {
        width: 200px;
        height: 400px;
        display: flex;
        margin: 20% auto;
        justify-content: center;
        align-items: center;
        background-color: blue;
      }
      .box {
        width: 200px;
        height: 200px;
        background-color: #ffb700;
        margin-right: 40px;
        clip-path: circle(6rem at right center);
      }
    </style>
  </head>
  <body>
    <div class="content">
      <div class="box"></div>
    </div>
  </body>
   <style>
      .content {
        width: 200px;
        display: flex;
        margin: 20% auto;
        justify-content: center;
        align-items: center;
        background-color: bisque;
      }
      .box {
        width: 200px;
        height: 200px;
        background-color: #ffb700;
        margin-right: 40px;
        clip-path: circle(10% at 2rem 90%);
      }

    </style>
  </head>
  <body>
    <div class="content">
      <div class="box"></div>
    </div>
  </body>
3.closest-side与 farthest-side 区别
  • 使用 closest-side 时,裁剪出的圆会尽量小,以确保它不会超出矩形的边界。

  • 使用 farthest-side 时,裁剪出的圆会尽量大,以确保它能够覆盖到矩形的边界。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Clip Path Example</title>
    <style>
      .container {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 95vh;
        margin-top: 20px;
      }
      .rectangle {
        width: 60px; /* 更小的宽度 */
        height: 30px; /* 更小的高度 */
        background-color: #25bc34;
      }
      .ellipse-closest {
        clip-path: circle(closest-side at 50% 50%);
      }
      .ellipse-farthest {
        clip-path: circle(farthest-side at 50% 50%);
      }
      .box {
        border: 1px solid black;
        padding: 10px;
        margin-right: 50px;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="box">
        <div class="rectangle ellipse-closest"></div>
        <p>closest-side</p>
      </div>
      <div class="box">
        <div class="rectangle ellipse-farthest"></div>
        <p>farthest-side</p>
      </div>
    </div>
  </body>
</html>

3.ellipse
  • 其实 eslipse circle 差不多的,就是在第一个参数能传入 两个参数
1.基本使用
  • 裁剪出一个椭圆

  • 第一个参数 控制左右 第二个参数控制 上下

  • at 关键字 后面控制圆的中心位置 默认圆中心 center center

clip-path: ellipse(20px 50px);
2.控制圆心
  • at 关键字后面 设置圆心位置 可以 是方向值 可以是 数字值
 clip-path: ellipse(4rem 50% at right center);
3.closest-side与 farthest-side 区别
  • 其实closest-side farthest-side 属性区别跟 circle 是一样的
  • 使用 closest-side 时,裁剪出的圆会尽量小,以确保它不会超出矩形的边界。
  • 使用 farthest-side 时,裁剪出的圆会尽量大,以确保它能够覆盖到矩形的边界。
  • 为了更明显地展示区别,我们可以:
    1. 改变椭圆的中心位置,使其不在元素的中心。
    2. 改变元素的尺寸比例,使宽高有明显差异。
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Clip Path - Ellipse Difference</title>
    <style>
      .container {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
      }

      .box {
        width: 300px;
        height: 200px;
        background-color: red;
        background-size: cover;
        position: relative;
      }

      .closest-side {
        margin-right: 30px;
        clip-path: ellipse(closest-side closest-side at 50% 68%);
      }

      .farthest-side {
        clip-path: ellipse(farthest-side farthest-side at 50% 68%);
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="box closest-side" data-text="Closest Side"></div>
      <div class="box farthest-side" data-text="Farthest Side"></div>
    </div>
  </body>
</html>

4.polygon
  • 这个属性是clip-path 使用最广泛的,它可以裁剪任意图形
  • polygon() 的参数用逗号和可选的空格分隔。它的参数格式是 x1 y1,x2 y2,x3 y3 ...... 最少 3对参数
1.画一个三角形
  • 我们之前画三角形 用的border去画三角形 我们用clip-path 只需要一行代码
<style>
      .content {
        width: 400px;
        height: 400px;
        display: flex;
        margin: 20% auto;
        justify-content: center;
        align-items: center;
        background-color: #030303;
      }
      .box {
        width: 200px;
        height: 200px;
        background-color: #ffb700;
        margin-right: 40px;
        clip-path: polygon(50% 0%, 0% 100%, 100% 100%); // 这一行代码 画出三角形
      }
    </style>
  </head>
  <body>
    <div class="content">
      <div class="box"></div>
    </div>
  </body>
2.使用 bennettfeely 网站拖拽图形

在我们做复杂图形不可能手调出来这样太浪费时间了,我们可以使用这个 网站 拖拽实现我们想要的图形

3.画一个对话框
    <style>
      .content {
        width: 400px;
        height: 400px;
        display: flex;
        margin: 20% auto;
        justify-content: center;
        align-items: center;
        background-color: #030303;
      }
      .box {
        display: flex;
        justify-content: center;
        align-items: center;
        box-sizing: border-box;
        padding-bottom: 53px;
        font-weight: 600;
        width: 200px;
        height: 200px;
        background-color: #f9f9f9;
        margin-right: 40px;
        clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 75%, 75% 100%, 50% 75%, 0% 75%);
      }
    </style>
  </head>
  <body>
    <div class="content">
      <div class="box">你干嘛啊!哎哟</div>
    </div>
  </body>
5.path
1.基本使用
  • path 里面接收的svg 路径 我们通过 Gpt生成一段svg 五角星的路径
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Clip Path - Star</title>
    <style>
      .star {
        margin: 20% auto;
        width: 150px;
        height: 150px;
        background-color: #e6adad;
         clip-path: path(
          'M 150 0 L 184 112 L 300 112 L 207 175 L 241 288 L 150 225 L 59 288 L 93 175 L 0 112 L 116 112 Z'
        );
      }
    </style>
  </head>
  <body>
    <div class="star"></div>
  </body>
</html>

2.svg写字html中
  • 在html中clipPath 定义idcss 通过url(#starClipPath) 接收路径;
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Clip Path - Star</title>
    <style>
      .star {
        margin: 20% auto;
        width: 150px;
        height: 150px;
        background-color: #e6adad;
        clip-path: url(#starClipPath);
      }
    </style>
  </head>
  <body>
    <!-- 定义SVG路径 -->
    <svg width="0" height="0">
      <defs>
        <clipPath id="starClipPath" clipPathUnits="objectBoundingBox">
          <path
            d="M 0.5 0 L 0.61 0.37 L 1 0.37 L 0.68 0.59 L 0.79 1 L 0.5 0.75 L 0.21 1 L 0.32 0.59 L 0 0.37 L 0.39 0.37 Z"
          />
        </clipPath>
      </defs>
    </svg>
    <div class="star"></div>
  </body>
</html>

2.实现GTA5封面

我们前面通过大篇幅去讲解 clip-path的使用 ,总算进入正题了,我们看看我们最终需要实现的结果

1.构思思路

布局我们采用grid布局 ,当然你可以使用 flex布局 float布局 只是相对于实现起来比较麻烦

首先我们上来看到这个效果 首先我们通过gird布局需要想一下怎么去划分

2.开始布局

1.划分行列

首先我们划分 我的想法 生成一个4*4的网格 ,当然你如果有更好的想法可以试试

·

这里在讲一个知识点gird布局网格 红线是怎么调出来的 我们 按一下f12 打开控制台

<!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>
      .box {
        display: grid;
        grid-template-columns: 180px 180px 1fr 180px;
        grid-template-rows: 20% 40% 20% 20%;
        width: 100%;
        max-width: 600px;
        min-height: 500px;
        border: 5px solid #dee906;
        height: 700px;
        background-color: #000000;
        margin: 0 auto;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div>1</div>
      <div>2</div>
      <div>3</div>
      <div>4</div>
      <div>5</div>
      <div>6</div>
      <div>7</div>
      <div>8</div>
      <div>9</div>
    </div>
  </body>
</html>

2.命名空间
  • 我们可以采用 gird布局的命名空间实现GTA5的布局
      grid-template-areas:
          'one two two three'
          'four five five five'
          'six five five five'
          'six seven eight eight';
3.给子元素添加上名字
  • 是不是感觉有那味道了,此时有很多 同学 这里应该有疑惑了,
  • 第九个元素我们没有给她命名,为啥占用了five的格子
    • 其实不然 第九个元素我们用了网格的定位就直接覆盖在 第五个元素上
    • 为什么要这么做? 因为grid 布局 它的局限就是只能布局成为一个矩形 要完成其他形状只能这样
<!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>
      .box {
        display: grid;
        grid-template-columns: 180px 180px 1fr 180px;
        grid-template-rows: 20% 40% 20% 20%;
        width: 100%;
        max-width: 600px;
        min-height: 500px;
        border: 5px solid #dee906;
        height: 700px;
        background-color: #000000;
        margin: 0 auto;
        grid-template-areas:
          'one two two three'
          'four five five five'
          'six five five five'
          'six seven eight eight';
      }
      .box div:nth-child(1) {
        grid-area: one;
        background-color: azure;
      }
      .box div:nth-child(2) {
        grid-area: two;
        background-color: #f5c60a;
      }
      .box div:nth-child(3) {
        grid-area: three;
        background-color: #0adaf5;
      }

      .box div:nth-child(4) {
        grid-area: four;
        background-color: #f700ff;
      }
      .box div:nth-child(5) {
        grid-area: five;
        background-color: #700af5;
      }
      .box div:nth-child(6) {
        grid-area: six;
        background-color: #0af5ba;
      }
      .box div:nth-child(7) {
        grid-area: seven;
        background-color: #b87dd7;
      }
      .box div:nth-child(8) {
        grid-area: eight;
        background-color: #637fe7;
      }
      .box div:nth-child(9) {
        grid-column-start: 2;
        grid-column-end: span 1;
        grid-row-start: 3;
        grid-row-end: 4;
        background-color: #df8975;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div>1</div>
      <div>2</div>
      <div>3</div>
      <div>4</div>
      <div>5</div>
      <div>6</div>
      <div>7</div>
      <div>8</div>
      <div>9</div>
    </div>
  </body>
</html>

4.进行裁剪

用刚刚我们的 拖拽裁剪实现我们想要的图形bennettfeely

  .box div:nth-child(1) {
        grid-area: one;
        background-color: azure;
        clip-path: polygon(0% 0%, 88% 0, 113% 97%, 0% 87%);
      }
      .box div:nth-child(2) {
        grid-area: two;
        background-color: #f5c60a;
        clip-path: polygon(0% 0%, 100% 0%, 84.45% 97%, 15.55% 95%);
      }
      .box div:nth-child(3) {
        grid-area: three;
        background-color: #0adaf5;
        clip-path: polygon(12% 0%, 100% 0%, 100% 87%, -9% 96%);
      }

      .box div:nth-child(4) {
        grid-area: four;
        background-color: #f700ff;
        clip-path: polygon(0% 0.15%, 106.34% 4.98%, 121.32% 65.63%, 99.66% 100.89%, 0% 102.41%);
      }
      .box div:nth-child(5) {
        grid-area: five;
        background-color: #700af5;
        clip-path: polygon(
          6.4% 3.48%,
          64.24% 1.59%,
          100% 0%,
          100% 95%,
          47% 100%,
          47% 63.21%,
          6.23% 67.02%,
          15.3% 44.04%
        );
      }
      .box div:nth-child(6) {
        grid-area: six;
        background-color: #0af5ba;
        clip-path: polygon(0 9.3%, 100% 5.42%, 100.14% 100.82%, 0% 100%);
      }
      .box div:nth-child(7) {
        grid-area: seven;
        background-color: #b87dd7;
        clip-path: polygon(5.92% 18.47%, 99.31% 6.39%, 98.38% 100%, 5.3% 100.85%);
      }
      .box div:nth-child(8) {
        grid-area: eight;
        background-color: #637fe7;
        clip-path: polygon(5% 9.35%, 100% 0%, 101% 100%, 5% 100%);
      }
      .box div:nth-child(9) {
        grid-column-start: 2;
        grid-column-end: span 1;
        grid-row-start: 3;
        grid-row-end: 4;
        background-color: #df8975;
        clip-path: polygon(6.5% 12.35%, 100% 0%, 100% 100%, 5.55% 100%);
      }
5.把图片放进去,进行微调
  • 将图片设置为 100% * 100%
<!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>
      .box {
        display: grid;
        grid-template-columns: 180px 180px 1fr 180px;
        grid-template-rows: 20% 40% 20% 20%;
        width: 100%;
        max-width: 600px;
        min-height: 500px;
        border: 5px solid #dee906;
        height: 700px;
        background-color: #000000;
        margin: 0 auto;
        grid-template-areas:
          'one two two three'
          'four five five five'
          'six five five five'
          'six seven eight eight';
      }
      .box div img {
        width: 100%;
        height: 100%;
        object-fit: cover;
        object-position: 70% 4%;
        cursor: pointer;
      }
      .box div:nth-child(1) {
        grid-area: one;
        background-color: azure;
        clip-path: polygon(0% 0%, 88% 0, 113% 97%, 0% 87%);
      }
      .box div:nth-child(2) {
        grid-area: two;
        background-color: #f5c60a;
        clip-path: polygon(0% 0%, 100% 0%, 84.45% 97%, 15.55% 95%);
      }
      .box div:nth-child(3) {
        grid-area: three;
        background-color: #0adaf5;
        clip-path: polygon(12% 0%, 100% 0%, 100% 87%, -9% 96%);
      }

      .box div:nth-child(4) {
        grid-area: four;
        background-color: #f700ff;
        clip-path: polygon(0% 0.15%, 106.34% 4.98%, 121.32% 65.63%, 99.66% 100.89%, 0% 102.41%);
      }
      .box div:nth-child(5) {
        grid-area: five;
        background-color: #700af5;
        clip-path: polygon(
          6.4% 3.48%,
          64.24% 1.59%,
          100% 0%,
          100% 95%,
          47% 100%,
          47% 63.21%,
          6.23% 67.02%,
          15.3% 44.04%
        );
      }
      .box div:nth-child(6) {
        grid-area: six;
        background-color: #0af5ba;
        clip-path: polygon(0 9.3%, 100% 5.42%, 100.14% 100.82%, 0% 100%);
      }
      .box div:nth-child(7) {
        grid-area: seven;
        background-color: #b87dd7;
        clip-path: polygon(5.92% 18.47%, 99.31% 6.39%, 98.38% 100%, 5.3% 100.85%);
      }
      .box div:nth-child(8) {
        grid-area: eight;
        background-color: #637fe7;
        clip-path: polygon(5% 9.35%, 100% 0%, 101% 100%, 5% 100%);
      }
      .box div:nth-child(9) {
        grid-column-start: 2;
        grid-column-end: span 1;
        grid-row-start: 3;
        grid-row-end: 4;
        background-color: #df8975;
        clip-path: polygon(6.5% 12.35%, 100% 0%, 100% 100%, 5.55% 100%);
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div>
        <img src="https://pic1.zhimg.com/80/v2-43f6cf9519c6c22f9525f8859bb92018_720w.png" alt="" />
      </div>
      <div>
        <img src="https://picx.zhimg.com/80/v2-8b5444e66efaf9c1833f98c8fdd2b40b_720w.png" alt="" />
      </div>
      <div>
        <img
          src="https://pica.zhimg.com/80/v2-9e4351256c80b09f8e900fb3a1531e65_720w.png"
          alt=""
        />
      </div>
      <div>
        <img src="https://picx.zhimg.com/80/v2-0ce6321f90c5b2647de365a9c2a46843_720w.png" alt="" />
      </div>
      <div>
        <img
          src="https://pic1.zhimg.com/80/v2-5f68ee395d2d55594f01b2c93812c708_720w.png"
          alt=""
        />
      </div>
      <div>
        <img src="https://picx.zhimg.com/80/v2-5f1f3fe4a818f26efb6c3b6948348ed2_720w.png" alt="" />
      </div>
      <div>
        <img
          src="https://picx.zhimg.com/80/v2-0ce8562e34c139bad8c2062ecf2a72e0_720w.png"
          alt=""
        />
      </div>
      <div>
        <img src="https://picx.zhimg.com/80/v2-823eae68c186072961c9029ed621f19b_1440w.png" alt="" />
      </div>
      <div>
        <img
          src="https://pic1.zhimg.com/80/v2-134c068adac02da200d0ee80b486be0d_720w.png"
          alt=""
        />
      </div>
    </div>
  </body>
</html>

6.调整第四张图片大小,添加放大过渡效果
  • 最终就实现了这个效果
   .box div img {
        width: 100%;
        height: 100%;
        object-fit: cover;
        object-position: 70% 4%;
        cursor: pointer;
        transition: all 0.4s;
   }  
   div:nth-child(4) img {
        width: 135%;
        height: 135%;
  }
  .box div img:hover {
        transform: scale(1.4);
   }

还是不太懂的兄弟们 可以 评论哦,我看到会及时回复的