自学内容网 自学内容网

四、CSS效果

一、box-shadow

box-shadow:在元素的框架上添加阴影效果 

/* x 偏移量 | y 偏移量 | 阴影颜色 */
box-shadow: 60px -16px teal;

/* x 偏移量 | y 偏移量 | 阴影模糊半径 | 阴影颜色 */
box-shadow: 10px 5px 5px black;

/* x 偏移量 | y 偏移量 | 阴影模糊半径 | 阴影扩散半径 | 阴影颜色 */
box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2);

/* 插页 (阴影向内) | x 偏移量 | y 偏移量 | 阴影颜色 */
box-shadow: inset 5em 1em gold;

/* 任意数量的阴影,以逗号分隔 */
box-shadow:
  3px 3px red,
  -1em 0 0.4em olive;

/* 全局关键字 */
box-shadow: inherit;
box-shadow: initial;
box-shadow: unset;
 

参考:box-shadow - CSS:层叠样式表 | MDN

课程示例:

未加box-shadow效果:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .container{
            background:red;
            width:200px;
            height:200px;
            margin: 100px;
            /* box-shadow: 5px 5px 10px 0 rgba(0,0,0,.2); */
            /* box-shadow: inset 5px 5px 10px 0 rgba(0,0,0,.2); */
            /* box-shadow: 0 0 0 5px green; */
        }
    </style>
</head>
<body>
    <div class="container">
    </div>
</body>
</html>

box-shadow基本用法:

/* box-shadow: x轴(水平)偏移 y轴(垂直)偏移 模糊区域半径 阴影扩散半径 阴影颜色; */
box-shadow: 5px 5px 10px 0 rgba(0,0,0,.2);  //这里加了个浅灰色的半透明阴影

如果阴影不明显的话,透明系数可以调到0.5。

增加阴影扩散区域10px

加了阴影扩散区域10px,阴影区域明显比之前大了一些。

/* box-shadow: (阴影向内) x轴(水平)偏移 y轴(垂直)偏移 模糊区域半径 阴影扩散半径 阴影颜色; */
box-shadow: inset 5px 5px 10px 0 rgba(0,0,0,.2);

/* box-shadow: x轴(水平)偏移 y轴(垂直)偏移 模糊区域半径 扩散半径 阴影颜色; */
box-shadow: 0 0 0 5px green; /*这里只给了5px的扩散*/

当扩张区域为负值,会是什么效果?

首先,为了效果明显,我们加大数值

box-shadow: 100px 100px 0 5px green;

扩展区域调为负值,调整为-20px

box-shadow: 100px 100px 0 -20px green;

调整为-50px

box-shadow: 100px 100px 0 -50px green;

可以看到,扩展半径调整为负值,随着负值越来越大,扩展大小越来越小。 

box-shadow高级用法:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .container{
            background:red;
            width:10px;
            height:10px;
            margin: 10px;
            border-radius: 5px;
            box-shadow: 200px 200px 0 5px green,
                230px 200px 0 5px green,
                215px 215px 0 -3px red;
        }
    </style>
</head>
<body>
    <div class="container">
    </div>
</body>
</html>

这里设置border-radius: 5px;,而width:10px、height:10px,导致看起来就是个圆形,设置为border-radius: 5px,阴影也会变成圆形。

为什么写这个例子呢,就是我们需要知道,可以通过这个投影可以做许多的效果。

再看一个利用投影做出来的效果:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .container{
            position: relative;
            width: 36px;
            height: 36px;
            border-radius: 50%;
            margin: 300px auto;
            background-color: #C63D01;
            box-shadow: 0px 0px 0 1px #000,
                -20px -26px 0 -10px #333333,
                -34px -40px 0 15px #fff,
                -34px -40px 0 16px,
                20px -26px 0 -10px #333333,
                34px -40px 0 15px #fff,
                34px -40px 0 16px,
                0px 55px 0 75px #fff,
                0px 55px 0 76px #000,
                0 22px 0 120px #08BDEB,
                0 22px 0 121px #000;
        }
        /*叮当猫的鼻子*/
        .container::before{
            content: '';
            position: absolute;
            bottom: -81px;
            left: 17px;
            height: 80px;
            width: 2px;
            background-color: #000;
        }
        /*叮当猫的嘴巴*/
        .container::after{
            content: '';
            position: absolute;
            bottom: -83px;
            left: -44px;
            width: 125px;
            height: 70px;
            border-bottom-right-radius: 28px;
            border-bottom: solid 2px black;
            border-bottom-left-radius: 28px;
        }
    </style>
