评判一个网页的美观程度,首要的当然是看它的 CSS 样式写的如何。
日本某宅写了一个非常厨二的页面——臆病な魔女,可以说是把 CSS 动画玩得非常 6 了,看得笔者顿时燃起了学好 CSS 的欲望。
如果想 CSS 玩的溜,除了熟悉基本的知识以外,掌握大量技巧也是必不可少的。
形状
扩张式矩形
目的:创建一个矩形,鼠标悬浮时扩张一定的大小
预览
<div class="expanding-box"></div>
body {
display: flex;
height: 100vh;
justify-content: center;
align-items: center;
}
.expanding-box {
position: relative;
width: 15em;
height: 10em;
&::after {
position: absolute;
content: "";
top: -1em;
right: -1em;
bottom: -3em;
left: -1em;
background: black;
--path: inset(2rem 0 2rem 2rem round 10px);
clip-path: var(--path);
transition: clip-path 0.3s;
}
&:hover::after {
--path: inset(0 round 10px);
}
}
首先利用伪元素::after
生成一个矩形
利用clip-path
的inset
来裁切矩形(顺序是上右下左圆角)
鼠标悬浮时去除裁切效果即可
字体排印
分割符
目的:实现分隔符效果
预览
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Archive</a></li>
<li><a href="#">About</a></li>
</ul>
ul {
display: flex;
font-weight: bold;
list-style-type: none;
li {
&:not(:last-child) {
margin-right: 5px;
&::after {
content: "|";
margin-left: 5px;
}
}
}
}
添加伪元素::after
,内容content: "|"
,设置间距
再用:not(:last-child)
去除伪元素的最后一个子元素即可
用户体验
提示用角标
目的:在按钮右上角创建一个提示用的角标
预览
<button class="badge" count="7">消息</button>
body {
display: flex;
justify-content: center;
}
button {
position: relative;
padding: 20px;
border-radius: 20px;
font-size: 24px;
}
.badge::before {
content: attr(count);
position: absolute;
right: 10px;
top: -8px;
background: tan;
padding: 0 8px;
border-radius: 12px;
transform: translate(50%, 0);
}
伪元素的content
可通过attr()
来获取标签的某一属性值
类似的提示框也可以配合过渡动画来实现:预览
伸缩式按钮
目的:实现伸缩式按钮(鼠标悬浮按钮则展开,移开按钮则收缩)
预览
<a href="#" class="sliding-button">
<span>下载</span>
<span>720p</span>
</a>
<a href="#" class="sliding-button">
<span>下载</span>
<span>1080p</span>
</a>
$tianyi-blue: #66ccff;
body {
display: flex;
height: 100vh;
align-items: center;
justify-content: center;
}
.sliding-button {
background: $tianyi-blue url(https://i.loli.net/2019/09/04/JULm1Agr5Gzy7iK.png)
no-repeat -30px center;
overflow: hidden;
transition: padding 0.2s ease, background-position 0.2s ease,
transform 0.5s ease;
border: 1px solid $tianyi-blue;
border-radius: 4px;
color: #fff;
text-decoration: none;
text-transform: uppercase;
padding: 6px 16px 6px 16px;
font-size: 18px;
font-weight: bold;
line-height: 27px;
&:nth-child(1) {
margin-right: 1em;
}
span:nth-child(1) {
position: absolute;
left: -80px;
}
&:hover {
padding-left: 69px;
background-position: 5px center;
transform: scale(1, 1);
span:nth-child(1) {
left: 30px;
}
}
}
给“下载”设置负的left
用于将其移除视界范围
鼠标悬浮时设置padding-left
使按钮给“下载”留出空间
left: 30px;
和transform: scale(1, 1);
把“下载”拉回按钮中(这个很 hack)
最后设定过渡动画即可看到流畅的过渡效果了
结构与布局
圣杯布局
目的:实现圣杯布局(左中右三列,左右两列定宽,中间列自适应宽度)
预览
<div class="g-container">
<div class="g-left">left</div>
<div class="g-middle">middle</div>
<div class="g-right">right</div>
</div>
.g-container {
display: flex;
height: 100vh;
min-width: 400px;
& > div {
text-align: center;
color: #fff;
line-height: 100vh;
font-size: 3vw;
}
.g-left {
order: 1;
flex: 200px 0 0;
background: cyan;
}
.g-middle {
order: 2;
flex: auto 1 0;
background: purple;
}
.g-right {
order: 3;
flex: 200px 0 0;
background: red;
}
}
左右列的flex-grow
设为200px
,表示它们各占200px
空间
中间列的flex-grow
设为auto
,flex-shrink
设为 1,表明是自适应宽度
过渡与动画
动态侧边栏
目的:创建一个导航用的侧边栏,里面包含一个列表,用户鼠标浮动到链接上时会显示过渡动画
预览
<body>
<nav>
<ul>
<li><a href="#">home</a></li>
<li><a href="#">resume</a></li>
<li><a href="#">tags</a></li>
<li><a href="#">categories</a></li>
<li><a href="#">archives</a></li>
<li><a href="#">search</a></li>
</ul>
</nav>
</body>
nav {
position: relative;
background: hsl(60, 100%, 65%);
width: 218px;
padding-top: 5px;
}
ul {
list-style: none;
width: 197px;
margin: 0 auto;
padding: 0;
vertical-align: baseline;
li {
margin: 2.5px 0;
a {
display: inline-block;
position: relative;
padding: 8px 0;
padding-left: 20px;
color: black;
font-weight: 800;
font-size: 22px;
letter-spacing: 0.075em;
text-decoration: none;
text-transform: uppercase;
&::before {
content: "";
position: absolute;
opacity: 0;
background: url("https://test.demo-1s.com/images/2019/06/24/d31DXx0KYav6cZkG.png")
left center no-repeat;
top: 0;
left: 2px;
width: 16px;
height: 100%;
transform: translateX(10px);
transition: 0.3s ease-out;
}
&:hover::before {
opacity: 1;
transform: translateX(0);
}
&::after {
content: "";
position: absolute;
height: 4px;
width: 0;
bottom: 2px;
left: -3px;
opacity: 0;
background: white;
border: 2px solid black;
transition: all 0.3s cubic-bezier(0.445, 0.05, 0.55, 0.95);
}
&:hover::after {
opacity: 1;
width: calc(100% + 6px);
}
}
}
}
body {
margin: 0;
padding: 0;
}
给 a 添加 2 个伪元素,并分别为其设置transition
以及hover
时的状态即可
图片幻灯片
目的:四幅图片(这里用颜色代替)按顺序依次向右滑动显示,最后被四道白色矩形依次遮住
预览
<body>
<main id="slider">
<div class="image"></div>
<div class="image"></div>
<div class="image"></div>
<div class="image"></div>
<div class="paint">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</main>
</body>
$imgs: blue, cyan, yellow, tan;
html,
body {
margin: 0;
padding: 0;
}
body {
display: flex;
min-height: 100vh;
}
#slider {
position: relative;
width: 500px;
height: 300px;
margin: auto;
}
.image {
position: absolute;
width: 0%;
height: 100%;
overflow: hidden;
&::after {
content: "";
display: block;
width: 500px;
height: 300px;
background-size: cover;
background-position: center;
}
@for $i from 1 through length($imgs) {
&:nth-child(#{$i})::after {
background-color: nth($imgs, $i);
}
}
}
.paint {
position: absolute;
width: 100%;
height: 100%;
div {
width: 100%;
height: 25%;
background-color: white;
transform: translateX(-100%);
}
}
// animation
@for $i from 1 to 5 {
.image:nth-child(#{$i}) {
animation: show-image 0.7s ease (0.5s + 0.2s * $i - 0.2s) forwards;
}
}
@for $i from 1 to 5 {
.paint div:nth-child(#{$i}) {
animation: slide-right 0.5s ease (1.6s + 0.1s * $i - 0.1s) forwards;
}
}
// keyframes
@keyframes show-image {
from {
width: 0%;
}
to {
width: 100%;
}
}
@keyframes slide-right {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0%);
}
}
添加一个 slider,用flex
使其垂直居中
在 slider 上添加 4 个 image,并使其大小和 slider 相同并重叠在一起,利用overflow:hidden
隐藏它们
为这些 image 设置::after
矩形伪元素,用作图片背景
创建show-image
关键帧:元素的宽度从 0%变为 100%
为 image 创建动画:把show-image
作为关键帧,每张图设置不同的延时delay
,fill-mode
设置forwards
表示动画完成时保持最后一个关键帧的属性值,这样就完成了 4 张图依次向右滑动的效果
添加一个 paint 以及 4 个子 div,表示 4 道白色矩形,默认的位置是向 x 轴左侧平移 1 个元素单位
创建slide-right
关键帧:向 x 轴左侧平移 1 个元素单位变为平移 0 个单位,也就是平移到原点
为 paint 的 4 个子 div 创建动画:把slide-right
作为关键帧,同样给每个矩形设置不同的延时delay
和forwards
的fill-mode
,就完成了四道白色矩形依次将图片遮住的效果