定位实战应用
一、绝对定位实现垂直水平居中
方法1: margin 负值法
<style>
* {
margin: 0;
padding: 0;
}
.parent {
width: 300px;
height: 300px;
border: 1px solid #000;
margin: 50px auto;
position: relative; /* 相对定位 */
}
.child {
width: 100px;
height: 100px;
background-color: skyblue;
position: absolute; /* 绝对定位 */
top: 50%;
left: 50%;
/* 垂直居中: margin-top: -自己高度的一半 */
margin-top: -50px;
/* 水平居中: margin-left: -自己宽度的一半 */
margin-left: -50px;
}
</style>
<body>
<div class="parent">
<div class="child"></div>
</div>
</body>原理:
top: 50%; left: 50%;让子元素左上角位于父元素中心margin-top: -50px; margin-left: -50px;向上向左移动自身的一半,实现居中
方法2: 四方向 + margin: auto
<style>
.parent {
width: 200px;
height: 100px;
background-color: skyblue;
position: relative; /* 相对定位 */
}
.child {
width: 50px;
height: 50px;
background-color: tomato;
position: absolute; /* 绝对定位 */
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto; /* 外边距自动 */
}
</style>
<body>
<div class="parent">
<div class="child"></div>
</div>
</body>原理:
- 设置
top: 0; bottom: 0; left: 0; right: 0;使子元素填充整个父元素 margin: auto;自动计算边距,实现居中
方法3: transform (推荐)
<style>
.parent {
width: 200px;
height: 200px;
border: 1px solid #000;
position: relative;
}
.child {
width: 100px;
height: 100px;
background-color: skyblue;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* 向左和向上移动自身一半 */
}
</style>优点: 不需要知道子元素的具体宽高
二、黑色半透明遮罩层
<style>
.box {
width: 300px;
height: 300px;
position: relative;
}
.box::before {
display: none;
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.box .icon-play {
display: block;
width: 80px;
height: 80px;
background: url(./images/play.png) no-repeat center;
background-size: cover;
position: absolute;
left: 110px;
top: 110px;
display: none;
}
.box:hover::before {
display: block;
}
.box:hover .icon-play {
display: block;
}
</style>
<body>
<div class="box">
<img src="./images/tx.png" alt="" />
<span class="icon-play"></span>
</div>
</body>效果: 鼠标移入时显示黑色半透明遮罩层和播放图标
三、带三角形的会话框
<style>
.head {
width: 124px;
margin: 150px auto;
position: relative;
}
/* 头像样式 */
.head img {
width: 100px;
height: 100px;
border-radius: 50%;
border: 2px solid skyblue;
}
.head-txt {
width: 200px;
height: 140px;
background-color: rgb(213, 241, 252);
/* 绝对定位 */
position: absolute;
left: 124px;
top: -20px;
border-radius: 20px;
line-height: 100px;
text-align: center;
display: none;
}
/* 三角形 */
.head-txt::after {
display: block;
content: "";
width: 0;
border: 20px solid transparent;
border-right-color: rgb(213, 241, 252);
position: absolute;
top: 50px;
left: -40px;
}
.head:hover .head-txt {
display: block;
}
</style>
<body>
<div class="head">
<img src="images/tx.png" alt="" />
<div class="head-txt">大家好,我是小美</div>
</div>
</body>四、鼠标移入展开下划线动画
<style>
a {
text-decoration: none;
color: #000;
display: block;
height: 30px;
width: 130px;
text-align: center;
line-height: 30px;
position: relative;
}
/* 绘制下划线,一开始宽为0 */
a::after {
content: "";
height: 2px;
background-color: rgb(31, 185, 246);
position: absolute;
left: 50%;
right: 50%;
bottom: 0;
transition: left .5s, right .5s;
}
a:hover::after {
left: 0;
right: 0;
}
</style>
<body>
<a href="">点击进入主页</a>
</body>五、固定定位实现返回顶部
<style>
html {
scroll-behavior: smooth; /* 平滑滚动 */
}
body {
height: 2000px;
}
.top {
display: block;
width: 60px;
height: 50px;
background-color: rgb(151, 148, 148);
color: #fff;
font-size: 12px;
text-align: center;
line-height: 50px;
text-decoration: none;
position: fixed; /* 固定定位 */
bottom: 100px;
right: 20px;
}
.top:hover {
background-color: gold;
}
</style>
<body id="top">
<a href="#top" class="top">返回顶部</a>
</body>六、登录弹窗效果
<style>
body {
height: 3000px;
}
/* 黑色半透明遮罩层 */
.mask {
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
position: fixed;
top: 0;
left: 0;
z-index: 100;
}
/* 登录框 */
.login {
box-sizing: border-box;
width: 300px;
background-color: #fff;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 40px;
z-index: 101;
}
.login input {
box-sizing: border-box;
width: 100%;
height: 40px;
outline: none;
margin-bottom: 20px;
border: 1px solid #ddd;
}
.login input:focus {
border: 1px solid tomato;
border-radius: 2px;
}
.login .login-button input {
background-color: tomato;
border: none;
border-radius: 5px;
color: #fff;
margin: 0;
cursor: pointer;
}
/* 关闭按钮 */
.login .close-button {
position: absolute;
right: 2px;
top: 2px;
width: 20px;
height: 20px;
background-color: #ddd;
background-image: url(./images/close.png);
background-size: 15px;
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
}
</style>
<body>
<a href="">登录</a>
<a href="">注册</a>
<!-- 黑色半透明遮罩层 -->
<div class="mask"></div>
<!-- 登录 -->
<div class="login">
<span class="close-button"></span>
<div class="user-name">
<input type="text" placeholder="用户名" />
</div>
<div class="user-pwd">
<input type="password" placeholder="密码" />
</div>
<div class="login-button">
<input type="submit" value="登录" />
</div>
</div>
</body>七、左右固定,中间自适应布局
<style>
body {
margin: 0;
}
.left {
width: 200px;
position: fixed; /* 固定定位 */
top: 0;
bottom: 0;
left: 0;
background-color: skyblue;
}
.right {
width: 150px;
position: fixed;
right: 0;
top: 0;
bottom: 0;
background-color: khaki;
}
.main {
margin: 0 160px 0px 210px;
background-color: tomato;
min-height: 700px;
}
</style>
<body>
<div class="left">左侧固定</div>
<div class="main">中间自适应</div>
<div class="right">右侧固定</div>
</body>八、粘性定位实现导航吸顶
<style>
body {
margin: 0;
}
.top {
height: 200px;
background-color: skyblue;
}
.head {
height: 100px;
background-color: palevioletred;
position: sticky; /* 粘性定位 */
top: 0;
}
.main {
width: 600px;
margin: 20px auto;
height: 2000px;
background-image: linear-gradient(to bottom, pink, yellow);
}
</style>
<body>
<div class="top">顶部区域</div>
<div class="head">吸顶导航</div>
<div class="main">内容区域</div>
</body>九、字母排序显示效果
<style>
.box {
width: 500px;
height: 300px;
overflow-y: scroll;
}
dl dt {
font-size: 20px;
height: 30px;
background-color: rgb(255, 192, 203);
position: sticky; /* 粘性定位 */
top: 0;
}
dl dd {
line-height: 30px;
font-size: 20px;
}
</style>
<body>
<div class="box">
<dl>
<dt>A</dt>
<dd>Andrew W.K.</dd>
<dd>Apparat</dd>
<dd>Arcade Fire</dd>
</dl>
<dl>
<dt>C</dt>
<dd>Chromeo</dd>
<dd>Common</dd>
<dd>Converge</dd>
</dl>
<dl>
<dt>E</dt>
<dd>Explosions In The Sky</dd>
</dl>
</div>
</body>十、表格首行冻结
方法1: 粘性定位
<style>
.box {
width: 500px;
height: 200px;
overflow-y: scroll; /* y轴方向溢出显示滚动条 */
}
table {
width: 100%;
border-collapse: collapse; /* 合并单元格边框线 */
}
table tr td,
table tr th {
border: 1px solid #333;
}
table tr th {
background-color: skyblue;
height: 50px;
position: sticky; /* 表格首行冻结 */
top: 0;
border-top: none;
}
table tr td {
font-size: 16px;
text-align: center;
height: 40px;
}
</style>
<body>
<div class="box">
<table>
<tr>
<th>姓名</th>
<th>学号</th>
<th>成绩</th>
<th>排名</th>
</tr>
<tr>
<td>张三</td>
<td>0001</td>
<td>90</td>
<td>1</td>
</tr>
<!-- 更多行... -->
</table>
</div>
</body>方法2: 绝对定位
<style>
.container {
position: relative;
width: 800px;
}
.scroll {
overflow-y: scroll;
height: 200px;
}
.container table {
border-collapse: collapse;
}
.container table tr td,
table tr th {
border: 1px solid #333;
text-align: center;
font-weight: 400;
height: 50px;
width: 25%;
}
/* 冻结行 */
.row {
position: absolute;
left: 0px;
right: 17px;
top: 0px;
}
.row table tr th {
background-color: #ddd;
font-weight: bold;
width: 25%;
}
</style>
<body>
<div class="container">
<div class="scroll">
<table class="music">
<tr>
<th>分类</th>
<th>排行</th>
<th>歌曲</th>
<th>歌手</th>
</tr>
<tr>
<td>古典</td>
<td>1</td>
<td>爱情是从</td>
<td>未知</td>
</tr>
<!-- 更多行... -->
</table>
<!-- 冻结行 -->
<div class="row">
<table>
<tr>
<th>分类</th>
<th>排行</th>
<th>歌曲</th>
<th>歌手</th>
</tr>
</table>
</div>
</div>
</div>
</body>十一、综合实战:流光按钮
<style>
body {
background-color: #000;
}
a.button {
display: block;
width: 160px;
height: 50px;
background-color: #333;
text-align: center;
line-height: 50px;
text-decoration: none;
color: #666;
font-weight: bold;
border-radius: 5px;
overflow: hidden;
position: relative;
}
a.button:hover {
color: yellow;
}
/* 彩色毛毛球 */
a.button::before {
content: "";
display: block;
width: 300px;
height: 300px;
background-image: radial-gradient(yellow, transparent 40%);
position: absolute;
left: var(--left);
top: var(--top);
margin-left: -150px;
margin-top: -150px;
display: none;
}
a.button:hover::before {
display: block;
}
/* 遮罩层 */
a.button::after {
content: "";
display: block;
position: absolute;
left: 2px;
right: 2px;
top: 2px;
bottom: 2px;
background-color: #333;
border-radius: 5px;
}
.m-center {
margin: 50px auto;
}
/* 文字 */
a.button span {
position: relative;
z-index: 1; /* 提高层级,确保文字在最上层 */
}
</style>
<body>
<a href="#" class="button m-center">
<span>加入购物车</span>
</a>
<script>
const button = document.querySelector("a.button");
button.onmousemove = function (e) {
const pageX = e.pageX;
const pageY = e.pageY;
const left = this.offsetLeft;
const top = this.offsetTop;
// 计算得到鼠标相对于按钮左边和上边距离
const x = pageX - left;
const y = pageY - top;
// 设置自定义属性
this.style.setProperty("--left", x + "px");
this.style.setProperty("--top", y + "px");
};
</script>
</body>十二、综合实战:带悬停效果的导航
<style>
body,
ul {
margin: 0;
}
ul {
padding: 0;
list-style: none;
}
a {
text-decoration: none;
color: #000;
}
.nav {
height: 50px;
background-color: skyblue;
text-align: center;
margin-top: 50px;
}
.nav ul {
width: 1200px;
margin: 0 auto;
height: inherit;
}
.nav ul li {
float: left;
font-size: 16px;
height: inherit;
}
.nav ul li a {
display: block;
padding: 0px 20px;
line-height: 50px;
position: relative;
z-index: 0;
}
/* 背景滑块 */
.nav ul li a::after {
content: "";
position: absolute;
left: 0;
right: 0;
top: -5px;
bottom: -5px;
background-color: rgb(2, 139, 194);
display: none;
z-index: -1;
}
.nav ul li a:hover {
color: #fff;
}
.nav ul li a:hover::after {
display: block;
}
</style>
<body>
<div class="nav">
<ul>
<li><a href="#">首页</a></li>
<li><a href="#">免费直播课</a></li>
<li><a href="#">web前端工程师</a></li>
<li><a href="#">Java架构师</a></li>
<li><a href="#">实战案例视频</a></li>
<li><a href="#">关于我们</a></li>
</ul>
</div>
</body>十三、综合实战:弹性滑动导航
<style>
body,
ul {
margin: 0;
}
ul {
padding: 0;
list-style: none;
}
a {
text-decoration: none;
color: #000;
}
.nav {
height: 50px;
background-color: skyblue;
text-align: center;
margin-top: 50px;
}
.nav ul {
width: 1200px;
margin: 0 auto;
height: inherit;
position: relative;
z-index: 0;
}
.nav ul li {
float: left;
font-size: 16px;
height: inherit;
}
.nav ul li a {
display: block;
padding: 0px 20px;
line-height: 50px;
}
/* 滑块 */
.nav ul li:last-child {
width: 72px;
height: 60px;
background-color: rgb(3, 135, 187);
position: absolute;
left: 0px;
top: -5px;
z-index: -1;
transition: left 0.3s, width 0.3s;
}
</style>
<body>
<div class="nav">
<ul>
<li><a href="#">首页</a></li>
<li><a href="#">免费直播课</a></li>
<li><a href="#">web前端工程师</a></li>
<li><a href="#">Java架构师</a></li>
<li><a href="#">实战案例视频</a></li>
<li><a href="#">关于我们</a></li>
<li class="move"></li>
</ul>
</div>
<script>
const move = document.querySelector(".move");
const oUl = document.querySelector(".nav ul");
let prevA = document.querySelector(".nav ul li:first-child a");
oUl.addEventListener("mouseover", function (e) {
const target = e.target;
if (target.tagName.toLowerCase() !== "a") return;
const width = target.offsetWidth;
const height = target.offsetHeight;
const left = target.offsetLeft;
move.style.width = width + "px";
move.style.height = height + 10 + "px";
move.style.left = left + "px";
if (prevA) {
prevA.style.color = "#000";
}
target.style.color = "#fff";
prevA = target;
});
</script>
</body>十四、综合实战:二级下拉菜单
<style>
body,
ul,
li {
margin: 0;
padding: 0;
}
li {
list-style: none;
}
a {
text-decoration: none;
color: #fff;
}
.menu {
height: 80px;
background-color: skyblue;
}
.menu-list {
width: 1000px;
margin: 0 auto;
}
.menu-list > li {
float: left;
position: relative;
}
.menu-list > li > a {
display: block;
padding: 0 20px;
line-height: 80px;
color: #fff;
}
/* 二级菜单 */
.menu-list > li .submenu {
display: none;
position: absolute;
left: 0;
right: 0;
top: 80px;
z-index: 2;
}
.menu-list > li:hover {
background-color: rgb(54, 172, 219);
}
.menu-list > li:hover .submenu {
display: block;
}
.menu-list > li .submenu a {
display: block;
line-height: 50px;
text-align: center;
background-color: skyblue;
}
.menu-list > li .submenu a:hover {
background-color: rgb(54, 172, 219);
}
</style>
<body>
<div class="menu">
<ul class="menu-list">
<li><a href="#">首页</a></li>
<li><a href="#">免费直播课</a></li>
<li>
<a href="#">web前端工程师</a>
<!-- 二级下拉菜单 -->
<ul class="submenu">
<li><a href="#">HTML5+CSS3</a></li>
<li><a href="#">JavaScript</a></li>
<li><a href="#">Vue3</a></li>
</ul>
</li>
<li><a href="#">Java架构师</a></li>
<li><a href="#">实战案例视频</a></li>
<li><a href="#">关于我们</a></li>
</ul>
</div>
</body>