习题解答
图 10-25 旋转、放大、倾斜、平移效果(左:初始;右:按下后)
这道题用 :active 伪类(鼠标按下不松开时触发)配合 transform 属性实现四种变形效果,再加上 transition 让变形过程平滑。
思路:四个方块分别绑定不同的 transform 函数——rotate()旋转、scale()放大、skew()倾斜、translate()平移。
完整代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>变形效果</title>
<style>
/* 公共样式:所有方块 */
.box {
display: inline-block;
width: 120px;
height: 120px;
background: #aaa;
margin: 40px 30px;
vertical-align: top;
line-height: 1.4;
padding: 6px;
color: #333;
font-size: 14px;
/* 过渡:让变形动画平滑 */
transition: transform 0.3s ease;
cursor: pointer;
}
/* 旋转:按下时顺时针旋转 45 度 */
.rotate:active { transform: rotate(45deg); }
/* 放大:按下时放大 1.4 倍 */
.scale:active { transform: scale(1.4); }
/* 倾斜:按下时沿 X 轴倾斜 20 度 */
.skew:active { transform: skewX(20deg); }
/* 平移:按下时向右下各平移 30px */
.translate:active { transform: translate(30px, 30px); }
</style>
</head>
<body>
<div class="box rotate">旋转</div>
<div class="box scale">放大</div>
<div class="box skew">倾斜</div>
<div class="box translate">平移</div>
</body>
</html>
📖 参见 10.1.2 transform 属性 / 10.2.1 过渡属性
图 10-26 180° 旋转(左:正常;右:悬停后翻转)
用 :hover 伪类触发 transform: rotate(180deg),同时设置 transition 让旋转过程有动画效果。图中展示的是一只兔子头像,悬停后上下翻转 180°。
完整代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>图片旋转</title>
<style>
body { display: flex; justify-content: center; align-items: center; min-height: 100vh; background: #fff; }
img {
width: 280px;
height: 280px;
border-radius: 50%; /* 圆形裁切 */
display: block;
/* 过渡:旋转用 0.8s,缓入缓出 */
transition: transform 0.8s ease-in-out;
cursor: pointer;
}
/* 鼠标悬停:旋转 180 度 */
img:hover {
transform: rotate(180deg);
}
</style>
</head>
<body>
<!-- 替换 src 为实际图片路径 -->
<img src="images/rabbit.png" alt="兔子头像">
</body>
</html>
📖 参见 10.1.2 transform 属性(rotate 函数)/ 10.2.1 过渡属性
图 10-27 360° 旋转
这题和上一题的区别:旋转角度是 360°(转一整圈回到原位),悬停时元素看起来"原地转一圈"。图中是一个带"旋转"文字的灰色方块。
关键点:transition 持续时间要足够长,旋转才看得清楚。
完整代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>css制作旋转图片</title>
<style>
body { display: flex; justify-content: center; padding: 60px; }
.outer {
width: 200px;
height: 200px;
background: #ddd;
padding: 20px;
}
.inner {
width: 160px;
height: 160px;
background: #888;
line-height: 160px;
text-align: center;
color: #fff;
font-size: 18px;
/* 过渡:1s 匀速旋转 */
transition: transform 1s linear;
cursor: pointer;
}
/* 悬停旋转一整圈(360 度) */
.inner:hover {
transform: rotate(360deg);
}
</style>
</head>
<body>
<div class="outer">
<div class="inner">旋转</div>
</div>
</body>
</html>
📖 参见 10.1.2 transform 属性(rotate 函数)/ 10.2.1 过渡属性
图 10-28 图片反转(左:背面;右:鼠标悬停后正面)
这是经典的"翻牌"效果,需要三个关键技术配合:
transform-style: preserve-3d —— 让子元素保持 3D 空间backface-visibility: hidden —— 背面不可见(翻过去就看不到了)rotateY(180deg) —— 初始让正面藏在背后,悬停时容器翻转完整代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>图片正反面旋转</title>
<style>
body { display: flex; justify-content: center; padding: 40px; }
/* 容器:定义透视和过渡 */
.card-container {
width: 260px;
height: 380px;
perspective: 800px; /* 透视距离,数值越小3D感越强 */
cursor: pointer;
}
/* 卡牌主体:3D 空间翻转 */
.card {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d; /* 子元素保持3D */
transition: transform 0.8s ease-in-out;
}
/* 悬停时翻转 */
.card-container:hover .card {
transform: rotateY(180deg);
}
/* 正面和背面共同样式 */
.front, .back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden; /* 背对屏幕时隐藏 */
border-radius: 8px;
overflow: hidden;
}
/* 背面:扑克牌花纹(初始可见) */
.back {
background: #1a1a2e;
border: 3px solid #ccc;
/* 用 CSS 模拟扑克背面图案 */
background-image: repeating-linear-gradient(
45deg,
#1a1a2e 0px,
#1a1a2e 8px,
#c0392b 8px,
#c0392b 10px
);
}
/* 正面:初始旋转 180deg(藏在背后) */
.front {
transform: rotateY(180deg);
background: #fff;
display: flex;
justify-content: center;
align-items: center;
font-size: 100px;
border: 3px solid #333;
}
/* 如果使用真实图片,取消注释并删除上面的模拟样式 */
/* .back img, .front img { width: 100%; height: 100%; object-fit: cover; } */
</style>
</head>
<body>
<div class="card-container">
<div class="card">
<!-- 背面:可替换为 img src="images/card_back.jpg" -->
<div class="back"></div>
<!-- 正面:黑桃 A -->
<div class="front">🂡</div>
</div>
</div>
</body>
</html>
📖 参见 10.1.4 transform-style 属性 / 10.1.6 backface-visibility 属性 / 10.2.1 过渡属性
图 10-29 平移动画(黑色方块从左向右移动)
这道题用 @keyframes + animation 实现自动循环的平移动画。从效果图可以看到:一个深色方块从屏幕左侧移动到右侧,然后循环。
注意和第1题的区别:那题是鼠标触发的 transition 过渡,这题是自动播放的 animation 动画。
完整代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>平移</title>
<style>
body { margin: 0; padding: 20px; }
.block {
width: 120px;
height: 120px;
background: #222; /* 深色方块 */
color: #fff;
line-height: 120px;
text-align: center;
font-size: 14px;
position: relative;
/* 绑定动画:名称 持续时间 速度曲线 循环次数 */
animation: moveRight 2s linear infinite alternate;
}
/* 定义平移关键帧:从左边 0 移动到右边 */
@keyframes moveRight {
from { left: 0px; }
to { left: calc(100vw - 160px); } /* 移动到靠近右侧 */
}
</style>
</head>
<body>
<div class="block">鼠标指向则平移</div>
</body>
</html>
📖 参见 10.3.1 动画属性(@keyframes / animation)
图 10-30 6张图片旋转(悬停后以中心点为原点向四周散开)
这道题和教材例10-7(扑克牌散开)很相似!6张图片叠放在同一位置,鼠标悬停时分别旋转到不同角度散开。
关键技术:transform-origin: top right(以右上角为旋转原点),配合 transition 实现平滑旋转展开效果。
完整代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>旋转练习</title>
<style>
body { background: #fff; }
/* 容器:相对定位,让图片叠放 */
#container {
width: 200px;
height: 150px;
margin: 180px auto;
position: relative;
}
img {
width: 160px;
height: 120px;
position: absolute;
border: 3px solid #fff;
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
/* 旋转原点:右上角(和教材示例一致) */
transform-origin: top right;
/* 过渡:旋转动画 0.6s */
transition: transform 0.6s ease-in-out;
object-fit: cover;
}
/* 悬停时 6 张图分别旋转到不同角度 */
#container:hover img:nth-of-type(1) { transform: rotate(-60deg); }
#container:hover img:nth-of-type(2) { transform: rotate(-120deg); }
#container:hover img:nth-of-type(3) { transform: rotate(-180deg); }
#container:hover img:nth-of-type(4) { transform: rotate(-240deg); }
#container:hover img:nth-of-type(5) { transform: rotate(-300deg); }
#container:hover img:nth-of-type(6) { transform: rotate(-360deg); }
</style>
</head>
<body>
<div id="container">
<!-- 替换为实际风景图片路径 -->
<img src="images/pic1.jpg" alt="">
<img src="images/pic2.jpg" alt="">
<img src="images/pic3.jpg" alt="">
<img src="images/pic4.jpg" alt="">
<img src="images/pic5.jpg" alt="">
<img src="images/pic6.jpg" alt="">
</div>
</body>
</html>
📖 参见 10.1.3 transform-origin 属性 / 10.2.1 过渡属性(例 10-7)
图 10-31 3D 旋转效果(图片排列成圆柱形旋转木马)
这是一个"旋转木马"(Carousel)效果。多张图片均匀分布在一个圆柱体的表面,用 @keyframes 让整个容器持续旋转。
核心思路:每张图片用 rotateY(n * 角度) translateZ(半径) 定位到圆柱面上,再让容器整体绕 Y 轴旋转。
完整代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>3D旋转</title>
<style>
body {
background: #111;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
overflow: hidden;
}
/* 透视包裹层 */
.scene {
perspective: 800px;
}
/* 旋转容器:preserve-3d 让子元素保持3D位置 */
.carousel {
width: 200px;
height: 150px;
position: relative;
transform-style: preserve-3d;
/* 无限旋转动画,8s一圈 */
animation: spin 8s linear infinite;
}
@keyframes spin {
from { transform: rotateY(0deg); }
to { transform: rotateY(360deg); }
}
/* 每张图片 */
.carousel img {
position: absolute;
width: 200px;
height: 150px;
border: 2px solid rgba(255,255,255,0.5);
object-fit: cover;
opacity: 0.85;
}
/* 8 张图均匀分布:每张间隔 360/8 = 45 度,translateZ 控制半径 */
.carousel img:nth-child(1) { transform: rotateY( 0deg) translateZ(300px); }
.carousel img:nth-child(2) { transform: rotateY( 45deg) translateZ(300px); }
.carousel img:nth-child(3) { transform: rotateY( 90deg) translateZ(300px); }
.carousel img:nth-child(4) { transform: rotateY(135deg) translateZ(300px); }
.carousel img:nth-child(5) { transform: rotateY(180deg) translateZ(300px); }
.carousel img:nth-child(6) { transform: rotateY(225deg) translateZ(300px); }
.carousel img:nth-child(7) { transform: rotateY(270deg) translateZ(300px); }
.carousel img:nth-child(8) { transform: rotateY(315deg) translateZ(300px); }
</style>
</head>
<body>
<div class="scene">
<div class="carousel">
<!-- 替换为实际风景图片 -->
<img src="images/s1.jpg" alt="">
<img src="images/s2.jpg" alt="">
<img src="images/s3.jpg" alt="">
<img src="images/s4.jpg" alt="">
<img src="images/s5.jpg" alt="">
<img src="images/s6.jpg" alt="">
<img src="images/s7.jpg" alt="">
<img src="images/s8.jpg" alt="">
</div>
</div>
</body>
</html>
📖 参见 10.1.2 transform 属性(3D变形函数)/ 10.1.4 transform-style / 10.1.5 perspective / 10.3.1 动画属性
图 10-32 3D 转换(父元素旋转,子元素保持3D空间)
这道题演示 transform-style: preserve-3d 的效果。从效果图可以看到:外框内有两个矩形(深色"HELLO"和浅色"YELLOW"),它们在3D空间中错落排列,呈现出立体感。
关键区别:
transform-style: flat(默认)—— 子元素压平在父元素平面上,看不到3D效果transform-style: preserve-3d —— 子元素保留各自的3D位置,能看到真实的空间关系完整代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>transform-style属性</title>
<style>
body { display: flex; justify-content: center; padding: 40px; }
/* 外框 */
.wrapper {
width: 300px;
height: 300px;
border: 1px solid #999;
position: relative;
/* 设置透视:让3D效果可见 */
perspective: 500px;
/* preserve-3d:子元素保留各自3D变换 */
transform-style: preserve-3d;
}
/* 子元素基础样式 */
.box {
position: absolute;
width: 140px;
height: 100px;
display: flex;
justify-content: center;
align-items: center;
font-size: 18px;
font-weight: bold;
}
/* 深色块:HELLO,沿X轴旋转,位于左上角 */
.hello {
background: #333;
color: #fff;
top: 40px;
left: 30px;
/* 沿X轴旋转 -20 度,产生3D透视感 */
transform: rotateX(-20deg) rotateY(15deg);
}
/* 浅色块:YELLOW,沿Y轴旋转,位于右下角,文字翻转 */
.yellow {
background: #e8e8e8;
color: #333;
top: 150px;
left: 100px;
/* 沿Y轴旋转 180 度,文字反显 */
transform: rotateY(180deg) rotateX(-20deg);
}
</style>
</head>
<body>
<div class="wrapper">
<div class="box hello">HELLO</div>
<div class="box yellow">YELLOW</div>
</div>
</body>
</html>
📖 参见 10.1.4 transform-style 属性 / 10.1.5 perspective 属性(例 10-8)