马黑黑 发表于 2026-3-14 12:48

CSS内外边距属性使用百分

<style>
        .artBox { margin: auto; max-width: 1200px; font: normal 18px/1.2 sans-serif; overflow: auto; position: relative; }
        .artBox p { margin: 10px 0; }
        .artBox h1, .artBox h2 { margin: 4px 0; }
        .artBox code, .artBox pre { background: rgba(0,128,128,.25); padding: 2px 6px; tab-size: 4; }
        .artBox pre { padding: 10px 20px; white-space: pre-wrap; word-wrap: break-word; }
        .artBox pre code { padding: 0; background: none; }
        .artBox blockquote { margin: 10px 20px; padding: 2px 15px; border-left: 3px solid skyblue; background: rgba(240,248,255,.65); }
        .tMid { text-align: center; }
</style>

<div class="artBox">
    <p>根据最新的 CSS 规范,百分比外边距(margin)和内边距(padding)的计算取决于书写模式(writing-mode):</p>
    <blockquote>
      <p>&#128311; 在水平书写模式(如默认的 horizontal-tb)下,所有方向的百分比边距都相对于包含块的宽度。</p>
      <p>&#128311; 在垂直书写模式(如 vertical-rl)下,所有方向的百分比边距都相对于包含块的高度。</p>
    </blockquote>
    <p>参考如下例子可能可以帮助理解 margin-*、padding-* 值取百分比时其值与容器元素宽高的关系:</p>
    <pre><code>&lt;style&gt;
        .pa {
                margin: 1.5rem auto;
                position: relative;
                width: 400px;
                height: 200px;
                background: #eee;
                border: 1px solid gray;
        }
        .son {
                margin-top: 25%;
                margin-left: 50%;
                width: 100px;
                height: 100px;
                background: #ccc;
        }
&lt;/style&gt;

&lt;div class="pa"&gt;
    &lt;span style="position: absolute; top: 10px; right: 10px;"&gt;心之所向&lt;/span&gt;
        &lt;div class="son"&gt;&lt;/div&gt;
&lt;/div&gt;
</code></pre>
        <div class="showing"></div>
    <p class="tMid"><button id="chgWritingMode" value="horizontal-tb">切换元素 class="ma" 书写模式</button></p>
    <p>容器 pa 固定宽高 400*200。默认书写模式下,子元素 son 的外边距均以父元素宽度做参照:上外边距设为 25%,是取容器宽度 400 的四分之一即 100px,son 的顶端距容器 pa 的顶部 100px;左边距设为 50%,取的也是容器宽度 400 的一半即 200px,son 的左端距容器 pa 的左端 200px。改变书写模式为垂直方向,则子元素 son 的外边距均以父容器的高度做参照:25% 的上边距取 pa 的高度 200 的四分之一即 50px,50% 的左边距取 pa 高度 200 的一半即 100px。</p>
    <p>若容器内的子元素 padding-* 也取百分比值,百分比所参照的同样是依据书写模式而取父元素即其所在的容器元素的宽或高。padding 是内边距,指其里面的内容和其边框的距离。内边距百分比值也有应用场景,常见的用法是占位,例如像这样:</p>
    <pre><code>&lt;style&gt;
        .ma {
                margin: 1.5rem auto;
                width: 400px;
                background: #eee;
                border: 1px solid gray;
        }
        .ma::before {
                display: block; /* 设为块级元素以占位 */
                content: '::before'; /* 演示用,content值可为空 */
                padding-bottom: 50%; /* padding-top 也可以 */
        }
&lt;/style&gt;

&lt;div class="ma"&gt;&lt;/div&gt;</code></pre>
        <div class="showing"></div>
    <p>.ma 没有设置高度,我们是希望将来通过其内的内容决定其高度,同时又希望 ma 元素占据一定的纵向空间,所以通过其伪元素 ::before 的
      <code>padding: 50%;</code> 占位,50% 用的是 ma 的宽度。这里,ma 元素的相关设置可能的场景是保障页面布局的固定性以避免页面加载时“闪烁”,将来里面内容的高度一般也是设置为 ma 现有的高度,该高度在其内内容(例如图片)加载前就已由其 ::before 伪元素撑开,为后续的内容做好空间准备。
    </p>
    <p>&#128171; margin-* 和 padding-* 的百分比赋值可能是个冷门知识,但有其特殊的应用场景,占位、定位是较常见的用途。其核心是:*-top/bottom 的百分比取值参照容器元素的宽度、*-left/right 的百分比取值参照容器元素的高度。</p>
</div>

<script>
        var hCodes = document.querySelectorAll('.artBox code');
        var rBoxes = document.querySelectorAll('.artBox .showing');
        rBoxes.forEach((box, idx) => {
                box.innerHTML = hCodes.innerText ;
        });
       
        chgWritingMode.onclick = () => {
                var pa = document.querySelector('.pa');
                var mode = chgWritingMode.value === 'horizontal-tb' ? 'vertical-lr' : 'horizontal-tb';
                pa.style.writingMode = mode;
                chgWritingMode.value = mode;
        };