</head>
<body>
    <div class="container">
    </div>
</body>
</html>

具体实现步骤:

第一步:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .container{
            position: relative;
            width: 36px;
            height: 36px;
            border-radius: 50%;
            margin: 300px auto;
            background-color: #C63D01;
            /* box-shadow: 0px 0px 0 1px #000,
                -20px -26px 0 -10px #333333,
                -34px -40px 0 15px #fff,
                -34px -40px 0 16px,
                20px -26px 0 -10px #333333,
                34px -40px 0 15px #fff,
                34px -40px 0 16px,
                0px 55px 0 75px #fff,
                0px 55px 0 76px #000,
                0 22px 0 120px #08BDEB,
                0 22px 0 121px #000; */
        }
        /*叮当猫的鼻子*/
        /* .container::before{
            content: '';
            position: absolute;
            bottom: -81px;
            left: 17px;
            height: 80px;
            width: 2px;
            background-color: #000;
        } */
        /*叮当猫的嘴巴*/
        /* .container::after{
            content: '';
            position: absolute;
            bottom: -83px;
            left: -44px;
            width: 125px;
            height: 70px;
            border-bottom-right-radius: 28px;
            border-bottom: solid 2px black;
            border-bottom-left-radius: 28px;
        } */
    </style>
</head>
<body>
    <div class="container">
    </div>
</body>
</html>

放开box-shadow

大白话:

1.营造层次感(立体感)- 可以通过向内或向外扩散阴影实现;

2.充当没有宽度的边框 - 当你的排版不能有边框,而又想要边框效果,就可以使用box-shadow扩散边框效果;

3.特殊效果 - 比如想画某种图案,可以通过box-shadow实现。

二、text-shadow_x264:文字阴影

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .container{
            margin:0 auto;
            max-width: 800px;
            font-size: 18px;
            line-height: 2em;
            font-family: STKaiti;
            /* text-shadow: 1px 1px 0 #aaa; */
            /* text-shadow: 0 0 1px rgba(128,128,128,.2); */
            /* background: black; */
            /* text-shadow: -1px -1px 0 white,
                -1px 1px 0 white,
                1px -1px 0 white,
                1px 1px 0 white; */
            /* text-shadow: 0 0 2px white; */
        }
        .container p{
            text-indent: 2em;
        }
    </style>
</head>
<body>
    <div class="container">
        <p>我与父亲不相见已二年余了,我最不能忘记的是他的背影。那年冬天,祖母死了,父亲的差使也交卸了,正是祸不单行的日子,我从北京到徐州,打算跟着父亲奔丧回家。到徐州见着父亲,看见满院狼藉的东西,又想起祖母,不禁簌簌地流下眼泪。父亲说,“事已如此,不必难过,好在天无绝人之路!”</p>
        <p>回家变卖典质,父亲还了亏空;又借钱办了丧事。这些日子,家中光景很是惨淡,一半为了丧事,一半为了父亲赋闲。丧事完毕,父亲要到南京谋事,我也要回北京念书,我们便同行。</p>
        <p>到南京时,有朋友约去游逛,勾留了一日;第二日上午便须渡江到浦口,下午上车北去。父亲因为事忙,本已说定不送我,叫旅馆里一个熟识的茶房陪我同去。他再三嘱咐茶房,甚是仔细。但他终于不放心,怕茶房不妥帖;颇踌躇了一会。其实我那年已二十岁,北京已来往过两三次,是没有甚么要紧的了。他踌躇了一会,终于决定还是自己送我去。我两三回劝他不必去;他只说,“不要紧,他们去不好!”</p>
    </div>
</body>
</html>

增加text-shadow

text-shadow: 1px 1px 0 #aaa;

现在看起来,更有立体感了。

text-shadow: 0 0 1px rgba(128,128,128,.2);

未使用前:

使用后:

加上模糊,看起来颜色变深了,区别不是那么明显(PC上效果不明显,移动端上效果明显),这就是所说的印刷品质感,就是当油墨印刷到纸上,有部分油墨渗透进纸张内,造成字体模糊的感觉。

当在复杂的页面,字体不太明显时,可以看下下面效果:

三、border-radius:圆角

