CSS 逻辑属性是现代布局的重要特性。传统的 top/right/bottom/left 是物理方向,而逻辑属性使用 block/inline 和 start/end,能自动适应不同的书写方向(LTR/RTL)和书写模式(水平/垂直)。
为什么需要逻辑属性#
物理属性的问题#
/* 物理属性:固定方向 */.card { margin-left: 20px; padding-right: 16px; border-bottom: 1px solid #e5e7eb;}当页面切换到 RTL(从右到左)语言时:
/* 需要单独覆盖 */[dir='rtl'] .card { margin-left: 0; margin-right: 20px; padding-right: 0; padding-left: 16px;}逻辑属性的解决方案#
/* 逻辑属性:自动适应方向 */.card { margin-inline-start: 20px; padding-inline-end: 16px; border-block-end: 1px solid #e5e7eb;}/* RTL 时自动变为 margin-right、padding-left */基本概念#
Block 与 Inline#
-
Block(块方向):文本块的堆叠方向
- 水平书写:垂直方向(上下)
- 垂直���写:水平方向(左右)
-
Inline(行内方向):文本的流动方向
- LTR:从左到右
- RTL:从右到左
Start 与 End#
- Start:内容开始的方向
- End:内容结束的方向
| 物理属性 | LTR 水平 | RTL 水平 | 垂直 |
|---|---|---|---|
| inline-start | left | right | top |
| inline-end | right | left | bottom |
| block-start | top | top | right/left |
| block-end | bottom | bottom | left/right |
尺寸属性#
inline-size / block-size#
替代 width 和 height:
.box { /* 物理属性 */ width: 200px; height: 100px;
/* 逻辑属性 */ inline-size: 200px; block-size: 100px;}min/max 尺寸#
.container { /* 物理 */ max-width: 1200px; min-height: 100vh;
/* 逻辑 */ max-inline-size: 1200px; min-block-size: 100vh;}margin 逻辑属性#
单边属性#
.element { /* 物理 → 逻辑 */ margin-top: 20px; /* → */ margin-block-start: 20px; margin-bottom: 20px; /* → */ margin-block-end: 20px; margin-left: 20px; /* → */ margin-inline-start: 20px; margin-right: 20px; /* → */ margin-inline-end: 20px;}简写属性#
.element { /* 块方向:上下 */ margin-block: 20px; /* 上下相同 */ margin-block: 10px 20px; /* 上 下 */
/* 行内方向:左右 */ margin-inline: 20px; /* 左右相同 */ margin-inline: 10px 20px; /* start end */}
/* 水平���中的新写法 */.center { margin-inline: auto;}padding 逻辑属性#
.element { /* 单边 */ padding-block-start: 16px; padding-block-end: 16px; padding-inline-start: 24px; padding-inline-end: 24px;
/* 简写 */ padding-block: 16px; padding-inline: 24px;}border 逻辑属性#
单边属性#
.element { border-block-start: 1px solid #e5e7eb; border-block-end: 2px solid #3b82f6; border-inline-start: 4px solid #10b981; border-inline-end: 1px solid #e5e7eb;}分离属性#
.element { border-block-start-width: 2px; border-block-start-style: solid; border-block-start-color: #3b82f6;
/* 简写 */ border-block: 1px solid #e5e7eb; border-inline: 2px dashed #3b82f6;}border-radius 逻辑属性#
.element { /* 物理 → 逻辑 */ border-top-left-radius: 8px; /* → */ border-start-start-radius: 8px; border-top-right-radius: 8px; /* → */ border-start-end-radius: 8px; border-bottom-right-radius: 8px; /* → */ border-end-end-radius: 8px; border-bottom-left-radius: 8px; /* → */ border-end-start-radius: 8px;}命名规则:border-{block}-{inline}-radius
inset 定位属性#
inset 简写#
.positioned { position: absolute;
/* 物理属性 */ top: 0; right: 0; bottom: 0; left: 0;
/* inset 简写 */ inset: 0;
/* 分开设置 */ inset: 10px 20px; /* 上下 左右 */ inset: 10px 20px 30px; /* 上 左右 下 */ inset: 10px 20px 30px 40px; /* 上 右 下 左 */}逻辑定位#
.positioned { position: absolute;
/* 物理 → 逻辑 */ top: 0; /* → */ inset-block-start: 0; bottom: 0; /* → */ inset-block-end: 0; left: 0; /* → */ inset-inline-start: 0; right: 0; /* → */ inset-inline-end: 0;
/* 简写 */ inset-block: 0; inset-inline: 0;}text-align 逻辑值#
.text { /* 物理值 */ text-align: left; text-align: right;
/* 逻辑值 */ text-align: start; text-align: end;}float 和 clear 逻辑值#
.float-element { /* 物理值 */ float: left; float: right;
/* 逻辑值 */ float: inline-start; float: inline-end;}
.clear-element { clear: inline-start; clear: inline-end;}resize 逻辑值#
.resizable { /* 物理值 */ resize: horizontal; resize: vertical;
/* 逻辑值 */ resize: inline; resize: block;}实战案例#
RTL 友好的导航#
.nav { display: flex; gap: 24px; padding-inline: 24px;}
.nav-item { padding-block: 12px; padding-inline: 16px; border-inline-start: 3px solid transparent;}
.nav-item.active { border-inline-start-color: #3b82f6; background: rgba(59, 130, 246, 0.1);}国际化卡片#
.card { padding: 24px; border-radius: 12px; border: 1px solid #e5e7eb;}
.card-header { display: flex; align-items: center; gap: 12px; padding-block-end: 16px; margin-block-end: 16px; border-block-end: 1px solid #e5e7eb;}
.card-icon { margin-inline-end: 8px;}
.card-action { margin-inline-start: auto;}列表项样式#
.list-item { display: flex; align-items: center; padding-block: 12px; padding-inline: 16px; border-block-end: 1px solid #f3f4f6;}
.list-item-icon { margin-inline-end: 12px;}
.list-item-content { flex: 1; min-inline-size: 0;}
.list-item-action { margin-inline-start: 12px;}表单布局#
.form-group { margin-block-end: 20px;}
.form-label { display: block; margin-block-end: 8px; font-weight: 500;}
.form-input { inline-size: 100%; padding-block: 12px; padding-inline: 16px; border: 1px solid #d1d5db; border-radius: 8px;}
.form-hint { margin-block-start: 4px; font-size: 0.875rem; color: #6b7280;}模态框#
.modal { position: fixed; inset: 0; display: flex; align-items: center; justify-content: center;}
.modal-content { max-inline-size: 500px; max-block-size: 80vh; padding: 24px; border-radius: 16px; background: white;}
.modal-header { display: flex; align-items: center; padding-block-end: 16px; border-block-end: 1px solid #e5e7eb;}
.modal-title { margin: 0;}
.modal-close { margin-inline-start: auto;}
.modal-body { padding-block: 20px; overflow-y: auto;}
.modal-footer { display: flex; gap: 12px; justify-content: flex-end; padding-block-start: 16px; border-block-start: 1px solid #e5e7eb;}侧边栏布局#
.layout { display: flex;}
.sidebar { inline-size: 280px; border-inline-end: 1px solid #e5e7eb; padding: 24px;}
.main { flex: 1; padding: 24px; min-inline-size: 0;}
/* RTL 时侧边栏自动移到右边 */引用块#
.blockquote { margin-block: 24px; margin-inline: 0; padding-block: 16px; padding-inline-start: 24px; border-inline-start: 4px solid #3b82f6; background: #f8fafc; border-radius: 0 8px 8px 0;}
[dir='rtl'] .blockquote { /* 圆角也需要调整 */ border-radius: 8px 0 0 8px;}属性映射表#
| 物理属性 | 逻辑属性 |
|---|---|
| width | inline-size |
| height | block-size |
| min-width | min-inline-size |
| max-height | max-block-size |
| margin-top | margin-block-start |
| margin-bottom | margin-block-end |
| margin-left | margin-inline-start |
| margin-right | margin-inline-end |
| padding-top | padding-block-start |
| padding-left | padding-inline-start |
| border-top | border-block-start |
| border-left | border-inline-start |
| top | inset-block-start |
| left | inset-inline-start |
| text-align: left | text-align: start |
| text-align: right | text-align: end |
渐进增强#
/* 回退方案 */.element { margin-left: 20px; margin-inline-start: 20px;}
/* 或使用 @supports */@supports (margin-inline-start: 0) { .element { margin-left: unset; margin-inline-start: 20px; }}浏览器兼容性#
逻辑属性在现代浏览器中支持良好:
| 浏览器 | 支持版本 |
|---|---|
| Chrome | 87+ |
| Firefox | 66+ |
| Safari | 14.1+ |
| Edge | 87+ |
常见问题#
🤔 什么时候用逻辑属性?
- 需要支持 RTL 语言(阿拉伯语、希伯来语等)
- 需要支持垂直书写(中文、日文竖排)
- 构建国际化组件库
🤔 现有项目要全部迁移吗?
不必全部迁移。优���处理与文本方向相关的属性(margin、padding、border),width/height 可以保留物理属性。
🤔 逻辑属性和 Flexbox/Grid 配合?
Flexbox 和 Grid 本身就是逻辑性的,justify-* 和 align-* 会自动适应方向。
CSS 逻辑属性是现代 CSS 的重要组成部分,特别是在构建国际化应用时。使用逻辑属性,你的布局可以自动适应不同的书写方向,无需编写额外的 RTL 样式。下一篇我们将学习 CSS 函数。