</script>

红影 发表于 2026-3-14 15:54

这个百分比的参照依据还奇怪,竟然上下参照的是宽度,而左右参照的是高度,这个太奇怪了。
那个例子也奇怪,“son 的顶端距容器 pa 的顶部 100px;”这个没问题,“son 的左端距容器 pa 的左端 100px”这个不对,我去量了一下,距离左边是200px啊,会不会都是参照的宽度?{:4_203:}

红影 发表于 2026-3-14 15:56

这个只是的确挺冷门的,一般都是直接使用数字,用百分比原来意义是不同的。

马黑黑 发表于 2026-3-14 17:43

红影 发表于 2026-3-14 15:54
这个百分比的参照依据还奇怪,竟然上下参照的是宽度,而左右参照的是高度,这个太奇怪了。
那个例子也奇怪 ...

我是昨天翻看N多年前买的书才写的这篇文章。经你提醒,我去查阅了新的标准,我引用的 W3C 那段话来自较早的规范或特定上下文,描述的是旧有行为,现行标准已经不是这样了。

谢谢你的发现,本文也已经根据新标准进行了修正。

杨帆 发表于 2026-3-14 18:25

马黑黑 发表于 2026-3-14 17:43
我是昨天翻看N多年前买的书才写的这篇文章。经你提醒,我去查阅了新的标准,我引用的 W3C 那段话来自较早 ...

哇,知识迭代好快,谢谢马老师经典讲授{:4_180:}

马黑黑 发表于 2026-3-14 19:45

杨帆 发表于 2026-3-14 18:25
哇,知识迭代好快,谢谢马老师经典讲授

这篇文章,一方面是一时冲动写了,另一方面也是为了探究 iframe 的自适应高度而作。我自己也不曾想到过去的权威现在已经产生如此彻底的变化。

杨帆 发表于 2026-3-14 20:45

马黑黑 发表于 2026-3-14 19:45
这篇文章,一方面是一时冲动写了,另一方面也是为了探究 iframe 的自适应高度而作。我自己也不曾想到过去 ...

是啊,学习是终生的课题,谢谢老师的讲座与探究{:4_180:}

红影 发表于 2026-3-15 22:49

马黑黑 发表于 2026-3-14 17:43
我是昨天翻看N多年前买的书才写的这篇文章。经你提醒,我去查阅了新的标准,我引用的 W3C 那段话来自较早 ...

嗯嗯,看到修改的内容了,辛苦黑黑{:4_187:}

马黑黑 发表于 2026-3-16 13:45

红影 发表于 2026-3-15 22:49
嗯嗯,看到修改的内容了,辛苦黑黑

还是得感谢你

红影 发表于 2026-3-18 11:35

马黑黑 发表于 2026-3-16 13:45
还是得感谢你

咋这么说,应该谢谢你才是,你带来了那么多好东西{:4_187:}

马黑黑 发表于 2026-3-18 14:36

红影 发表于 2026-3-18 11:35
咋这么说,应该谢谢你才是,你带来了那么多好东西

这都是随手的,没啥

红影 发表于 2026-3-21 16:15

马黑黑 发表于 2026-3-18 14:36
这都是随手的,没啥

随手都是好东西,黑黑真是大宝库啊。

马黑黑 发表于 2026-3-21 19:58

红影 发表于 2026-3-21 16:15
随手都是好东西,黑黑真是大宝库啊。

哪里哪里?湿湿水而已

红影 发表于 2026-3-21 21:59

马黑黑 发表于 2026-3-21 19:58
哪里哪里?湿湿水而已

这说法真好玩{:4_173:}

马黑黑 发表于 2026-3-21 22:36

红影 发表于 2026-3-21 21:59
这说法真好玩

湿湿水是粤语词汇

红影 发表于 2026-3-22 16:37

马黑黑 发表于 2026-3-21 22:36
湿湿水是粤语词汇

知道,虽然不是很清楚具体的意思。

马黑黑 发表于 2026-3-22 18:12

红影 发表于 2026-3-22 16:37
知道,虽然不是很清楚具体的意思。

就是差不多的意思

红影 发表于 2026-3-22 21:52

马黑黑 发表于 2026-3-22 18:12
就是差不多的意思

我觉得是意思意思的意思{:4_173:}

马黑黑 发表于 2026-3-23 08:20

红影 发表于 2026-3-22 21:52
我觉得是意思意思的意思

你这个意思意思的意思也是很有意思的

红影 发表于 2026-3-23 21:38

马黑黑 发表于 2026-3-23 08:20
你这个意思意思的意思也是很有意思的

说意思意思的意思有意思更有意思{:4_173:}
页: [1] 2
查看完整版本: CSS内外边距属性使用百分