课程示例:

未修改前的效果:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .container{
            width: 100px;
            height: 100px;
            background: red;
            /* border: 10px solid green; */
            /* border-radius: 10px; */
            /* border-radius: 50%; */
            /*border: 50px solid green;
            border-top-left-radius: 100px 50px;
            border-top-right-radius: 0;
            border-bottom-left-radius: 0;
            border-bottom-right-radius: 0;*/
            border-radius: 10px 10px 10px 10px / 20px 20px 20px 20px;
        }
    </style>
</head>
<body>
    <div class="container">
    </div>
</body>
</html>

容器的当前宽和高分别为100px,当加上

border-radius: 50%;

当没有边框的时候,容器变成了圆形

现在,我们加上边框

border: 10px solid green;

边框也变成了圆形。

这是,设置border-radius:50px

border-radius:50px

发现,里边的就是圆形的,但是外边的边框就不那么圆了。这是因为,边框还有10px,所有我们将border-redius:60px,再看效果:

border-radius:60px

发现边框终于变圆了,要注意这点差异,所以,我们一般使用的时候,直接写50%就好了。 

除了使用border-radius,我们还可以使用更详细的样式:

border: 50px solid green;
border-top-left-radius: 100px 50px;
border-top-right-radius: 0;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;

如果去掉border,会怎么样呢?

border-radius除了支持圆形以外,还支持更多的写法。

两个半径不一样效果:

border-radius: 10px 10px 10px 10px / 20px 20px 20px 20px;

绿框内,容器的四个角不再是圆形了,有点想椭圆的形状。

同样,也可以拆开写四个角:

            border: 50px solid green;
            border-top-left-radius: 100px 50px;
            border-top-right-radius: 0;
            border-bottom-left-radius: 0;
            border-bottom-right-radius: 0;

如果将边框为成0,效果怎么样?

修改边框4个角

这样,我们控制4个角的值,做出各种奇怪的图案。

之前哆啦A梦的两个胡须就可以通过控制下面2个角的角度做起来

四、background:背景

