编程语言研究书库

显示与定位 — 元素怎么站队、怎么脱队

显示与定位 — 元素怎么站队、怎么脱队

这一章回答三个日常问题: 「怎么把这个元素藏起来」「怎么让导航条钉在屏幕顶上」 「怎么让弹窗正好盖住页面」。三件对应三样本事:display 与隐藏三法、五种定位、 以及内容溢出(overflow)的处置。原书拆成第 5、6 两章,这里合在一起讲—— 它们管的都是「盒模型(上一章)算出来的盒子,往哪儿放」。

1. 这一章在全书链条里的位置

盒模型回答了「盒子多大」,这一章回答「盒子怎么排、怎么挪、怎么藏」。 站队的方式(display)一旦定下来,后面 Flexbox、Grid 两章才有施展的舞台—— 它们本质上都是「把 display 换成 flex / grid 后解锁的高级站队规则」。 而定位(position)是「我不想站队了」的出口:弹窗、提示条、钉住的导航,全靠它。

2. 顶层全景:默认流,与三条出路

默认(文档流):块级盒子从上到下堆,行内盒子从左到右排
   │
   ├─ 出路一:换 display —— 换站队方式(block / inline / inline-block / none)
   │
   ├─ 出路二:换 position —— 脱队,自己找锚点(relative / absolute / fixed / sticky)
   │
   └─ 出路三:overflow —— 盒子装不下内容时,裁剪还是滚动

图说:前两条管「盒子去哪儿」,第三条管「装不下的内容怎么办」。

书里给 display 的评价极高,称它「可以说是 CSS 里最重要的属性」—— 它决定渲染引擎把元素当块、当行内文字、还是彻底移除1。

3. 核心原理:display 与站队

block、inline、inline-block 三家

block(块级):<div>、<h1>、<p> 默认就是。独占一整行,宽度自动拉满, 上下天然和其他块隔开。像剧院里一人一排的座位。

inline(行内):<span>、<a> 默认就是。只占自己内容的宽度,不独占行, 但有一条硬限制:width、height 对它无效,垂直方向的内边距也压线2。 「我给 span 设了宽度怎么没用」——全书最常见的初学者疑问,答案就是它。

inline-block:两者兼得——可以设宽高、可以上下留白,同时仍坐在文字流里不独占行。 书里给的典型用途:把纵向的列表项(li)改成横向菜单3。

值占宽能吃 width/height例子
block拉满整行能div、h1、p
inline只占内容不能span、a
inline-block内容宽,但可调能横向菜单的 li

none:元素彻底移除,不占地、不可见,仿佛没写过4。 和第 4 节的「隐藏」不同——none 连位置都不留。

主线例子的第一段:一个藏起来的提示条

输入:一个按钮和一个提示条,要求「鼠标悬停才出现」。

.tooltip { display: none; }              /* 平时:彻底不存在 */
.button:hover .tooltip { display: block; }  /* 悬停:以块级身份出现 */

效果:平时页面没有提示条的任何痕迹(连空隙都没有);鼠标移到按钮上,提示条出现。 这是 display 两值的组合拳,也是「状态伪类 + display」的第一个实战5。

4. 核心原理:藏起来的三种办法

「藏起来」有三层不同的意思,书里分得很清——选错是高频 bug:

办法效果位置还在吗适用
display: none元素不存在不在真移除:收起、菜单关闭
visibility: hidden看不见在,留下一片空白6要保留布局的占位
opacity: 0.5半透明在淡出淡入的中间态

opacity 管整条「透明度连续谱」:0.0 全透明到 1.0 全不透明,设 0.5 就是五成透7。 它和上面两法不在一个维度——它是「调透明度」,不是「开关可见性」。 有一条连锁规则要记牢:opacity 会传染给所有孩子——父元素 0.5,子元素设 1.0 也回不来, 孩子永远至少和父元素一样透8。想「背景半透明、文字不透明」?那是第 09 章 rgba 的活, opacity 做不到。

overflow 是第四条,管「装不下」:内容超出盒子的宽高时怎么办。

值效果
visible(默认)溢出来,照画9
hidden裁掉,不可见
scroll裁掉,但永远显示滚动条
auto内容超了才出滚动条——日常首选

书里两个实用模式:圆角卡片里溢出的内容,用 overflow: hidden 沿圆角裁齐10; 内容多少不确定的盒子,用 overflow: auto 自适应滚动11。 注意 scroll 与 auto 的差别:scroll 内容不够也强行画滚动条,丑——一般选 auto。

