效果演示
实现了一个翻转卡片的效果,包括卡片正面和背面的样式,以及卡片内部表单的样式。卡片可以通过切换按钮 .toggle 的选中状态来进行翻转。卡片的样式包括背景颜色、边框、阴影、圆角等。表单元素的样式包括输入框、按钮等。
Code
<div class="wrapper">
<div class="card-switch">
<label class="switch">
<input type="checkbox" class="toggle">
<span class="slider"></span>
<span class="card-side"></span>
<div class="flip-card__inner">
<div class="flip-card__front">
<div class="title">Log in</div>
<form class="flip-card__form" action="">
<input class="flip-card__input" name="email" placeholder="Email" type="email">
<input class="flip-card__input" name="password" placeholder="Password" type="password">
<button class="flip-card__btn">Let`s go!</button>
</form>
</div>
<div class="flip-card__back">
<div class="title">Sign up</div>
<form class="flip-card__form" action="">
<input class="flip-card__input" placeholder="Name" type="name">
<input class="flip-card__input" name="email" placeholder="Email" type="email">
<input class="flip-card__input" name="password" placeholder="Password" type="password">
<button class="flip-card__btn">Confirm!</button>
</form>
</div>
</div>
</label>
</div>
</div>
body {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: #e8e8e8;
}
.wrapper {
--input-focus: #2d8cf0;
--font-color: #323232;
--font-color-sub: #666;
--bg-color: #fff;
--bg-color-alt: #666;
--main-color: #323232;
}
/* switch card */
.switch {
transform: translateY(-200px);
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 30px;
width: 50px;
height: 20px;
}
.card-side::before {
position: absolute;
content: 'Log in';
left: -70px;
top: 0;
width: 100px;
text-decoration: underline;
color: var(--font-color);
font-weight: 600;
}
.card-side::after {
position: absolute;
content: 'Sign up';
left: 70px;
top: 0;
width: 100px;
text-decoration: none;
color: var(--font-color);
font-weight: 600;
}
.toggle {
opacity: 0;
width: 0;
height: 0;
}
.slider {
box-sizing: border-box;
border-radius: 5px;
border: 2px solid var(--main-color);
box-shadow: 4px 4px var(--main-color);
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--bg-colorcolor);
transition: 0.3s;
}
.slider:before {
box-sizing: border-box;
position: absolute;
content: "";
height: 20px;
width: 20px;
border: 2px solid var(--main-color);
border-radius: 5px;
left: -2px;
bottom: 2px;
background-color: var(--bg-color);
box-shadow: 0 3px 0 var(--main-color);
transition: 0.3s;
}
.toggle:checked + .slider {
background-color: var(--input-focus);
}
.toggle:checked + .slider:before {
transform: translateX(30px);
}
.toggle:checked ~ .card-side:before {
text-decoration: none;
}
.toggle:checked ~ .card-side:after {
text-decoration: underline;
}
/* card */
.flip-card__inner {
width: 300px;
height: 350px;
position: relative;
background-color: transparent;
perspective: 1000px;
text-align: center;
transition: transform 0.8s;
transform-style: preserve-3d;
}
.toggle:checked ~ .flip-card__inner {
transform: rotateY(180deg);
}
.toggle:checked ~ .flip-card__front {
box-shadow: none;
}
.flip-card__front, .flip-card__back {
padding: 20px;
position: absolute;
display: flex;
flex-direction: column;
justify-content: center;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
background: lightgrey;
gap: 20px;
border-radius: 5px;
border: 2px solid var(--main-color);
box-shadow: 4px 4px var(--main-color);
}
.flip-card__back {
width: 100%;
transform: rotateY(180deg);
}
---
.flip-card__form {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
.title {
margin: 20px 0 20px 0;
font-size: 25px;
font-weight: 900;
text-align: center;
color: var(--main-color);
}
.flip-card__input {
width: 250px;
height: 40px;
border-radius: 5px;
border: 2px solid var(--main-color);
background-color: var(--bg-color);
box-shadow: 4px 4px var(--main-color);
font-size: 15px;
font-weight: 600;
color: var(--font-color);
padding: 5px 10px;
outline: none;
}
.flip-card__input::placeholder {
color: var(--font-color-sub);
opacity: 0.8;
}
.flip-card__input:focus {
border: 2px solid var(--input-focus);
}
.flip-card__btn:active, .button-confirm:active {
box-shadow: 0px 0px var(--main-color);
transform: translate(3px, 3px);
}
.flip-card__btn {
margin: 20px 0 20px 0;
width: 120px;
height: 40px;
border-radius: 5px;
border: 2px solid var(--main-color);
background-color: var(--bg-color);
box-shadow: 4px 4px var(--main-color);
font-size: 17px;
font-weight: 600;
color: var(--font-color);
cursor: pointer;
}
实现思路拆分
body {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: #e8e8e8;
}
- 设置 body 元素的高度为视口高度的 100%
- 使用 flexbox 将 body 元素的内容水平和垂直居中
- 设置 body 的背景颜色为 #e8e8e8
.wrapper {
--input-focus: #2d8cf0;
--font-color: #323232;
--font-color-sub: #666;
--bg-color: #fff;
--bg-color-alt: #666;
--main-color: #323232;
}
- 定义一个名为 .wrapper 的样式块,用于设置一些自定义变量
- 设置变量 --input-focus 为 #2d8cf0
- 设置变量 --font-color 为 #323232
- 设置变量 --font-color-sub 为 #666
- 设置变量 --bg-color 为 #fff
- 设置变量 --bg-color-alt 为 #666
- 设置变量 --main-color 为 #323232
.switch {
transform: translateY(-200px);
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 30px;
width: 50px;
height: 20px;
}
- 设置类名为 .switch 的元素的样式
- 将元素在垂直方向上向上平移 200px
- 设置元素的定位为相对定位
- 使用 flexbox 将元素的内容垂直排列
- 将元素的子元素在纵轴上居中对齐
- 设置元素之间的间距为 30px
- 设置元素的宽度为 50px
- 设置元素的高度为 20px
.card-side::before {
position: absolute;
content: 'Log in';
left: -70px;
top: 0;
width: 100px;
text-decoration: underline;
color: var(--font-color);
font-weight: 600;
}
- 设置类名为 .card-side 的元素的伪元素 ::before 的样式
- 设置伪元素的定位为绝对定位
- 设置伪元素的内容为 ‘Log in’
- 将伪元素的左侧位置向左平移 70px
- 将伪元素的顶部位置设置为 0
- 设置伪元素的宽度为 100px
- 设置伪元素的文本装饰为下划线
- 设置伪元素的颜色为 --font-color 变量的值
- 设置伪元素的字体粗细为 600
.card-side::after {
position: absolute;
content: 'Sign up';
left: 70px;
top: 0;
width: 100px;
text-decoration: none;
color: var(--font-color);
font-weight: 600;
}
- 设置类名为 .card-side 的元素的伪元素 ::after 的样式
- 设置伪元素的定位为绝对定位
- 设置伪元素的内容为 ‘Sign up’
- 将伪元素的左侧位置向右平移 70px
- 将伪元素的顶部位置设置为 0
- 设置伪元素的宽度为 100px
- 取消伪元素的文本装饰
- 设置伪元素的颜色为 --font-color 变量的值
- 设置伪元素的字体粗细为 600
.toggle {
opacity: 0;
width: 0;
height: 0;
}
- 设置类名为 .toggle 的元素的样式
- 设置元素的不透明度为 0
- 设置元素的宽度为 0
- 设置元素的高度为 0
.slider {
box-sizing: border-box;
border-radius: 5px;
border: 2px solid var(--main-color);
box-shadow: 4px 4px var(--main-color);
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--bg-colorcolor);
transition: 0.3s;
}
- 设置类名为 .slider 的元素的样式
- 设置元素的盒模型为边框盒模型
- 设置元素的圆角为 5px
- 设置元素的边框为 2px 实线边框,颜色为 --main-color 变量的值
- 设置元素的阴影效果
- 设置元素的定位为绝对定位
- 设置元素的鼠标指针样式为指针
- 将元素的上、左、右、下边距都设置为 0
- 设置元素的背景颜色为 --bg-colorcolor 变量的值
- 添加元素所有属性的过渡效果,过渡时间为 0.3s
.slider:before {
box-sizing: border-box;
position: absolute;
content: "";
height: 20px;
width: 20px;
border: 2px solid var(--main-color);
border-radius: 5px;
left: -2px;
bottom: 2px;
background-color: var(--bg-color);
box-shadow: 0 3px 0 var(--main-color);
transition: 0.3s;
}
- 创建一个伪元素 ::before ,用于表示滑块的样式
- 设置 box-sizing 属性为 border-box ,以便将边框和内边距包含在元素的总宽度和总高度内
- 设置伪元素的定位为绝对定位
- 设置伪元素的内容为空
- 设置伪元素的高度为 20px
- 设置伪元素的宽度为 20px
- 设置伪元素的边框为 2px 宽的实线边框,颜色为 --main-color 变量
- 设置伪元素的边框半径为 5px,使其呈现圆角效果
- 将伪元素的左边距设置为 -2px,使其与滑块的边缘对齐
- 将伪元素的底边距设置为 2px,使其与滑块的底部对齐
- 设置伪元素的背景颜色为 --bg-color 变量
- 添加一个向上的盒子阴影效果,颜色为 --main-color 变量
- 设置伪元素的过渡效果为 0.3s,使其在状态改变时产生平滑的过渡效果
.toggle:checked + .slider {
background-color: var(--input-focus);
}
- 当切换按钮( .toggle )被选中时,将相邻的滑块( .slider )的背景颜色设置为 --input-focus 变量
.toggle:checked + .slider:before {
transform: translateX(30px);
}
- 当切换按钮( .toggle )被选中时,将相邻的滑块( .slider )的伪元素( ::before )向右平移 30px
.toggle:checked ~ .card-side:before {
text-decoration: none;
}
- 当切换按钮( .toggle )被选中时,将相邻的卡片侧边( .card-side )的伪元素( ::before )的文本装饰样式设置为无
.toggle:checked ~ .card-side:after {
text-decoration: underline;
}
- 当切换按钮( .toggle )被选中时,将相邻的卡片侧边( .card-side )的伪元素( ::after )的文本装饰样式设置为下划线
.flip-card__inner {
width: 300px;
height: 350px;
position: relative;
background-color: transparent;
perspective: 1000px;
text-align: center;
transition: transform 0.8s;
transform-style: preserve-3d;
}
- 设置卡片内部容器( .flip-card__inner )的样式
- 设置容器的宽度为 300px
- 设置容器的高度为 350px
- 设置容器的定位为相对定位
- 设置容器的背景颜色为透明
- 设置容器的透视属性为 1000px,用于创建 3D 效果
- 设置容器内部文本居中对齐
- 添加容器的过渡效果,当容器的 transform 属性发生变化时,过渡时间为 0.8s
- 设置容器的 transform-style 属性为 preserve-3d ,使其保留 3D 效果
.toggle:checked ~ .flip-card__inner {
transform: rotateY(180deg);
}
.toggle:checked ~ .flip-card__front {
box-shadow: none;
}
- 当切换按钮( .toggle )被选中时,将相邻的卡片内部容器( .flip-card__inner )绕 Y 轴旋转 180 度
- 当切换按钮( .toggle )被选中时,将相邻的卡片正面( .flip-card__front )的盒子阴影样式设置为无
.flip-card__front, .flip-card__back {
padding: 20px;
position: absolute;
display: flex;
flex-direction: column;
justify-content: center;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
background: lightgrey;
gap: 20px;
border-radius: 5px;
border: 2px solid var(--main-color);
box-shadow: 4px 4px var(--main-color);
}
- 设置 .flip-cardfront 和 .flip-cardback 的样式:
- 设置内边距为 20px
- 设置定位为绝对定位
- 使用 flexbox 创建垂直方向的列布局
- 设置内容在垂直方向上居中对齐
- 设置 -webkit-backface-visibility 和 backface-visibility 为 hidden ,用于解决翻转时的闪烁问题
- 设置背景颜色为浅灰色
- 设置元素之间的间隔为 20px
- 设置边框半径为 5px,呈现圆角效果
- 设置边框为 2px 宽的实线边框,颜色为 --main-color 变量
- 添加盒子阴影效果,阴影偏移量为 (4px, 4px),颜色为 --main-color 变量
.flip-card__back {
width: 100%;
transform: rotateY(180deg);
}
- 设置 .flip-card__back 的样式:
- 设置宽度为 100%
- 使用 transform 属性将元素绕 Y 轴旋转 180 度,实现翻转效果
.flip-card__form {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
- 设置 .flip-card__form 的样式:
- 使用 flexbox 创建垂直方向的列布局
- 设置内容在垂直方向上居中对齐
- 设置元素之间的间隔为 20px
.title {
margin: 20px 0 20px 0;
font-size: 25px;
font-weight: 900;
text-align: center;
color: var(--main-color);
}
- 设置 .title 的样式:
- 设置上下边距为 20px,左右边距为 0
- 设置字体大小为 25px
- 设置字体粗细为 900
- 设置文本居中对齐
- 设置颜色为 --main-color 变量
.flip-card__input {
width: 250px;
height: 40px;
border-radius: 5px;
border: 2px solid var(--main-color);
background-color: var(--bg-color);
box-shadow: 4px 4px var(--main-color);
font-size: 15px;
font-weight: 600;
color: var(--font-color);
padding: 5px 10px;
outline: none;
}
- 设置 .flip-card__input 的样式:
- 设置宽度为 250px
- 设置高度为 40px
- 设置边框半径为 5px,呈现圆角效果
- 设置边框为 2px 宽的实线边框,颜色为 --main-color 变量
- 设置背景颜色为 --bg-color 变量
- 添加盒子阴影效果,阴影偏移量为 (4px, 4px),颜色为 --main-color 变量
- 设置字体大小为 15px
- 设置字体粗细为 600
- 设置文字颜色为 --font-color 变量
- 设置内边距为 5px 10px
- 移除输入框的外边框样式
.flip-card__input::placeholder {
color: var(--font-color-sub);
opacity: 0.8;
}
- 设置 .flip-card__input 的 placeholder 样式:
- 设置占位符文本颜色为 --font-color-sub 变量
- 设置占位符文本透明度为 0.8
.flip-card__input:focus {
border: 2px solid var(--input-focus);
}
- 设置 .flip-card__input 获得焦点时的样式:
- 设置边框为 2px 宽的实线边框,颜色为 --input-focus 变量
.flip-card__btn:active, .button-confirm:active {
box-shadow: 0px 0px var(--main-color);
transform: translate(3px, 3px);
}
- 设置 .flip-card__btn 和 .button-confirm 在按下时的样式:
- 添加盒子阴影效果,阴影偏移量为 (0px, 0px),颜色为 --main-color 变量
- 使用 transform 属性将元素向右下方移动 3px
.flip-card__btn {
margin: 20px 0 20px 0;
width: 120px;
height: 40px;
border-radius: 5px;
border: 2px solid var(--main-color);
background-color: var(--bg-color);
box-shadow: 4px 4px var(--main-color);
font-size: 17px;
font-weight: 600;
color: var(--font-color);
cursor: pointer;
}
- 设置 .flip-card__btn 的样式:
- 设置上下边距为 20px,左右边距为 0
- 设置宽度为 120px
- 设置高度为 40px
- 设置边框半径为 5px,呈现圆角效果
- 设置边框为 2px 宽的实线边框,颜色为 --main-color 变量
- 设置背景颜色为 --bg-color 变量
- 添加盒子阴影效果,阴影偏移量为 (4px, 4px),颜色为 --main-color 变量
- 设置字体大小为 17px
- 设置字体粗细为 600
- 设置文字颜色为 --font-color 变量
- 设置鼠标光标为指针形状