雪碧图动画
 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .container{
        }
        .i{
            width: 20px;
            height: 20px;
            background: url(./background.png) no-repeat;
            background-size: 20px 40px;
            transition: background-position .4s;
        }
        .i:hover{
            background-position: 0 -20px;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="i"></div>
    </div>
</body>
</html>

background-position:指定背景图像在元素中出现的位置

transition:动画过渡效果

参考:https://juejin.cn/post/7328621062727745536#%E4%B8%80%EF%BC%9Atransition%20%E8%BF%87%E6%B8%A1%E6%95%88%E6%9E%9C

课程示例2:

panda.jpg

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .container{
            width: 400px;
            height: 300px;
            border: 1px solid red;
            background:url(./panda.jpg);
            /* background-size: contain; */
            /* background-repeat: no-repeat; */
            /* background-position: center center; */
            /* background-size: cover; */
        }
    </style>
</head>
<body>
    <div class="container">
    </div>
</body>
</html>

通过上面页面,可以看到图片是比容器大的,所以只能显示一部分图片区域。

想让背景图居中,看下面代码:

background-position: center center;

对比上面的页面,可以看到图片是横向居中,垂直居中的,但是还是没有显示全,耳朵部分没有显示全。

修改下代码:

background-position: center top;

设置背景图的大小

background-size: 200px 100px;
background-size: 50% 50%;
background-size: cover; /*覆盖整个画面,同时保持长宽比不变*/
background-size: contain; /*多余的地方空白出来,同时保持长宽比不变*/

先看下background-size: cover效果:

看下background-size:contain效果:

设置背景图铺排方式:

background-repeat: no-repeat - 背景图像不平铺; 
background-repeat:  repeat-x - 背景图像在横向上平铺;
background-repeat:  repeat-y - 背景图像在纵向上平铺;
background-repeat:  repeat - 背景图像在横向和纵向平铺;
background-repeat:  round - 当背景图像不能以整数次平铺时,会根据情况缩放图像;
background-repeat:  space - 当背景图像不能以整数次平铺时,会用空白间隙填充在图像周围;

五、clip-path: 按路径裁剪

按容器进行裁剪 - 可以指定显示容器的一部分显示,另一部分被裁剪掉

未裁剪之前的效果:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .container{
            width: 400px;
            height: 300px;
            border: 1px solid red;
            background:url(./panda.jpg);
            background-size: cover;
            background-repeat: no-repeat;
            background-position: center center;
            padding:10px;
            /* clip-path: inset(100px 50px); */
            /* clip-path: circle(50px at 100px 100px); */
            /* clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%, 10% 10%, 40px 10px); */
            /* clip-path: url(#clipPath); */
            /* background-size: cover; */
            /* transition:clip-path .4s; */
        }
        .container:hover{
            /* clip-path: circle(80px at 100px 100px); */
        }
    </style>
</head>
<body>
    <div class="container">
        你好,我是熊猫
    </div>
    <svg>
        <defs>
            <clipPath id="clipPath">
                <!-- <circle cx="60" cy="60" r="50" fill="#34538b" /> -->
                <polygon stroke="#979797" points="0.4921875 81.2070313 92.640625 81.2070313 121.601562 0.21875 153.648437 81.2070313 247.390625 80.7734375 173.394531 140.496094 200.308594 227.09375 121.601562 172.71875 53.4960937 227.09375 80.859375 140.496094"></polygon>
            </clipPath>
        </defs>
    </svg>
</body>
</html>

开始裁剪:

clip-path: inset(100px 50px);

clip-path详解:CSS中 clip-path 的用法总结clip-path 基本介绍 clip-path 是一个CSS属性,剪切路径,允 - 掘金

解释:

clip-path: inset(100px, 50px) 

inser - 按矩形裁剪,宽100px,高50px

按圆形裁剪

clip-path: circle(50px at 100px 100px);

在裁剪圆形的基础上,加入过渡效果

.container{
            width: 400px;
            height: 300px;
            border: 1px solid red;
            background:url(./panda.jpg);
            background-size: cover;
            background-repeat: no-repeat;
            background-position: center center;
            padding:10px;
            /* clip-path: 按矩形裁剪(宽100px 高50px); */
            /* clip-path: inset(100px 50px); */
            /* clip-path: 按圆形裁剪(在水平100px垂直50px的地方裁剪半径50px的圆形); 
                跟border-radius的圆形区别:
                1.border-radius改变容器的大小形状,clip-path容器的占位没有改变,还是原来的形状
                2.clip-path因为不改变容器内的定位,所以有的时候做一些容器内的定位就很好做 */
            clip-path: circle(50px at 100px 100px);
            /* clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%, 10% 10%, 40px 10px); */
            /* clip-path: url(#clipPath); */
            /* background-size: cover; */
            transition:clip-path .4s;
        }
        .container:hover{
            clip-path: circle(80px at 100px 100px);
        }

鼠标放上去之前

鼠标放上去触发过渡效果

按多边形裁剪

clip-path: polygon(第一个重要的点(x,y), 第二个重要的点(x,y), ..., 第N个重要的点(x,y)) - 按多边形裁剪; 
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%, 10% 10%, 40px 10px);
     

