css3实现按钮hover效果

5,758 阅读3分钟

前言

看了标题你 可能 以为是我要分析一波css底层是怎么实现hover事件的,不是的!我只是看到一篇文章盘点那些出色的CSS图像悬停效果 觉得嗯不错我要学一下。

正文

【第一个】

先看一下第一个的最终实现效果吧!

下面直接上代码吧!

<!DOCTYPE html>
<html>
<head>
<style>
.data-container {
	background: #ffebee;
	height: 100px;
	display: flex;
	justify-content: center;
	align-items: center;
}
.btn {
	cursor: pointer;
	position: relative;
	padding: 10px 20px;
	background: white;
	font-size: 28px;
	border-top-right-radius: 10px;
	border-bottom-left-radius: 10px;
	transition: all 1s;
}
.btn:after, .btn:before {
	content: " ";
	width: 20px;
	height: 10px;
	position: absolute;
	border: 0px solid #fff;
	transition: all 1s;
}
.btn:after {
	top: -2px;
	left: -2px;
	border-top: 5px solid black;
	border-left: 5px solid black;
}
.btn:before {
	bottom: -2px;
	right: -2px;
	border-bottom: 5px solid black;
	border-right: 5px solid black;
}
.btn:hover {
	border-top-right-radius: 0px;
	border-bottom-left-radius: 0px;
}
.btn:hover:before, .btn:hover:after {
	width: 100%;
	height: 100%;
}
</style>
</head>
<body>
<div class="data-container">
	<span class="btn">Hover Style </span>
</div>
</body>
</html>

分析:

  1. 利用伪元素生成边框,精简html结构
  2. 利用css3 transition样式实现动画效果
  3. 实现的核心是:
  • 一般状态下 边框元素(这里是:before/:after伪元素)的宽高是 width: 20px; height:10px;
  • hover状态下边框元素的宽高是 width: 100%; height:100%;
  • 中间的过渡动画用css3 transition实现
附备注
  1. 生成的gif图用的工具是 ScreenToGif 软件
  2. 文章里的样式使用sass写的,我在网上找把sass转为css的工具一时没有找到,最后在文章提供的codepen.io路径里发现,codepen支持这两者转换。如图


【第二个】

看一下第二个的最终效果吧!

下面看一下代码吧!

 <!DOCTYPE html>
 <html>
 <head>
 <style>
 body {
	background: #E1332D;
	font-family: 'Roboto', sans-serif;
	font-weight: 400;
 }
 
 .buttons {
	display: -webkit-box;
	display: flex;
	-webkit-box-orient: vertical;
	-webkit-box-direction: normal;
	flex-direction: column;
	height: 100%;
	-webkit-box-pack: center;
	justify-content: center;
	text-align: center;
	width: 100%;
 }
 
 .container {
	-webkit-box-align: center;
	align-items: center;
	display: -webkit-box;
	display: flex;
	-webkit-box-orient: vertical;
	-webkit-box-direction: normal;
	flex-direction: column;
	-webkit-box-pack: center;
	justify-content: center;
	padding: 1em;
	text-align: center;
 }
 
 .btn {
	color: #fff;
	cursor: pointer;
	font-size: 16px;
	font-weight: 400;
	line-height: 45px;
	margin: 0 0 2em;
	max-width: 160px;
	position: relative;
	text-decoration: none;
	text-transform: uppercase;
	width: 100%;
 }
 .btn:hover {
	text-decoration: none;
 }
 
 .btn-5 {
	border: 0px solid;
	box-shadow: inset 0 0 20px rgba(255, 255, 255, 0);
	outline: 1px solid;
	outline-color: rgba(255, 255, 255, 0.5);
	outline-offset: 0px;
	text-shadow: none;
	-webkit-transition: all 1250ms cubic-bezier(0.19, 1, 0.22, 1);
	transition: all 1250ms cubic-bezier(0.19, 1, 0.22, 1);
 }
 
 .btn-5:hover {
	border: 1px solid;
	box-shadow: inset 0 0 20px rgba(255, 255, 255, 0.5), 0 0 20px rgba(255, 255, 255, 0.2);
	outline-color: rgba(255, 255, 255, 0);
	outline-offset: 15px;
	text-shadow: 1px 1px 2px #427388;
 }
 </style>
 </head>
 <body>
  <section class="buttons">
    <div class="container">
    <a href="#" class="btn btn-5">Hover</a>
    </div>
  </section>
</body>
</html>

分析:

实现的核心:一般状态 下没什么,hover状态时,飞出去的的白色边框是 outline 实现的。 outline-color: rgba(255, 255, 255, 0);outline-offset: 15px;最终的outline边框是没有颜色,偏离15px。

内阴影是 box-shadow: inset 0 0 20px rgba(255, 255, 255, 0.5), 0 0 20px rgba(255, 255, 255, 0.2);

transition实现动画效果


【第三个】

看一下第三个的效果:

代码如下:

<!DOCTYPE html>
<html>
<head>
<style>
body {
	background: #E1332D;
	font-family: 'Roboto', sans-serif;
	font-weight: 400;
}
.buttons {
	display: -webkit-box;
	display: flex;
	-webkit-box-orient: vertical;
	-webkit-box-direction: normal;
	flex-direction: column;
	height: 100%;
	-webkit-box-pack: center;
	justify-content: center;
	text-align: center;
	width: 100%;
}
.container {
	-webkit-box-align: center;
	align-items: center;
	display: -webkit-box;
	display: flex;
	-webkit-box-orient: vertical;
	-webkit-box-direction: normal;
	flex-direction: column;
	-webkit-box-pack: center;
	justify-content: center;
	padding: 1em;
	text-align: center;
}
.btn {
	color: #fff;
	cursor: pointer;
	font-size: 16px;
	font-weight: 400;
	line-height: 45px;
	margin: 0 0 2em;
	max-width: 160px;
	position: relative;
	text-decoration: none;
	text-transform: uppercase;
	width: 100%;
}
.btn:hover {
	text-decoration: none;
}
.btn-4 {
	border: 1px solid;
	overflow: hidden;
	position: relative;
}
.btn-4 span {
	z-index: 20;
}
.btn-4:after {
	background: #fff;
	content: "";
	width: 50px;
	height: 155px;
	opacity: .2;
	position: absolute;
	top: -50px;
	left: -75px;
	-webkit-transform: rotate(35deg);
	transform: rotate(35deg);
	-webkit-transition: all 550ms cubic-bezier(0.19, 1, 0.22, 1);
	transition: all 550ms cubic-bezier(0.19, 1, 0.22, 1);
	z-index: -10;
}
.btn-4:hover:after {
	left: 120%;
	-webkit-transition: all 550ms cubic-bezier(0.19, 1, 0.22, 1);
	transition: all 550ms cubic-bezier(0.19, 1, 0.22, 1);
}
</style>
</head>
<body>
<section class="buttons">
<div class="container">
	<a href="#" class="btn btn-4"><span>Hover</span></a>
</div>
</section>
</body>
</html>

分析:

  1. 常规状态下,用元素的:after伪元素生成一个背景是白色,宽50px,高155px的矩形。
  2. transform变形rotate旋转35deg
  3. 用定位把白色矩形移出视线外,hover状态时通过css过渡transition 改变定位的left值,实现最终效果 整个过程的图是如下:


【第四个】

看一下第四个的效果:

代码如下:

<!DOCTYPE html>
<html>
<head>
<style>
body {
	background: #E1332D;
	font-family: 'Roboto', sans-serif;
	font-weight: 400;
}
.buttons {
	display: -webkit-box;
	display: flex;
	-webkit-box-orient: vertical;
	-webkit-box-direction: normal;
	flex-direction: column;
	height: 100%;
	-webkit-box-pack: center;
	justify-content: center;
	text-align: center;
	width: 100%;
}
.container {
	-webkit-box-align: center;
	align-items: center;
	display: -webkit-box;
	display: flex;
	-webkit-box-orient: vertical;
	-webkit-box-direction: normal;
	flex-direction: column;
	-webkit-box-pack: center;
	justify-content: center;
	padding: 1em;
	text-align: center;
}
.btn {
	color: #fff;
	cursor: pointer;
	font-size: 16px;
	font-weight: 400;
	line-height: 45px;
	margin: 0 0 2em;
	max-width: 160px;
	position: relative;
	text-decoration: none;
	text-transform: uppercase;
	width: 100%;
}
.btn:hover {
	text-decoration: none;
}
.btn-3 {
  background: #e3403a;
  border: 1px solid #da251f;
  box-shadow: 0px 2px 0 #d6251f, 2px 4px 6px #e02a24;
  font-weight: 900;
  letter-spacing: 1px;
  -webkit-transition: all 150ms linear;
  transition: all 150ms linear;
}

.btn-3:hover {
  background: #e02c26;
  border: 1px solid rgba(0, 0, 0, 0.05);
  box-shadow: 1px 1px 2px rgba(255, 255, 255, 0.2);
  color: #ec817d;
  text-decoration: none;
  text-shadow: -1px -1px 0 #c2211c;
  -webkit-transition: all 250ms linear;
  transition: all 250ms linear;
}
</style>
</head>
<body>
<section class="buttons">
	<div class="container">
	<a href="#" class="btn btn-3"><span>Hover</span></a>
</div>
</section>
</body>
</html>

分析:

  1. 常规状态下,通过边框,背景颜色比周围颜色亮,下边框黑色阴影,形成外凸的视觉效果
  2. hover时,边框和边框阴影变的更暗,背景颜色也变的比周五颜色暗,形成内陷的视觉效果
  3. 通过给两种状态使用transition,使得两种状态之间互相变换时有渐变动画效果

【第五个】

效果如下:

代码如下:

<!DOCTYPE html>
<html>
<head>
<style>
body {
	background: #E1332D;
	font-family: 'Roboto', sans-serif;
	font-weight: 400;
}
.buttons {
	display: -webkit-box;
	display: flex;
	-webkit-box-orient: vertical;
	-webkit-box-direction: normal;
	flex-direction: column;
	height: 100%;
	-webkit-box-pack: center;
	justify-content: center;
	text-align: center;
	width: 100%;
}
.container {
	-webkit-box-align: center;
	align-items: center;
	display: -webkit-box;
	display: flex;
	-webkit-box-orient: vertical;
	-webkit-box-direction: normal;
	flex-direction: column;
	-webkit-box-pack: center;
	justify-content: center;
	padding: 1em;
	text-align: center;
}
.btn {
	color: #fff;
	cursor: pointer;
	font-size: 16px;
	font-weight: 400;
	line-height: 45px;
	margin: 0 0 2em;
	max-width: 160px;
	position: relative;
	text-decoration: none;
	text-transform: uppercase;
	width: 100%;
}
.btn:hover {
	text-decoration: none;
}
.btn-2 {
  letter-spacing: 0;
}
.btn-2:hover {
  letter-spacing: 5px;
}
.btn-2:after,
.btn-2:before {
  border: 1px solid rgba(255, 255, 255, 0);
  bottom: 0px;
  content: " ";
  display: block;
  margin: 0 auto;
  position: relative;
  -webkit-transition: all 280ms ease-in-out;
  transition: all 280ms ease-in-out;
  width: 0;
}
.btn-2:hover:after,
.btn-2:hover:before {
  border-color: #fff;
  -webkit-transition: width 350ms ease-in-out;
  transition: width 350ms ease-in-out;
  width: 70%;
}
</style>
</head>
<body>
<section class="buttons">
	<div class="container">
	<a href="#" class="btn btn-2"><span>Hover</span></a>
    </div>
</section>
</body>
</html>

分析:

  1. 常规状态下文字间的距离为0hover状态下时是5px(letter-spacing:5px)
  2. 用伪元素:after,:before生成两条线。常规状态下宽度是0hover状态下宽度是70%
  3. 常规状态和hover状态使用transition实现渐变动效

【第六个】

实现的效果如下:

代码如下:

<!DOCTYPE html>
<html>
<head>
<style>
body {
	background: #E1332D;
	font-family: 'Roboto', sans-serif;
	font-weight: 400;
}
.buttons {
	display: -webkit-box;
	display: flex;
	-webkit-box-orient: vertical;
	-webkit-box-direction: normal;
	flex-direction: column;
	height: 100%;
	-webkit-box-pack: center;
	justify-content: center;
	text-align: center;
	width: 100%;
}
.container {
	-webkit-box-align: center;
	align-items: center;
	display: -webkit-box;
	display: flex;
	-webkit-box-orient: vertical;
	-webkit-box-direction: normal;
	flex-direction: column;
	-webkit-box-pack: center;
	justify-content: center;
	padding: 1em;
	text-align: center;
}
.btn {
	color: #fff;
	cursor: pointer;
	font-size: 16px;
	font-weight: 400;
	line-height: 45px;
	margin: 0 0 2em;
	max-width: 160px;
	position: relative;
	text-decoration: none;
	text-transform: uppercase;
	width: 100%;
}
.btn:hover {
	text-decoration: none;
}
.btn-1 {
  background: #e02c26;
  font-weight: 100;
}
.btn-1 svg {
  height: 45px;
  left: 0;
  position: absolute;
  top: 0;
  width: 100%;
}
.btn-1 rect {
  fill: none;
  stroke: #fff;
  stroke-width: 2;
  stroke-dasharray: 422, 0;
  -webkit-transition: all 0.35s linear;
  transition: all 0.35s linear;
}
.btn-1:hover {
  background: rgba(225, 51, 45, 0);
  font-weight: 900;
  letter-spacing: 1px;
}
.btn-1:hover rect {
  stroke-width: 5;
  stroke-dasharray: 15, 310;
  stroke-dashoffset: 48;
  -webkit-transition: all 1.35s cubic-bezier(0.19, 1, 0.22, 1);
  transition: all 1.35s cubic-bezier(0.19, 1, 0.22, 1);
}
</style>
</head>
<body>
<section class="buttons">
<div class="container">
	<a href="#" class="btn btn-1">
	<svg>
	    <rect x="0" y="0" fill="none" width="100%" height="100%"/>
	</svg>
	Hover
	</a>
</div>
</section>
</body>
</html>

分析:

  1. 常规状态下,用svg rect实现一个边框 stroke-width: 2; stroke-dasharray: 422, 0;
  2. hover 状态时,svg rect 的样式为 stroke-width: 5; stroke-dasharray: 15, 310; stroke-dashoffset: 48;
  3. 两种状态过渡通过 transition实现
  4. stroke-dassarray可以实现很多看起来很难实现的效果

总结

  1. 通过不同方式实现两种不同状态下(常规状态下,hover状态下)不同的样式
  2. 通过css3的transition: all ... 等实现动画渐变效果