一些CSS使用的记录,详情参考 CSS 参考手册 | 菜鸟教程 (runoob.com)
ICSS案例参考学习 GitHub - chokcoco/iCSS: 不止于 CSS
动画库 CSS Animation Kit (angrytools.com)
anime.js • JavaScript animation engine (animejs.com)
图片动画库:
imagehover.css- 纯CSS3鼠标滑过图片效果动画库,44种鼠标滑过效果 ciar4n/imagehover.css: Pure CSS Image Hover Effect Library (github.com)
TiltEffect 是一款让图像跟随鼠标产生微妙立体倾斜效果的插件,使其有层次感和深度感。 codrops/ImageTiltEffect: A subtle tilt effect for images. The idea is to move and rotate semi-transparent copies with the same background image in order to create a subtle motion or depth effect. (github.com)
Magnifier 是一款实用纯js制作的图片放大镜插件。它有以下一些特定:mark-rolich/Magnifier.js: Javascript library enabling magnifying glass effect on an images (github.com)
css背景(background)
- background-color:red;//背景色
- background-size:80px 60px; 检索或设置对象的背景图像的尺寸大小
- background-image:url('bgdesert.jpg');//背景图片
- background-repeat:no-repeat // 设置或检索对象的背景图像如何铺排填充。必须先指定background-image属性
- background-position:center //设置或检索对象的背景图像位置。必须先指定background-image属性。
- background-image: linear-gradient(to right,#e66465, #9198e5); // 线性渐变 从左边开始的线性渐变。起点是红色,慢慢过渡到黄色
边框(border)和轮廓(outline)
/* 边框宽度 | 边框样式 | 边框颜色 */
border: medium solid green; //设置对象边框的特性。
outline:#00FF00 dotted thick; //设置或检索对象外的线条轮廓。
border-radius: 15px 50px 30px 5px; //圆角边框。(左上角,右上角,右下角,左下角)
box-shadow: 10px 10px 5px #888888; // 方框添加一个或多个阴影
媒体查询
媒体查询(Media Queries)使用媒体查询 - CSS:层叠样式表 | MDN
- 移动端优先开发
先写默认样式(移动端),再用min-width
适配大屏。 - 桌面端优先开发
先写桌面样式,再用max-width
适配小屏。
@media (max-width: 768px) { ... } /* 小屏幕 (手机) */
@media (min-width: 769px) and (max-width: 1024px) { ... } /* 平板 */
@media (min-width: 1025px) { ... } /* 桌面端 */
@media (orientation: portrait) { /* 竖屏 */
body { background: pink; }
}
@media (orientation: landscape) { /* 横屏 */
body { background: lightgreen; }
}
@media (min-resolution: 2dppx) {
img {
content: url('image@2x.png'); /* 在 Retina 屏使用高清图 */
}
}
/* 同时满足 */
@media (min-width: 600px) and (max-width: 1200px) {
p { font-size: 18px; }
}
/* 满足任意一个 */
@media (max-width: 500px), (orientation: landscape) {
body { color: red; }
}
body {
background-color:#fff;
}
// max-height,max-width,min-height,min-width
/* 屏幕宽度小于等于 600px 时生效 */
@media (max-width: 600px) {
body {
background-color: lightblue;
}
}
flex 盒子模型
.box{
display: flex;//容器都指定为Flex布局。
flex-direction: row | row-reverse | column | column-reverse;//flex-direction属性决定主轴的方向
- row(默认值):主轴为水平方向,起点在左端。
- row-reverse:主轴为水平方向,起点在右端。
- column:主轴为垂直方向,起点在上沿。
- column-reverse:主轴为垂直方向,起点在下沿。
flex-wrap: nowrap | wrap | wrap-reverse; //如果一条轴线排不下,如何换行
- nowrap(默认):不换行。
- wrap:换行,第一行在上方。
- wrap-reverse:换行,第一行在下方。
justify-content: flex-start | flex-end | center | space-between | space-around; //主轴上的对齐方式。
- flex-start(默认值):左对齐
- flex-end:右对齐
- center: 居中
- space-between:两端对齐,项目之间的间隔都相等。
- space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
align-items: flex-start | flex-end | center | baseline | stretch; //交叉轴上如何对齐
- flex-start:交叉轴的起点对齐。
- flex-end:交叉轴的终点对齐。
- center:交叉轴的中点对齐。
- baseline: 项目的第一行文字的基线对齐。
- stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
}
定位
h2 {
position:absolute;
left:100px;
top:150px;
}
sticky:粘性定位 粘性定位的元素是依赖于用户的滚动,在 **position:relative** 与 **position:fixed** 定位之间切换。
fixed :Fixed定位使元素的位置与文档流无关,因此不占据空间。Fixed定位的元素和其他元素重叠。
relative:相对定位元素的定位是相对其正常位置。
absolute:绝对定位的元素的位置相对于最近的已定位父元素,如果元素没有已定位的父元素,那么它的位置相对于<html>:
//子绝父相
<style>
.header {
position: relative;
height: 105px;
background-color: pink;
}
.logo {
position: absolute;
top: 25px;
left: 0;
height: 175px;
width: 56px;
}
</style>
<body>
<div class="header w">
<div class="logo"></div>
</div>
</body>
文本(text) 鼠标 (cursor)
h1 {
font-size: 12px; //字体大小
font-style:normal | italic | oblique; //字体样式
- normal 标准的字体样式
- italic 斜体的字体样式。
- oblique 倾斜的字体样式。
font-weight:normal | bold | 100-900; //字体粗细
color:#FF0000;//颜色
text-align:center; //文本对齐
- left:左对齐(默认值)
- center:居中对齐
- right:右对齐
text-decoration:none; //文本修饰
- none:默认值,无任何修饰(最常用)
- underline:下划线,例如链接a标签自带的下划线(常用)
- overline:上划线(几乎不用)
- line-through:删除线(不常用)
// text-overflow 文本溢出属性
text-overflow: ellipsis;
overflow: hidden;
text-indent:10px; // 文本缩进
letter-spacing: 3px; // 字母间距
word-spacing:3px; // 字间距
line-height:20px; // 行高
text-shadow: h-shadow v-shadow blur color; //文本阴影
- h-shadow:水平阴影的位置,正负值均可(必需)
- v-shadow:垂直阴影的位置,正负值均可(必需)
- blur:模糊的距离(可选)
- color:阴影的颜色(可选)
//鼠标样式
cursor: default;
- default:默认光标(通常是一个箭头)
- pointer:光标呈现为指示链接的指针(一只手)
- crosshair:光标呈现为十字线。
- move:此光标指示某对象可被移动。
- text:此光标指示文本。
- wait:此光标指示程序正忙(通常是一只表或沙漏)。
- help:此光标指示可用的帮助(通常是一个问号或一个气球)。
}
css 伪类
a:link {color:#FF0000;} /* 未访问的链接 */
a:visited {color:#00FF00;} /* 已访问的链接 */
a:hover {color:#FF00FF;} /* 鼠标划过链接 */
a:active {color:#0000FF;} /* 已选中的链接 */
**注意:** 在CSS定义中,a:hover 必须被置于 a:link 和 a:visited 之后,才是有效的。
**注意:** 在 CSS 定义中,a:active 必须被置于 a:hover 之后,才是有效的。
**注意:** 伪类的名称不区分大小写。
隔行换色
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
ul li:nth-child(odd) {
background-color: red;
}
ul li:nth-child(even) {
background-color: green;
}
</style>
</head>
<body>
<ul>
<li>未来可期1</li>
<li>未来可期2</li>
<li>未来可期3</li>
<li>未来可期4</li>
<li>未来可期5</li>
<li>未来可期6</li>
<li>未来可期7</li>
<li>未来可期8</li>
<li>未来可期9</li>
<li>未来可期10</li>
</ul>
</body>
</html>
响应式导航栏实例
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<ul class="topnav">
<li><a class="active" href="#home">主页</a></li>
<li><a href="#news">新闻</a></li>
<li><a href="#contact">联系</a></li>
<li class="right"><a href="#about">关于</a></li>
</ul>
<div style="padding:0 16px;">
<h2>响应式导航栏实例</h2>
<p>在屏幕宽度小于 600px 会重置导航栏。</p>
<h4>重置浏览器窗口大小,查看效果。</h4>
</div>
</body>
<style>
body {margin: 0;}
ul.topnav {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
ul.topnav li {float: left;}
ul.topnav li a {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
ul.topnav li a:hover:not(.active) {background-color: #111;}
ul.topnav li a.active {background-color: #4CAF50;}
ul.topnav li.right {float: right;}
@media screen and (max-width: 600px){
ul.topnav li.right,
ul.topnav li {float: none;}
}
</style>
</html>
三角型
<div class="arrow-box">
<div class="triangular"></div>
</div>
<style>
.arrow-box {
position: relative;
width: 300px;
height: 160px;
background: #f0f9ff;
border: 2px solid #1598d9;
border-radius: 6px;
line-height: 160px;
}
.arrow-box::after,
.arrow-box::before {
position: absolute;
// bottom: 100%; // 上箭头
// left: calc(45% + 14px);
left: 100%;
top: calc(45% + 14px);
border: solid transparent;
content: "";
height: 0;
width: 0;
pointer-events: none;
}
.arrow-box::after {
border-color: transparent;
border-width: 12px;
// border-bottom-color: #fff; //// 上箭头
// margin-left: -12px;
border-left-color: #fff;
margin-top: -12px;
}
.arrow-box::before {
border-color: transparent;
border-width: 15px;
// border-bottom-color: #1598d9; // 上箭头
// margin-left: -15px;
border-left-color: #1598d9;
margin-top: -15px;
}
.triangular {
// 三角形
width: 0;
height: 0;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-top: 20px solid lightblue; // 把其他的颜色变为transparent(透明色)可形成三角形
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-bottom: 20px solid transparent;
}
</style>
过度
<h1>过度</h1>
<style scoped>
h1 {
/* transition: all 2s; */
transition: width 2s, color 3s, background 4s;
color: red;
width: 100px;
background: #000;
}
h1:hover {
width: 300px;
color: blue;
background: red;
}
</style>
2d/3d旋转
<div class="dd">转换</div>
<style >
.dd {
width: 100px;
height: 100px;
background-color: #f00;
transition: all 1s ease-in-out;
}
.dd:hover {
/* 2d 移动(平移)translate()方法,根据左(X轴)和顶部(Y轴)位置给定的参数,从当前元素位置移动。 */
/* transform: translate(50px, 100px); */
/* 3d 移动(平移)translate()方法 x轴,y轴,z轴 */
/* transform: translate3d(50px,100px,0); */
/* 2d 旋转 rotate()方法,在一个给定度数顺时针旋转的元素。负值是允许的,这样是元素逆时针旋转。 */
/* transform: rotate(180deg); */
/* 3d转换 */
/* transform: rotate3d(1, 2, 3, 180deg); */
/* 缩放 scale()方法 ,该元素增加或减少的大小,取决于宽度(X轴)和高度(Y轴)的参数: */
/* transform: scale(2, 2); */
/* transform: scale3d(2, 2, 2); */
/* 换倾斜转 skew()方法,该元素对X轴和Y轴应用倾斜转换: */
/* transform: skew(30deg, 20deg); */
/* matrix()方法,有六个参数,包含旋转,缩放,移动(平移)和换倾斜转: */
/* transform: matrix(0.866, 0.5, -0.5, 0.866, 100, 10); */
}
</style>
animejs
npm install animejs --save
可参考示例 Documentation | anime.js (animejs.com)
多阶段的时间线动画
<template>
<div class="container">
<div class="box" ref="box"></div>
</div>
</template>
<script setup>
import { onMounted, ref } from 'vue';
import anime from 'animejs/lib/anime.es.js';
const box = ref(null);
onMounted(() => {
const timeline = anime.timeline({
easing: 'easeInOutExpo', // 动画缓动函数
duration: 1000, // 动画持续时间
loop: true // 循环播放动画
});
timeline
.add({
targets: box.value,
translateX: 250,
scale: 2,
backgroundColor: '#FF0000'
})
.add({
targets: box.value,
rotate: '1turn',
borderRadius: '50%',
duration: 2000
})
.add({
targets: box.value,
translateY: 100,
scale: 1,
backgroundColor: '#0000FF',
offset: '-=1500' // 在前一个动画未完成前开始此动画
})
.add({
targets: box.value,
translateX: 0,
rotate: '0turn',
backgroundColor: '#00FF00',
borderRadius: '0%',
duration: 1500
});
});
</script>
<style scoped>
.container {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.box {
width: 100px;
height: 100px;
background-color: #FF00FF;
position: relative;
}
</style>
路径动画和关键帧结合
<template>
<div class="container">
<svg viewBox="0 0 500 500">
<path id="motionPath" fill="none" stroke="lightgrey" stroke-width="2"
d="M10 80 Q 95 10 180 80 T 330 80 Q 415 150 500 80" />
<circle ref="circle" r="10" fill="red"></circle>
</svg>
</div>
</template>
<script setup>
import { onMounted, ref } from 'vue';
import anime from 'animejs/lib/anime.es.js';
const circle = ref(null);
onMounted(() => {
anime({
targets: circle.value,
translateX: anime.path('#motionPath').x,
translateY: anime.path('#motionPath').y,
easing: 'easeInOutQuad',
duration: 5000,
loop: true,
keyframes: [
{ r: 5, fill: '#FF0000' }, // 缩小并变红
{ r: 10, fill: '#00FF00' }, // 变大并变绿
{ r: 15, fill: '#0000FF' } // 变得更大并变蓝
]
});
});
</script>
<style scoped>
.container {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
svg {
width: 100%;
height: auto;
}
</style>
混合3D变换和CSS属性动画
<template>
<div class="container">
<div class="box" ref="box"></div>
</div>
</template>
<script setup>
import { onMounted, ref } from 'vue';
import anime from 'animejs/lib/anime.es.js';
const box = ref(null);
onMounted(() => {
anime({
targets: box.value,
translateZ: 100,
rotateX: '1turn',
rotateY: '1turn',
backgroundColor: [
{ value: '#FF0000', duration: 1000 },
{ value: '#00FF00', duration: 1000 },
{ value: '#0000FF', duration: 1000 }
],
opacity: [
{ value: 0.5, duration: 1000 },
{ value: 1, duration: 1000 }
],
duration: 3000,
easing: 'easeInOutExpo',
loop: true,
direction: 'alternate'
});
});
</script>
<style scoped>
.container {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
perspective: 1000px;
/* 必须为3D变换提供透视效果 */
}
.box {
width: 100px;
height: 100px;
background-color: #3498db;
opacity: 1;
}
</style>
图片动画效果
<div class="wrapper">
<div class="scenes" tabindex="0">
<div class="scene-1">
<h2 class="scene-title">Qui-Gon Jinn and Obi-Wan Kenobi</h2>
</div>
<div class="scene-2">
<h2 class="scene-title">Darth Maul</h2>
</div>
</div>
</div>
//css
@keyframes scene-transition {
25% {
filter: brightness(100%);
}
100% {
filter: brightness(100%);
-webkit-mask-size: 1800%;
}
}
.scenes {
position: relative;
width: 500px;
height: 500px;
outline: 2px solid #ccc;
cursor: pointer
}
.scene-1,
.scene-2 {
position: absolute;
inset: 0;
background-size: cover;
background-repeat: repeat;
background-position: center;
}
.scene-1 {
background-image:
radial-gradient(circle, #fff3 10%, transparent 20%),
url(https://img-s-msn-com.akamaized.net/tenant/amp/entityid/AA1oEjiP.img?w=768&h=480&m=6&x=394&y=103&s=381&d=381);
}
.scene-2 {
background-image: url(https://img-s-msn-com.akamaized.net/tenant/amp/entityid/AA1oGYlS.img?w=768&h=783&m=6);
filter: brightness(0%);
-webkit-mask-image: url(https://assets.codepen.io/77020/sw-jedi-crest.svg);
-webkit-mask-size: 10%;
-webkit-mask-position: center;
-webkit-mask-repeat: no-repeat;
}
.scenes:is(:hover, :focus) .scene-2 {
animation: scene-transition 4s cubic-bezier(1, 0, 1, 1) forwards;
}
<div class="scenes" tabindex="0">
<div class="scene-1">
<h2 class="scene-title">Kylo Ren</h2>
</div>
<div class="scene-2">
<h2 class="scene-title">C-3PO and Captain Gandalf</h2>
</div>
</div>
// css
@property --angle {
syntax: '<angle>';
inherits: true;
initial-value: -10deg;
}
@keyframes scene-transition {
to {
--angle: 370deg;
}
}
.scenes {
position: relative;
width: 500px;
height: 300px;
outline: 2px solid #ccc;
}
.scene-1,
.scene-2 {
position: absolute;
inset: 0;
background-size: cover;
}
.scene-1 {
background-image: url(https://img-s-msn-com.akamaized.net/tenant/amp/entityid/AA1oGYlS.img?w=768&h=783&m=6);
}
.scene-2 {
background-image: url(https://img-s-msn-com.akamaized.net/tenant/amp/entityid/AA1oEjiP.img?w=768&h=480&m=6&x=394&y=103&s=381&d=381);
z-index: -1;
-webkit-mask-image:
conic-gradient(#fff 0deg,
#fff calc(var(--angle) - 10deg),
transparent calc(var(--angle) + 10deg),
transparent 360deg),
conic-gradient(transparent 340deg,
#fff 360deg);
}
.scenes:is(:hover, :focus) .scene-2 {
z-index: 1;
animation: scene-transition 2s linear forwards;
}
<div class="scenes" tabindex="0">
<div class="scene-1">
<h2 class="scene-title">Kylo Ren</h2>
</div>
<div class="scene-2">
<h2 class="scene-title">C-3PO and Captain Gandalf</h2>
</div>
</div>
// css
@property --radius {
syntax: '<percentage>';
inherits: true;
initial-value: -5%;
}
@keyframes scene-transition {
to {
--radius: 105%;
}
}
.scenes {
position: relative;
width: 500px;
height: 300px;
}
.scene-1,
.scene-2 {
position: absolute;
inset: 0;
background-size: cover;
}
.scene-1 {
background-image: url(https://img-s-msn-com.akamaized.net/tenant/amp/entityid/AA1oGYlS.img?w=768&h=783&m=6);
}
.scene-2 {
background-image: url(https://img-s-msn-com.akamaized.net/tenant/amp/entityid/AA1oEjiP.img?w=768&h=480&m=6&x=394&y=103&s=381&d=381);
-webkit-mask-image: radial-gradient(circle,
#fff calc(var(--radius) - 5%),
transparent calc(var(--radius) + 5%));
}
.scenes:is(:hover, :focus) .scene-2 {
z-index: 1;
animation: scene-transition 2s linear forwards;
}
<div class="scenes" tabindex="0">
<div class="scene-1">
<h2 class="scene-title">Kylo Ren</h2>
</div>
<div class="scene-2">
<h2 class="scene-title">C-3PO and Captain Gandalf</h2>
</div>
</div>
//css
.scenes {
position: relative;
width: 500px;
height: 300px;
}
.scene-1,
.scene-2 {
position: absolute;
inset: 0;
background-size: cover;
}
.scene-1 {
background-image: url(https://img-s-msn-com.akamaized.net/tenant/amp/entityid/AA1oGYlS.img?w=768&h=783&m=6);
}
.scene-2 {
background-image: url(https://img-s-msn-com.akamaized.net/tenant/amp/entityid/AA1oEjiP.img?w=768&h=480&m=6&x=394&y=103&s=381&d=381);
-webkit-mask-image: linear-gradient(to right,
transparent 47.5%,
#fff 52.5%);
-webkit-mask-size: 210%;
-webkit-mask-position: left;
}
.scenes:is(:hover, :focus) .scene-2 {
-webkit-mask-position: right;
transition: -webkit-mask-position 2s linear;
}
打字机效果
<h1 style="text-shadow: 5px 5px 5px #000;">欢迎光临呐,各位访客们。</h1>
<style>
h1 {
/* 本例12个文字(加标点符号);有多少个文字,width就是多少个em */
width: 12em;
/* 加上两个动画,一个是打字动画,使用steps让字一个一个的出现,
注意step和字数保持一致,光标动画也是同理,*/
animation: typingWords 5s steps(12) infinite, cursor 0.5s steps(1) infinite;
/* 要设置不允许换行,且溢出隐藏 */
white-space: nowrap;
overflow: hidden;
/* 使用右边框作为打印的指针光标 */
border-right: 1px solid #000;
}
@keyframes typingWords {
0% {
width: 0;
}
}
@keyframes cursor {
50% {
border-color: transparent;
}
}
</style>
扩展卡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Expanding Cards</title>
</head>
<body>
<div class="container">
<div class="panel active"
style="background-image: url('https://images.unsplash.com/photo-1558979158-65a1eaa08691?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80')">
<h3>Explore The World</h3>
</div>
<div class="panel"
style="background-image: url('https://images.unsplash.com/photo-1572276596237-5db2c3e16c5d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80')">
<h3>Wild Forest</h3>
</div>
<div class="panel"
style="background-image: url('https://images.unsplash.com/photo-1507525428034-b723cf961d3e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1353&q=80')">
<h3>Sunny Beach</h3>
</div>
<div class="panel"
style="background-image: url('https://images.unsplash.com/photo-1551009175-8a68da93d5f9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1351&q=80')">
<h3>City on Winter</h3>
</div>
<div class="panel"
style="background-image: url('https://images.unsplash.com/photo-1549880338-65ddcdfd017b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80')">
<h3>Mountains - Clouds</h3>
</div>
</div>
</body>
<style>
@import url('https://fonts.googleapis.com/css?family=Muli&display=swap');
* {
box-sizing: border-box;
}
body {
font-family: 'Muli', sans-serif;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
margin: 0;
}
.container {
display: flex;
width: 90vw;
}
.panel {
flex: 0.5;
height: 80vh;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
border-radius: 50px;
color: #fff;
cursor: pointer;
margin: 10px;
position: relative;
-webkit-transition: all 700ms ease-in;
}
.panel h3 {
font-size: 24px;
position: absolute;
bottom: 20px;
left: 20px;
margin: 0;
opacity: 0;
}
.panel.active {
flex: 5;
}
.panel.active h3 {
opacity: 1;
transition: opacity 0.3s ease-in 0.4s;
}
@media (max-width: 480px) {
.container {
width: 100vw;
}
.panel:nth-of-type(4),
.panel:nth-of-type(5) {
display: none;
}
}
</style>
<script>
const panels = document.querySelectorAll('.panel')
panels.forEach((panel) => {
panel.addEventListener('click', () => {
removeActiveClasses()
panel.classList.add('active')
})
})
function removeActiveClasses() {
panels.forEach((panel) => {
panel.classList.remove('active')
})
}
</script>
</html>
隐藏的搜索小部件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PTKnXrLnZ9+fkDaog==" crossorigin="anonymous" />
<title>Hidden Search</title>
</head>
<body>
<div class="search">
<input type="text" class="input" placeholder="Search...">
<button class="btn">
<i class="fas fa-search"></i>
</button>
</div>
</body>
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');
* {
box-sizing: border-box;
}
body {
background-image: linear-gradient(90deg, #7d5fff, #7158e2);
font-family: 'Roboto', sans-serif;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
margin: 0;
}
.search {
position: relative;
height: 50px;
}
.search .input {
background-color: #fff;
border: 0;
font-size: 18px;
padding: 15px;
height: 50px;
width: 50px;
transition: width 0.3s ease;
}
.btn {
background-color: #fff;
border: 0;
cursor: pointer;
font-size: 24px;
position: absolute;
top: 0;
left: 0;
height: 50px;
width: 50px;
transition: transform 0.3s ease;
}
.btn:focus,
.input:focus {
outline: none;
}
.search.active .input {
width: 200px;
}
.search.active .btn {
transform: translateX(198px);
}
</style>
<script>
const search = document.querySelector('.search')
const btn = document.querySelector('.btn')
const input = document.querySelector('.input')
btn.addEventListener('click', () => {
search.classList.toggle('active')
input.focus()
})
</script>
</html>
滚动动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Scroll Animation</title>
</head>
<body>
<h1>Scroll to see the animation</h1>
<div class="box">
<h2>Content</h2>
</div>
<div class="box">
<h2>Content</h2>
</div>
<div class="box">
<h2>Content</h2>
</div>
<div class="box">
<h2>Content</h2>
</div>
<div class="box">
<h2>Content</h2>
</div>
<div class="box">
<h2>Content</h2>
</div>
<div class="box">
<h2>Content</h2>
</div>
<div class="box">
<h2>Content</h2>
</div>
<div class="box">
<h2>Content</h2>
</div>
<div class="box">
<h2>Content</h2>
</div>
<div class="box">
<h2>Content</h2>
</div>
<div class="box">
<h2>Content</h2>
</div>
<div class="box">
<h2>Content</h2>
</div>
</body>
<script>
const boxes = document.querySelectorAll('.box')
window.addEventListener('scroll', checkBoxes)
checkBoxes()
function checkBoxes() {
const triggerBottom = (window.innerHeight / 5) * 4
boxes.forEach((box) => {
const boxTop = box.getBoundingClientRect().top
if (boxTop < triggerBottom) {
box.classList.add('show')
} else {
box.classList.remove('show')
}
})
}
</script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');
* {
box-sizing: border-box;
}
body {
background-color: #efedd6;
font-family: 'Roboto', sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 0;
overflow-x: hidden;
}
h1 {
margin: 10px;
}
.box {
background-color: steelblue;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
width: 400px;
height: 200px;
margin: 10px;
border-radius: 10px;
box-shadow: 2px 4px 5px rgba(0, 0, 0, 0.3);
transform: translateX(400%);
transition: transform 0.4s ease;
}
.box:nth-of-type(even) {
transform: translateX(-400%);
}
.box.show {
transform: translateX(0);
}
.box h2 {
font-size: 45px;
}
</style>
</html>
以上是参考 GitHub - bradtraversy/50projects50days: 50+ mini web projects using HTML, CSS & JS