按路径裁剪,可以借助矢量图形svg

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .container{
            width: 400px;
            height: 300px;
            border: 1px solid red;
            background:url(./panda.jpg);
            background-size: cover;
            background-repeat: no-repeat;
            background-position: center center;
            padding:10px;
            /* clip-path: 按矩形裁剪(宽100px 高50px); */
            /* clip-path: inset(100px 50px); */
            /* clip-path: 按圆形裁剪(在水平100px垂直50px的地方裁剪半径50px的圆形); 
                跟border-radius的圆形区别:
                1.border-radius改变容器的大小形状,clip-path容器的占位没有改变,还是原来的形状
                2.clip-path因为不改变容器内的定位,所以有的时候做一些容器内的定位就很好做 */
            /* clip-path: circle(50px at 100px 100px); */
            /* clip-path: polygon(第一个重要的点(x,y), 第二个重要的点(x,y), ..., 第N个重要的点(x,y)) - 按多边形裁剪; 
                clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%, 10% 10%, 40px 10px);
            */
            /* clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%, 10% 10%, 40px 10px); */
            clip-path: url(#clipPath);
            /* background-size: cover; */
            transition:clip-path .4s;
        }
        .container:hover{
            /* clip-path: circle(80px at 100px 100px); */
        }
    </style>
</head>
<body>
    <div class="container">
        你好,我是熊猫
    </div>
    <svg>
        <defs>
            <clipPath id="clipPath">
                <!-- r50为半径,cx,cy为圆心坐标的一个圆 -->
                <circle cx="60" cy="60" r="50" fill="#34538b" />
                <!-- <polygon stroke="#979797" points="0.4921875 81.2070313 92.640625 81.2070313 121.601562 0.21875 153.648437 81.2070313 247.390625 80.7734375 173.394531 140.496094 200.308594 227.09375 121.601562 172.71875 53.4960937 227.09375 80.859375 140.496094"></polygon> -->
            </clipPath>
        </defs>
    </svg>
</body>
</html>

使用矢量图形svg,实现之前的多边形裁剪

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .container{
            width: 400px;
            height: 300px;
            border: 1px solid red;
            background:url(./panda.jpg);
            background-size: cover;
            background-repeat: no-repeat;
            background-position: center center;
            padding:10px;
            /* clip-path: 按矩形裁剪(宽100px 高50px); */
            /* clip-path: inset(100px 50px); */
            /* clip-path: 按圆形裁剪(在水平100px垂直50px的地方裁剪半径50px的圆形); 
                跟border-radius的圆形区别:
                1.border-radius改变容器的大小形状,clip-path容器的占位没有改变,还是原来的形状
                2.clip-path因为不改变容器内的定位,所以有的时候做一些容器内的定位就很好做 */
            /* clip-path: circle(50px at 100px 100px); */
            /* clip-path: polygon(第一个重要的点(x,y), 第二个重要的点(x,y), ..., 第N个重要的点(x,y)) - 按多边形裁剪; 
                clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%, 10% 10%, 40px 10px);
            */
            /* clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%, 10% 10%, 40px 10px); */
            clip-path: url(#clipPath);
            /* background-size: cover; */
            transition:clip-path .4s;
        }
        .container:hover{
            /* clip-path: circle(80px at 100px 100px); */
        }
    </style>
</head>
<body>
    <div class="container">
        你好,我是熊猫
    </div>
    <svg>
        <defs>
            <clipPath id="clipPath">
                <!-- r50为半径,cx,cy为圆心坐标的一个圆 -->
                <!-- <circle cx="60" cy="60" r="50" fill="#34538b" /> -->
                <!-- 点坐标为points的多边形 /> -->
                <polygon stroke="#979797" points="0.4921875 81.2070313 92.640625 81.2070313 121.601562 0.21875 153.648437 81.2070313 247.390625 80.7734375 173.394531 140.496094 200.308594 227.09375 121.601562 172.71875 53.4960937 227.09375 80.859375 140.496094"></polygon>
            </clipPath>
        </defs>
    </svg>
</body>
</html>

注意:clip-path功能很强大,基本上什么形状都可以做出来,但是需要注意,有些时候浏览器的兼容性不是那么好。

六、3D-transform: 在3D空间中进行变换

translate: 位移

scale: 缩放

skew: 斜切

rotate: 旋转

课程示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .container{
            margin:50px;
            padding: 10px;
            border: 1px solid red;
            width: 200px;
            height: 200px;
            position: relative;
            /* perspective: 500px; */
            /* transform-style: preserve-3d; */
            /* transform: translateZ(-100px); */
            /* transition:transform .4s; */
        }
        .container{
            /* transform: translateZ(-100px) rotateX(90deg) rotateY(90deg); */
        }
        #cube{
            width:200px;
            height:200px;
        }
        #cube div{
            width: 200px;
            height:200px;
            position: absolute;
            line-height: 200px;
            font-size:50px;
            text-align: center;
        }
        #cube:hover{
            /* transform: translateZ(-100px) rotateX(270deg); */
            /* transform: translateZ(-100px) rotateX(90deg) rotateY(90deg); */
        }
        .front{
            /* transform: translateZ(100px); */
            /* transform: translateX(100px); */
            /* transform: translateX(100px) translateY(10px) rotate(25deg); */
            /* transform: rotate(25deg) translateX(100px) translateY(10px); */
            background:rgba(255,0,0,.3);
        }
        .back{
            /* transform: translateZ(-100px); */
            /* transform: translateZ(-100px) rotateY(180deg);
            background:rgba(0,255,0,.3); */
        }
        .left{
            /* transform: translateX(-100px) rotateY(-90deg);
            background:rgba(0,0,255,.3); */
        }
        .right{
            /* transform: translateX(100px) rotateY(90deg);
            background:rgba(255,255,0,.3); */
        }
        .top{
            /* transform: translateY(-100px) rotateX(-90deg);
            background:rgba(255,0,255,.3); */
        }
        .bottom{
                /* transform: translateY(100px) rotateX(90deg);
                background:rgba(0,255,255,.3); */
        }

        
    </style>
