CSS定位与布局问题:绝对定位问题?

作者站长头像
站长
· 阅读数 25

css问题 下面代码 为什么ul使用绝对定位居中 a元素变成块元素 文字会垂直代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    *{
        /* 初始化 取消页面的内外边距 */
        margin: 0;
        padding: 0;
    }
    body{
        /* 100%窗口高度 */
        height: 100vh;
        /* 渐变背景 本人比较偏爱渐变背景 */
        background: linear-gradient(200deg,#dad4ec,#f3e7e9);
    }
    ul{
        /* 绝对定位 水平、垂直居中 */
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%,-50%);
        /* 弹性布局 */
        display: flex;
        margin: 0;
        padding: 0;
    }
    ul li{
        list-style: none;
        /* 这里加个动画过渡 */
        transition: 0.5s;
    }
    ul li a{
        /* 相对定位 */
        position: relative;
        display: block;
        text-align: center;
        margin: 0 30px;
        color: #333;
        font-size: 40px;
        text-decoration: none;
    }
</style>
<body>
<ul>
    <li><a href="#">首页</a></li>
    <li><a href="#">关于我们</a></li>
    <li><a href="#">服务</a></li>
    <li><a href="#">案例</a></li>
    <li><a href="#">用户反馈</a></li>
</ul>
</body>
</html>

为什么用绝对定位居中宽度展示文字会被挤下去 如下图CSS定位与布局问题:绝对定位问题?如果用flex布局居中就是没问题代码如下图

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <style>
        *{
            /* 初始化 取消页面的内外边距 */
            margin: 0;
            padding: 0;
        }
        body{
            display: flex;
            justify-content: center;
            align-items: center;
            /* 100%窗口高度 */
            height: 100vh;
            /* 渐变背景 本人比较偏爱渐变背景 */
            background: linear-gradient(200deg,#dad4ec,#f3e7e9);
        }
        ul{
            /* 绝对定位 水平、垂直居中 */

            /* 弹性布局 */
            display: flex;
            margin: 0;
            padding: 0;
        }
        ul li{
            list-style: none;
            /* 这里加个动画过渡 */
            transition: 0.5s;
        }
        ul li a{
            /* 相对定位 */
            position: relative;
            display: block;
            text-align: center;
            margin: 0 30px;
            color: #333;
            font-size: 40px;
            text-decoration: none;
        }
    </style>
    <body>
    <ul>
        <li><a href="#">首页</a></li>
        <li><a href="#">关于我们</a></li>
        <li><a href="#">服务</a></li>
        <li><a href="#">案例</a></li>
        <li><a href="#">用户反馈</a></li>
    </ul>
    </body>
    </html>

效果如下图CSS定位与布局问题:绝对定位问题?

回复
1个回答
avatar
test
2024-06-19

其实和absolute元素的block width的计算有关

css2 block width: Absolutely positioned, non-replaced elements

the constraint that determines the used values for these elements is:left + margin-left + border-left-width + padding-left + width+ padding-right + border-right-width + margin-right + right = width of containing block(解读: static定位时,是不需要考虑left和right的。我们对最终效果的不理解大概是没有考虑到left和right)

该问题背景下应该应用以下计算规则。

Otherwise, set 'auto' values for 'margin-left' and 'margin-right'to 0, and pick the one of the following six rules that applies.

  1. width and right are auto and left is not auto, then the width is shrink-to-fit . Then solve for right

如何计算shrink-to-fit?

Calculation of the shrink-to-fit width is similar to calculating the width of a table cell using the automatic table layout algorithm. Roughly: calculate the preferred width(解读:最大内容宽度?) by formatting the content without breaking lines other than where explicit line breaks occur, and also calculate the preferred minimum width(解读:最小内容宽度?), e.g., by trying all possible line breaks. CSS 2.1 does not define the exact algorithm. Thirdly, calculate the available width: this is found by solving for 'width' after setting 'left' (in case 1) or 'right' (in case 3) to 0.(解读:这里我们需要先假设right为0)Then the shrink-to-fit width(解读:fit-content?) is: min(max(preferred minimum width, available width), preferred width).

在该问题背景下,最终计算得到的shrink-to-fit width应该是available width

  • 如果包含块再小一些的话,就可能是preferred minimum with,每一个元素都被挤到一列排布了。
  • 如果包含块比较大的话(可以通过缩放页面来得到一个大的包含块),就可能是preferred with,每个元素的文本按一行来排布。

最后再计算right(之前在计算width的时候假设right为0,并不是它最终的计算值)。该问题背景下right应该为0。但是从最终的效果来看,它是水平居中的,离着右侧边缘还有一定的距离,怎么会是0呢?因为我们使用了transform: translate(-50%, -50%)

附:由于对absolute元素的block width的计算产的误解而导致和预想的不一致或对产生的效果不理解的问题,看到过几次了。(今天我在为回答问题overflow创建的BFC和float创建的BFC 为什么会有这样的区别?而查阅资料的时候,偶然在文档中发现对应的说明😂。)

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容