5. 核心原理:position,脱队的五种姿势

先建立锚的概念

包含块(containing block):一个定位元素找「谁当参考系」。 规则一句话:用 absolute 的元素,会找最近的、position 不是 static 的祖先当锚; 找不到就一路找到页面根上12。这是理解 absolute 的全部钥匙。

五种取值

值相对谁原位置场景
static(默认)——站队中一切正常状态
relative自己的原位置保留(邻居不让位)13微调、给 absolute 孩子当锚
absolute最近的非 static 祖先不保留,脱队14弹窗、角标、提示
fixed浏览器视口(屏幕)不保留钉住的导航、回到顶部按钮
sticky先 relative,滚过阈值改 fixed——滚动触发的钉住15

配合四个偏移属性 top / right / bottom / left 落坐标。

主线例子的第二段:弹窗钉在卡片右上角

接着第 3 段的例子。HTML 结构:卡片 <div class="parent"> 里有个 <div class="child"> 角标。

.parent { position: relative; width: 300px; height: 200px; }
.child  { position: absolute; top: 10px; right: 10px; }

走一遍流程:.parent 声明 relative——它自己不挪(没有偏移量), 但从此有资格当锚;.child 声明 absolute——脱队,找最近的非 static 祖先, 找到 .parent,把自己钉在它的右上角往里 10px 处16。 书里那个「消失的 absolute 元素」警告就是这个流程的反例: 忘了给父级 relative,absolute 元素就一路锚到页根,飞到屏幕角落去了17。

钉在屏幕上只换一个词:position: fixed; top: 0; left: 0; width: 100%;—— 锚变成视口,滚动页面它不动18。手机上有条书里点名的坑:键盘弹出时 fixed 元素可能抖动错位19。

sticky 最年轻也最易翻车:它要求至少给一个偏移量(如 top: 0), 且任何父级都不能有 overflow: hidden——父级一旦裁剪,sticky 就失效20。 失效时它退回普通 static,不报错,最难查。

z-index:谁盖着谁

重叠发生时,z-index: 数字 决定前后;数字大的在上面,默认 auto 相当于 021。 铁律一条:z-index 只对非 static 元素生效——position: static 的元素设多大都没用, 这是「z-index 失灵」投诉的九成原因22。弹窗盖住一切的手法就是 position: fixed; z-index: 100;——先脱队,再抬层。

一个把 relative + absolute + transform 串起来的名场面

完美居中一个弹窗,三行合谋:

.overlay {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);  /* 把自己往回拉自身的一半 */
}

top/left: 50% 把弹窗的左上角推到容器正中——偏了;translate(-50%, -50%) 再把它往回拉自身宽高的一半,正好居中23。transform 的详细机制在第 11 章, 这里当作「absolute 的经典搭档」记住即可。

6. 作者的判断与证据

  • 「display 是 CSS 里最重要的属性」——作者断言(用了 arguably,留了余地)1。
  • 「opacity 传染给孩子,子级无法复原」——事实性陈述,是 CSS 的硬规则8。
  • 「sticky 的失效条件(父级 overflow: hidden)」——事实性陈述,但本书没解释为什么 (sticky 需要在父级盒内滚动,裁剪后滚动上下文消失)。这类「给结论不给原因」的条目 在速查书里是常态。
  • 「手机上小心 fixed,键盘会捣乱」——经验断言,无数据19。
  • 证据类型依旧:断言 + 最小例子,无系统性验证。

7. 边界与局限

  • 没讲 display 的完整现代值表(flow-root、contents、双值语法如 block flex), 只列了最常用的六个——对速查定位是合理裁剪。
  • 没讲层叠上下文(stacking context)的形成条件——只给了名词24。 实际:z-index 的比较只在同一个层叠上下文内有效,opacity、transform、filter 等都会 意外创建新上下文,这是「z-index 9999 还被人压住」的真正原因。本书点名词不展开, 读者撞上此坑需查 MDN。
  • sticky 在表格里的妙用(粘性表头)到第 13 章才出现,本章没提。

判断(我们的,不是书里的): 把「隐藏三法」并排成表是本章最值钱的部分—— 多数初学者把 display/visibility/opacity 混着用,排完表就再也不会选错。 本章最大的洞是层叠上下文:只给名词不给形成条件,z-index 的疑难杂症因此无解。 如果错,会错在: 对纯初学者,层叠上下文的规则链(position、opacity、transform 都会开新层) 讲早了会把「z-index 管前后」这条刚刚建立的基本直觉冲垮——先讲现象、后讲机制, 也是一条可以辩护的教法路径。