</head>
<body>
    <div class="container">
        <div id="cube">
            <div class="front">1</div>
            <!-- <div class="back">2</div>
            <div class="right">3</div>
            <div class="left">4</div>
            <div class="top">5</div>
            <div class="bottom">6</div> -->
        </div>
    </div>
</body>
</html>

进行2D变换:

transform: 设置对象转换

.front{
            /* transform: translateZ(100px); */
            /* 指定对象X轴(水平方向)的平移 */
            transform: translateX(100px);
            /* transform: translateX(100px) translateY(10px) rotate(25deg); */
            /* transform: rotate(25deg) translateX(100px) translateY(10px); */
            background:rgba(255,0,0,.3);
        }

往右100px,往下10px,旋转25度

.front{
            /* transform: translateZ(100px); */
            /*指定对象X轴(水平方向)的平移 */
            /* transform: translateX(100px); */
            /* transform: translateX(100px) translateY(10px) rotate(25deg); 
                translateX: 往右100px
                translateY: 往下10px
                rotate: 旋转25度
                最重要一点: 变换不可以改变这几个属性顺序,如果改变就会图案不一样!!!
            */
            transform: translateX(100px) translateY(10px) rotate(25deg);
            /* transform: rotate(25deg) translateX(100px) translateY(10px); */
            background:rgba(255,0,0,.3);
        }

我们改变下属性顺序看下,会是什么结果!

.front{
            /* transform: translateZ(100px); */
            /*指定对象X轴(水平方向)的平移 */
            /* transform: translateX(100px); */
            /* transform: translateX(100px) translateY(10px) rotate(25deg); 
                translateX: 往右100px
                translateY: 往下10px
                rotate: 旋转25度
                最重要一点: 变换不可以改变这几个属性顺序,如果改变就会图案不一样!!!
            */
            /* transform: translateX(100px) translateY(10px) rotate(25deg); */
            transform: rotate(25deg) translateX(100px) translateY(10px);
            background:rgba(255,0,0,.3);
        }

发现图案不一样了,所以变换,如果改变属性顺序,会造成图案不一样!!!

造成变换图案不一样的原因是,CSS是根据你的顺序逐个解析执行属性的,按照数学的矩阵运算最终计算图案的位置以及形状。

理解3D变换: x轴 - 水平,y轴 - 垂直, z轴 - 面向我们是正轴,屏幕往里是负轴。

front面是正面,理论上我们应该让它面向我们100px。

.front{
            transform: translateZ(100px);
            /*指定对象X轴(水平方向)的平移 */
            /* transform: translateX(100px); */
            /* transform: translateX(100px) translateY(10px) rotate(25deg); 
                translateX: 往右100px
                translateY: 往下10px
                rotate: 旋转25度
                最重要一点: 变换不可以改变这几个属性顺序,如果改变就会图案不一样!!!
            */
            /* transform: translateX(100px) translateY(10px) rotate(25deg); */
            /* transform: rotate(25deg) translateX(100px) translateY(10px); */
            background:rgba(255,0,0,.3);
        }

我们发现,设置了z轴为什么看起来好像没有变化呢?

实际上,因为电脑屏幕是平面的,所以z轴就涉及到视觉原理近大远小,当没有透视关系对比的时候,我们是看不出视觉差的,我们设置的是z轴+100px,所以从视觉原理来说,就是保持x轴、y轴形成的图案效果。

现在,我们设置perspective:透视属性、 transform-style:定义子元素所在空间维度

.container{
            margin:50px;
            padding: 10px;
            border: 1px solid red;
            width: 200px;
            height: 200px;
            position: relative;
            /* perspective: 透视属性,z轴透视的距离; */
            perspective: 500px;
            /* transform-style: preserve-3d; */
            /* transform: translateZ(-100px); */
            /* transition:transform .4s; */
        }
        .container{
            /* transform: translateZ(-100px) rotateX(90deg) rotateY(90deg); */
        }
        #cube{
            width:200px;
            height:200px;
            /* transform-style: 指定子元素透视的平面; 
                preserve-3d: 指定子元素定位在三维空间内 ;
                flat: 指定子元素位于此元素所在平面内
            */
            transform-style: preserve-3d;
        }

