Uncollapsing Margins

本文探讨了CSS中常见的边距折叠现象,并介绍了如何通过设置内边距或边框来防止边距折叠,确保元素布局符合预期。

原文地址:http://www.complexspiral.com/publications/uncollapsing-margins/

Uncollapsing Margins

Like many basic concepts, margin collapsing can lead to unexpected and sometimes counterintuitive results. Before we explore those results and how to work around them, however, let's take a look at the most basic form of margin collapsing.

Consider a series of paragraphs that have the following style applied to them:

p {margin: 10px 0; background: #CCC;}

The separation between the outer border edges of these paragraphs will be ten pixels, as shown in Figure 1.

 

Figure 1. Adjacent paragraphs with collapsed margins.

Why is this? Because it's what authors would tend to expect. If you declare top and bottom margins of 1em for paragraphs, odds are that you want one em of space between successive paragraphs. If you're feeling dubious about that assertion, consider this:

p {margin: 1em 0;}

ul {margin: 1em 0;}

Closing Up Headings

A common typographical effect is to place paragraph text up close to a heading. Some people solve this by adding a class to a paragraph that immediately follows a heading, and then removing the top margin from such paragraphs. Thanks to margin collapsing, though, there's a more elegant way to solve the problem. Consider:

h1, h2, h3, h4, h5, h6 {margin-bottom: 0;}

p {margin: 0 0 1em;}

Given those rules, any paragraph that immediately follows a heading will sit right up next to it, while successive paragraphs will still be separated by a "blank line". Because margin collapsing between paragraphs causes the top and bottom margins to collapse, we can remove one of the two without changing the layout situation at all. Thus, the presence of the bottom margin on paragraphs keeps them their usual distance apart, while still allowing them to snuggle up close to headings.

The odds are very high that what the author expects, given those simple rules, is that the separation between a paragraph and a list will be one em, not two em. If more is desired, then the rules can be adjusted; for example, the margins of the ul element could be increased.

Having established all that, let's talk about a situation where margin collapsing does something that authors rarely want to see.

Marginal Excesses

The workhorse of tableless layout is the div element. Sidebars, mastheads, footers, and more all find themselves defined by an ID'ed div in such designs. Aside from its relative semantic neutrality, the div is particularly suited to this purpose because it is a flow element, which in HTML is an element that can contain both block and inline elements. In other words, you can put just about any element inside a div.

The other primary advantage of the div is that it traditionally generates a block-level box, but has no other inherent presentation. In CSS terms, a browser's built-in style sheet would assert, simply:

div {display: block;}

Astonishingly, this simple bit of style masks a potential layout problem—one that arises not because of something the author does, but more because of what the author neglects to do.

We can illustrate this problem easily enough simply by adding two elements and a small bit of style. Consider the following markup:

<div id="masthead">

<h1>ConHugeCo</h1>

<p>Making the world safe for super sizes</p>

</div>

To that very simple bit of structure, we'll apply the following very simple styles, with the result seen in Figure 2.

#masthead {background: #F80; margin: 10px;}

#masthead h1 {margin: 20px 10px;}

#masthead p {margin: 5px 10px; font-style: italic;}

Figure 2. The (barely) styled masthead.

Notice how close the content of the h1 gets to the top of the div's background area? You might expect that there would be twenty pixels of margin between the top of the h1 and the top of the div. Instead, the top margin of the h1 is actually "sticking out" of the div. The two margins actually overlap. THe same is true for the bottom margin of the p element and the bottom margin of the div.

Let's illustrate this by adding dashed lines to represent the outer margin edges of the three elements.

Figure 3. The margins revealed.

In Figure 3, the margins of the div are represented by a dotted gray border, the margins of the h1 by a dotted red border, and the p element by dotted blue. As you can see, the margins of the h1 and the p overlap each other, which is normal collapsing behavior. It's the same thing that happens between successive paragraphs. You can also see that the top margin of the h1 sticks out of the masthead's content area, overlapping and exceeding the top margin of the div. A similar thing happens with the bottom of the p element.

You might well wonder why this is anything resembling a good idea. To understand it, let's take that paragraph and put it into a different set of circumstances.

Looking At Lists

The style and markup that will illustrate this point are as simple as our earlier example:

li {background: #FB8; margin: 2px;}

p {margin: 10px;}

 

<li>

<p>This is a paragraph in a two-paragraph list item.</p>

<p>This is also a paragraph in a two-paragraph item.</p>

</li>

For the purposes of this exercise, we'll assume the list item is part of an unordered list. List items can contain paragraphs because they, like divs, are flow elements. In fact, a list item can contain any markup that a div can contain.

Here's how the markup is rendered, with additional dotted lines to mark where the margins fall.

Figure 4. Where the margins sit.

See how the paragraph margins stick out of the top and bottom of the list item? It's the same behavior that we saw with the masthead example earlier in the article. Now notice how the first line of the first paragraph lines up nicely with the list item's marker (the filled bullet symbol). That can only happen because of margin collapsing, which is what's allowing the paragraph's top margin to stick out of the list item. Imagine that margins were prevented from doing this. If that were true, the result could very easily be what we see in Figure 5.

Figure 5. Misalignment could result without margin collapsing.

Nobody would want that to happen: it just doesn't look good. On the other hand, this is exactly what we want to have happen in the masthead: to have the margins sit inside the masthead, not collapse to the outside. So how do we keep the margins from sticking out of the masthead? There are a few ways, as it happens.

Uncollapsing

In order to "un-collapse" the margin, there are two basic solutions: padding or borders. The key is to place them appropriately. Which solution is better will depend on the design requirements for a given project.

In either case, you need to apply the padding or border to the masthead itself. Let's consider padding first. We'll add the smallest possible padding to the masthead, just one pixel on the top and bottom and none on the sides, with the result seen in Figure 6.

#masthead {background: #F80; margin: 10px; padding: 1px 0;}

#masthead h1 {margin: 20px 10px;}

#masthead p {margin: 5px 10px; font-style: italic;}

Figure 6. Masthead padding yields the desired result.

Because of the padding, the margins of the h1 and p elements do not collapse with the margins of the masthead. They are instead "contained" within the masthead's content area. This is in accordance with CSS2.1, section 8.3.1[1], but the behavior actually goes back to CSS1. Its intent, as is so often the case, is to satisfy expected authorial desires. After all, that's what drove the margin collapsing behavior illustrated by Figure 4.

Alternatively, you could kill the top margin on the h1 and the bottom margin on the p element, and create the needed space with padding on the masthead itself, like this:

#masthead {background: #F80; margin: 10px; padding: 20px 5px;}

#masthead h1 {margin: 0 10px 20px;}

#masthead p {margin: 5px 10px 0; font-style: italic;}

This would create the precise distances that were originally intended. With the one-pixel padding on the masthead shown in Figure 6, the padding "wraps around" all of the content inside the masthead. Thus there would be 21 pixels of space between the top of the h1's content area and the top of the masthead's background, not 20 pixels. If that's a real problem, then the one-pixel approach won't work. You'll have to use masthead padding and remove the margins instead, as shown in the most recent example.

Another way to keep the margins contained is to set a border on the masthead. This border can be the same color as the page background, thus making it effectively invisible. For example:

#masthead {background: #F80; margin: 10px; border: 1px solid #FFF;}

#masthead h1 {margin: 20px 10px;}

#masthead p {margin: 5px 10px; font-style: italic;}

In this case, the separation between the visible top of the masthead and the top of the h1's content area will be exactly 20 pixels, since the border sits outside that margin but blends into the page background—assuming that background is a solid color, of course. If you set the masthead's border to another color, like gray, then you'll find a distance of 20 pixels from the top of the h1's content area to the inner edge of the top border.

Summary

In the majority of cases, margin collapsing delivers the types of layout results we want. It's only in those cases where we want margins to be "contained" by other elements that things can go a bit awry. Thanks to the way CSS is written, however, there are ways to overcome the unwanted collapsing. By associating either padding or a border with an element, it will "contain" the margins of descendant elements.

  • [1] The most relevant portion of this section is the last sentence of the first bullet point, which states: "Note. Adjoining boxes may be generated by elements that are not related as siblings or ancestors."

 

### Margins 命令在 Stata 中的具体含义和用法 `margins` 是 Stata 中用于估计边际效应(Marginal Effects)、预测均值(Predicted Means)和其他统计量的重要命令。该命令通常在回归分析之后使用,能够帮助研究者理解自变量变化对因变量的影响程度。 #### 1. **Margins 的基本概念** `margins` 主要用来计算平均边际效应(Average Marginal Effects, AME),特定观测值的边际效应(Marginal Effects at Specific Values, MEsSV),或者调整后的预测值(Adjusted Predictions)。这些统计量可以帮助解释复杂模型中的系数意义[^1]。 #### 2. **语法结构** 以下是 `margins` 的基础语法: ```stata margins [varlist] [, options] ``` - `[varlist]`: 可选参数,指定需要计算边际效应的变量列表。 - `, options`: 提供多种选项来控制输出的内容和形式。 常见的选项包括但不限于: - `at()`: 设置某些变量的固定取值水平。 - `dydx(varname)`: 计算某个连续变量的变化对其它变量的导数。 - `predict(outcome(#))`: 对于分类模型(如 logit 或 probit),指定感兴趣的类别进行预测。 - `post`: 将结果存储到内存中以便后续调用其他命令处理。 #### 3. **实际应用案例** ##### (a) 连续型变量的边际效应 假设我们运行了一个线性回归模型: ```stata regress y x1 x2 ``` 接着可以通过以下方式获取 `x1` 和 `x2` 的平均边际效应: ```stata margins, dydx(x1 x2) ``` 这会返回两个独立变量对于响应变量 `y` 平均影响大小的结果[^1]。 ##### (b) 类别型变量的不同组间比较 如果我们的模型涉及虚拟变量,则可以利用如下方法对比不同类别的效果差异: ```stata logistic outcome treatment##group covariates margins group, over(treatment) ``` 这里展示了如何基于逻辑回归探索治疗措施 (`treatment`) 跨群体 (`group`) 表现是否存在显著区别[^1]。 #### 4. **注意事项** 尽管 `margins` 功能强大,但在具体操作过程中仍需注意几点事项: - 正确解读所得数值的实际物理意义; - 验证所设定条件是否合理反映真实世界情境; - 结合图形展示增强结论说服力。 --- ### 示例代码 下面提供一段完整的例子演示如何运用 `margins` 来探讨教育年限(`educ`)对收入(`income`)的作用关系: ```stata sysuse nlsw88.dta, clear gen byte highschool = grade >= 12 if !missing(grade) // 执行多元回归 reg income i.highschool c.ttl_exp c.ttl_exp#c.ttl_exp // 查看高中毕业状态下的AME margins, dydx(highschool) // 探讨工作经验平方项带来的非线性趋势 margins, atmeans predictnl effect_at_0_years = _b[_cons], se(se_effect_at_0_years) ``` 此脚本不仅揭示了学历提升所带来的经济回报率变动情况,还深入挖掘了职业经历长度可能存在的二次曲线特征。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值