8. 可带走的

  1. block 独占一行;inline 不吃宽高;inline-block 居中取两者,行内菜单靠它3。
  2. display: none 连位置一起拿走;visibility: hidden 留下空白;opacity 只调透明度6。
  3. opacity 传染:父 0.5,子永远回不去 1.0;要「半透背景 + 实字」用 rgba(第 09 章)8。
  4. overflow 三选:裁圆角用 hidden,不确定内容用 auto,别用 scroll(强行出滚动条)11。
  5. absolute 找最近的非 static 祖先当锚;父级先 position: relative 是肌肉记忆12。
  6. fixed 钉屏幕,sticky 要 top 生效且父级不能有 overflow: hidden20。
  7. z-index 只对非 static 生效;弹窗 = fixed + 大 z-index22。
  8. 居中弹窗: absolute + top/left 50% + translate(-50%, -50%)23。

9. 原文地图

主题原书章原文位置
display 是最重要的属性Chapter 5: Display & Visibilitytext/06-ch01-1-chapter-overview.txt:7(搜「most important」)
block/inline 的流同上text/06-ch01-1-chapter-overview.txt:19(搜「stack vertically」)
display 常用值同上text/06-ch01-1-chapter-overview.txt:27(搜「display Values」)
隐藏提示条模式同上text/06-ch01-1-chapter-overview.txt:111(搜「Hidden Tooltip」)
visibility 留空白同上text/06-ch01-1-chapter-overview.txt:55(搜「without changing the layout」)
opacity 0–1 与传染同上text/06-ch01-1-chapter-overview.txt:69(搜「opacity」);:136 搜「at least as transparent」
overflow 四值同上text/06-ch01-1-chapter-overview.txt:85(搜「overflow」)
overflow 裁圆角同上text/06-ch01-1-chapter-overview.txt:123(搜「leak」)
文档流/包含块/层叠上下文Chapter 6: Positioningtext/07-ch01-1-chapter-overview.txt:19(搜「Document Flow」)
五种 position 取值同上text/07-ch01-1-chapter-overview.txt:27(搜「position」)
absolute 锚定父级示例同上text/07-ch01-1-chapter-overview.txt:48(搜「Becomes the anchor」)
fixed 钉屏同上text/07-ch01-1-chapter-overview.txt:71(搜「fixed-nav」)
z-index 只对非 static 生效同上text/07-ch01-1-chapter-overview.txt:80(搜「z-index」)
完美居中同上text/07-ch01-1-chapter-overview.txt:99(搜「Perfectly Centering」)
消失的 absolute 元素同上text/07-ch01-1-chapter-overview.txt:125(搜「Vanishing」)
sticky 的两个条件同上text/07-ch01-1-chapter-overview.txt:129(搜「Sticky Requirements」)
手机上小心 fixed同上text/07-ch01-1-chapter-overview.txt:131(搜「keyboard」)