通过对比效果看,在还是原来宽高的情况下,为体现透视的近大远小视觉效果,正面图案变大了,视觉上感觉离得更近了。

perspective:设置透视属性        

transform-style:设置透视效果

修改translateZ,当我们将z轴设置为0px

translateZ:0px,相当于没有面向我们,也没有向屏幕里, 从视觉上看,还是原来图案大小。

继续修改,当我们将z轴设置为-100px

translateZ:-200px, 图案变小了,从视觉上看,向屏幕里凹进去了。

为了更明细一些,我们把背后的那个面(back)放出来,做对比:

现在,将其他面放开:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .container{
            margin:50px;
            padding: 10px;
            border: 1px solid red;
            width: 200px;
            height: 200px;
            position: relative;
            /* perspective: 透视属性,z轴透视的距离; */
            perspective: 500px;
            /* transform-style: preserve-3d; */
            /* transform: translateZ(-100px); */
            /* transition:transform .4s; */
        }
        .container{
            /* transform: translateZ(-100px) rotateX(90deg) rotateY(90deg); */
        }
        #cube{
            width:200px;
            height:200px;
            /* transform-style: 指定子元素透视的平面; 
                preserve-3d: 指定子元素定位在三维空间内 ;
                flat: 指定子元素位于此元素所在平面内
            */
            transform-style: preserve-3d;
        }
        #cube div{
            width: 200px;
            height:200px;
            position: absolute;
            line-height: 200px;
            font-size:50px;
            text-align: center;
        }
        #cube:hover{
            /* transform: translateZ(-100px) rotateX(270deg); */
            /* transform: translateZ(-100px) rotateX(90deg) rotateY(90deg); */
        }
        .front{
            transform: translateZ(100px);
            /*指定对象X轴(水平方向)的平移 */
            /* transform: translateX(100px); */
            /* transform: translateX(100px) translateY(10px) rotate(25deg); 
                translateX: 往右100px
                translateY: 往下10px
                rotate: 旋转25度
                最重要一点: 变换不可以改变这几个属性顺序,如果改变就会图案不一样!!!
            */
            /* transform: translateX(100px) translateY(10px) rotate(25deg); */
            /* transform: rotate(25deg) translateX(100px) translateY(10px); */
            background:rgba(255,0,0,.3);
        }
        .back{
            /* transform: translateZ(-100px); 
                z轴向屏幕里100px
            */
            /* transform: translateZ(-100px); */
            /* transform: translateZ(-100px) rotateY(180deg); 
                z轴向屏幕里100px, y轴旋转180度
            */
            transform: translateZ(-100px) rotateY(180deg);
            background:rgba(0,255,0,.3); 
        }
        .left{
            transform: translateX(-100px) rotateY(-90deg);
            background:rgba(0,0,255,.3);
        }
        .right{
            transform: translateX(100px) rotateY(90deg);
            background:rgba(255,255,0,.3);
        }
        .top{
            transform: translateY(-100px) rotateX(-90deg);
            background:rgba(255,0,255,.3);
        }
        .bottom{
                transform: translateY(100px) rotateX(90deg);
                background:rgba(0,255,255,.3);
        }

        
    </style>
</head>
<body>
    <div class="container">
        <div id="cube">
            <div class="front">1</div>
            <div class="back">2</div>
            <div class="right">3</div>
            <div class="left">4</div>
            <div class="top">5</div>
            <div class="bottom">6</div>
        </div>
    </div>
</body>
</html>

现在立方体的效果已经出来了,但是因为设置透视属性的原因,立方体的视觉效果,已经超出了最一开始设置的红框的容器大小,现在我们将立方体整体变小。

#cube{
            width:200px;
            height:200px;
            /* transform-style: 指定子元素透视的平面; 
                preserve-3d: 指定子元素定位在三维空间内 ;
                flat: 指定子元素位于此元素所在平面内
            */
            transform-style: preserve-3d;
            transform: translateZ(-100px);
        }

现在,立方体已经没有超出容器了。

加上动画过渡效果:

注意:

限制:3D变换性能并不是非常好,在低端机器上很容易出现卡顿。

七、面试题


原文地址:https://blog.csdn.net/zhenlong_qu/article/details/145165453

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!