定位实战应用

学习

定位实战应用

2026-02-23/0/ 编辑


定位实战应用

一、绝对定位实现垂直水平居中

方法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>