Footnotes

  1. 出处:「Chapter 5: Display & Visibility」(text/06-ch01-1-chapter-overview.txt:7,搜「most important」)。原文:「The display property is arguably the most important property in CSS.」 ↩ ↩2

  2. 出处:「Chapter 5: Display & Visibility」(text/06-ch01-1-chapter-overview.txt:37,搜「Width/height properties are ignored」)。原文:inline「Takes only as much width as necessary; does not start on a new line. Width/height properties are ignored.」 ↩

  3. 出处:「Chapter 5: Display & Visibility」(text/06-ch01-1-chapter-overview.txt:47,搜「horizontal menu」)。原文:「Make a list look like a horizontal menu」,li { display: inline-block; margin-right: 10px; }。 ↩ ↩2

  4. 出处:「Chapter 5: Display & Visibility」(text/06-ch01-1-chapter-overview.txt:41,搜「none」)。原文:「Removes the element from the document entirely. It takes up no space.」 ↩

  5. 出处:「Chapter 5: Display & Visibility」(text/06-ch01-1-chapter-overview.txt:111,搜「Hidden Tooltip」)。原文模式:.tooltip { display: none; } + .button:hover .tooltip { display: block; }。 ↩

  6. 出处:「Chapter 5: Display & Visibility」(text/06-ch01-1-chapter-overview.txt:55,搜「without changing the layout」;:67 搜「empty space」)。原文:visibility「Shows or hides an element without changing the layout」,hidden 时「the empty space where it would be is still there」。 ↩ ↩2

  7. 出处:「Chapter 5: Display & Visibility」(text/06-ch01-1-chapter-overview.txt:75,搜「0.0」)。原文:「A number from 0.0 (fully transparent) to 1.0 (fully opaque)」。 ↩

  8. 出处:「Chapter 5: Display & Visibility」(text/06-ch01-1-chapter-overview.txt:136,搜「at least as transparent」)。原文:「If you set opacity: 0.5 on a parent, you cannot make a child opacity: 1.0 to 'fix' it. The child will always be at least as transparent as its parent.」 ↩ ↩2 ↩3

  9. 出处:「Chapter 5: Display & Visibility」(text/06-ch01-1-chapter-overview.txt:93,搜「Content spills out」)。原文:visible「Content spills out.」 ↩

  10. 出处:「Chapter 5: Display & Visibility」(text/06-ch01-1-chapter-overview.txt:123,搜「leak」)。原文:圆角容器里子元素可能「leak」出角,用 overflow: hidden 裁剪。 ↩

  11. 出处:「Chapter 5: Display & Visibility」(text/06-ch01-1-chapter-overview.txt:138,搜「better choice」)。原文:「overflow: scroll forces scrollbars to appear even if the content fits, which can look ugly. Usually, overflow: auto is the better choice.」 ↩ ↩2

  12. 出处:「Chapter 6: Positioning」(text/07-ch01-1-chapter-overview.txt:21,搜「Containing Block」)。原文:「When you use absolute positioning, the element looks for the nearest parent that has a position other than static to use as its anchor.」 ↩ ↩2

  13. 出处:「Chapter 6: Positioning」(text/07-ch01-1-chapter-overview.txt:37,搜「normal spot」)。原文:relative「Positioned relative to its normal spot. The space it originally occupied is preserved.」 ↩

  14. 出处:「Chapter 6: Positioning」(text/07-ch01-1-chapter-overview.txt:39,搜「nearest positioned ancestor」)。原文:absolute「Removed from the flow and positioned relative to its nearest positioned ancestor (anything not static).」 ↩

  15. 出处:「Chapter 6: Positioning」(text/07-ch01-1-chapter-overview.txt:43,搜「Switches between」)。原文:sticky「Switches between relative and fixed based on the user's scroll position.」 ↩

  16. 出处:「Chapter 6: Positioning」(text/07-ch01-1-chapter-overview.txt:48,搜「Becomes the anchor」)。原文示例 .parent { position: relative } + .child { position: absolute; top: 10px; right: 10px },输出解释:「The .child element will sit 10px from the top and 10px from the right of the .parent box.」 ↩

  17. 出处:「Chapter 6: Positioning」(text/07-ch01-1-chapter-overview.txt:125,搜「Vanishing」)。原文:「If you set position: absolute but the element is flying off to the corner of the screen, check if the parent has position: relative. Without it, the element anchors to the <body>.」 ↩

  18. 出处:「Chapter 6: Positioning」(text/07-ch01-1-chapter-overview.txt:71,搜「fixed-nav」)。原文输出解释:「The navigation bar will stick to the very top and left of the screen, regardless of scrolling.」 ↩

  19. 出处:「Chapter 6: Positioning」(text/07-ch01-1-chapter-overview.txt:131,搜「keyboard」)。原文:「Be careful with position: fixed on mobile devices; keyboard pop-ups can sometimes cause layout glitches with fixed elements.」 ↩ ↩2

  20. 出处:「Chapter 6: Positioning」(text/07-ch01-1-chapter-overview.txt:129,搜「Sticky Requirements」)。原文:「For position: sticky to work, at least one offset (like top: 0) must be set, and no parent element can have overflow: hidden.」 ↩ ↩2

  21. 出处:「Chapter 6: Positioning」(text/07-ch01-1-chapter-overview.txt:80,搜「z-index」)。原文:「Default Value: auto (behaves like 0)」。 ↩

  22. 出处:「Chapter 6: Positioning」(text/07-ch01-1-chapter-overview.txt:95,搜「other than static」)。原文:「z-index only works on elements that have a position value other than static.」 ↩ ↩2

  23. 出处:「Chapter 6: Positioning」(text/07-ch01-1-chapter-overview.txt:99,搜「Perfectly Centering」)。原文:「A classic trick to center an element inside a relative parent」,含注释「Pulls the element back to its own center」。 ↩ ↩2

  24. 出处:「Chapter 6: Positioning」(text/07-ch01-1-chapter-overview.txt:23,搜「Stacking Context」)。原文仅给出名词与一句「Some elements appear 'on top' of others」,无形成条件。 ↩

On this page