《CSS 新世界》的那些技巧1

7 阅读9分钟

整理自 20 个实用 CSS 特性示例,涵盖现代 CSS 布局、文字控制、样式继承等核心知识点。

1. shape-outside 圆形环绕

文字环绕不规则形状排列,float:let + shape-outside: circle(50%),常用于杂志风格图文混排

<div class="cs-round-x"></div>
<p>这是一段测试文字...</p>

<style>
    .cs-round-x {
        border-radius: 50%;
        height: 300px;
        width: 300px;
        background-color: rgb(0, 183, 255);
        /* 核心 */
        float: left;
        shape-outside: circle(50%);
    }
</style>

2. direction 简约布局流向

原理:改变文档流方向,实现左右镜像布局。

关键点

  • direction: rtl 让布局从右向左排列
  • 常用于聊天界面(自己的消息在右边)
  • 配合逻辑属性(margin-inline-end)效果更佳
<section data-self>
    <div class="cs-pic"></div>
    <article>
        <div class="cs-name">前端架构师</div>
        <p class="cs-text">有自身完整结构</p>
    </article>
</section>

<style>
    [data-self] {
        direction: rtl;  /* right-to-left 从右到左 */
    }
</style>

3. margin-inline-end 间隔

image.png

原理:逻辑属性,根据 direction 流向自动调整方向。

<div>
    <button>确定</button>
    <button>确定</button>
    <button>取消</button>
</div>

<style>
    button {
        margin-inline-end: 10px;  /* 根据 direction 流向 */
    }
    div {
        direction: rtl;
    }
</style>

关键点

  • margin-inline-end 跟随 direction 方向
  • ltr 时 = margin-right,rtl 时 = margin-left

4. border-inline-start 边框

image.png

原理:逻辑边框属性,适应不同书写方向。

<div class="flex">
    <div class="item">1</div>
    <div class="item">2</div>
</div>

<style>
    .flex {
        flex-direction: row-reverse;  /* 反向 */
    }
    .item {
        border-inline-start: 10px solid rgb(102, 0, 255);
    }
</style>

关键点

  • border-inline-start 是逻辑方向的开始边框
  • row-reverse 时,视觉最右边是逻辑开始
  • 配合 flex-direction 变化时自动适应

5. stretch 简约计算

image.png

image.png

原理:替代 calc,实现弹性宽度。

<button>弹性宽度</button>

<style>
    button {
        /* width: calc(100% - 30px); */
        width: stretch;  /* 更简洁 */
        margin-left: 15px;
        margin-right: 15px;
    }
</style>

关键点

  • width: stretch = 填充可用空间减去 margin
  • calc(100% - 30px) 更优雅
  • 移动端自适应布局常用

6. all: unset 清空全部样式

image.png

原理:一键移除元素所有默认样式。

<dialog open="true"></dialog>

<style>
    dialog {
        all: unset;
        /* 移除 html 自带的所有样式,重新自定义 */
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        padding: 20px;
        min-width: 200px;
        min-height: 200px;
        border-radius: 15px;
        border: 1px solid #b6b6b6;
    }
</style>

关键点

  • all: unset 清除所有继承和非继承属性
  • 常用于 dialog、button 等有默认样式的元素
  • 之后需要手动添加需要的样式

7. fit-content 不定宽弹窗居中

image.png

原理:根据内容自适应宽高 + margin auto 居中。

<dialog open="true">这是一个不固定大小的内容</dialog>

<style>
    dialog {
        all: unset;
        position: absolute;
        border: 1px solid #000;
        
        /* 解决方式:fit-content + margin */
        width: fit-content;
        height: fit-content;
        inset: 0;      /* 相当于 top/right/bottom/left: 0 */
        margin: auto;  /* 居中魔法 */
        
        animation: tinyUp .3s;
    }
</style>

关键点

  • fit-content 根据内容决定尺寸
  • inset: 0 + margin: auto 实现居中
  • 比 transform 方案更稳定(无抽搐)

8. fit-content 内容弹性居中

image.png

原理:文字少时居中,多时自动左对齐。

<div class="cw-box">
    <div class="cw-content">文字少自动居中</div>
</div>

<style>
    .cw-box {
        width: 300px;
        height: 150px;
        background: skyblue;
    }
    .cw-content {
        width: fit-content;
        margin: 0 auto;
    }
</style>

关键点

  • 文字少:width < 容器,margin auto 居中
  • 文字多:width = 容器,自然左对齐
  • 标题居中的优雅解决方案

9. inherit 继承样式

image.png

原理:强制继承父元素属性。

<ul>
    <li>这是一段跟随父元素的文字</li>
    <li><a href>a标签</a></li>
</ul>

<style>
    ul {
        font-size: 13px;
        color: chocolate;
    }
    li a {
        color: inherit;  /* 继承 ul 的 color */
    }
</style>

关键点

  • <a> 默认有蓝色,用 inherit 强制继承
  • border、padding、width 等也可继承
  • 统一颜色风格常用

10. initial 反继承样式

image.png

原理:恢复到浏览器默认值。

<ul>
    <li>林俊杰</li>
    <li>周杰伦</li>
    <li>周星驰</li>
    <li>乌鸦哥-张耀扬,字体大小不同</li>  <!-- 字体大小不同 -->
</ul>

<style>
    ul { font-size: 10px }
    li:last-child { font-size: initial }  /* 浏览器默认,约 16px */
</style>

关键点

  • initial = 属性的初始值(非继承值)
  • font-size: initial ≈ 16px
  • 用于打破继承链

11. inset 设置四个方向

image.png

原理:top/right/bottom/left 的简写。

<dialog open="true">
    <p>这是一个弹窗</p>
</dialog>

<style>
    dialog {
        all: unset;
        position: absolute;
        padding: 15px;
        width: fit-content;
        height: fit-content;
        /* 类似 padding:1 ~ 4 个参数 */
        inset: 30px 30px;   /* 上下30px,左右30px */
        border: 1px solid #000;
    }
</style>

关键点

  • inset: 30px = 四边都是 30px
  • inset: 30px 20px = 上下30,左右20
  • inset: 10px 20px 30px 40px = 上右下左

12. revert 恢复指定样式

原理:恢复到 UA(浏览器)默认样式或继承值。

image.png
<ul>
    <li>假设全局有li-style:none</li>
    <li>假设全局有li-style:none</li>
</ul>

<style>
    /* 假设全局有 list-style: none */
    li { list-style: none }
    
    /* 还原 li 样式到浏览器默认 */
    li { list-style: revert }
</style>

关键点

  • revert 恢复到 UA 样式表或继承值
  • 与 initial 不同:revert 考虑继承层叠
  • 撤销框架/重置样式的影响

13. writing-mode 文字方向

image.png

原理:控制文字书写方向。

<div class="cs-text">你好世界!</div>

<style>
    .cs-text {
        /* 默认:从左往右 */
        writing-mode: horizontal-tb;
        /* 竖向-从左向右 */
        writing-mode: sideways-lr;
        /* 竖向-从右向左 */
        writing-mode: sideways-rl;
        /* 竖排从上到下,列从左到右 */
        writing-mode: vertical-lr;
        /* 竖排从上到下,列从右到左(古书) */
        writing-mode: vertical-rl;
    }
</style>

关键点

  • horizontal-tb:默认水平
  • vertical-rl:竖排,古书风格
  • 配合 border-inline-* 等逻辑属性

14. 断句 min-content、wbr、word-break

image.png image.png

原理:控制长文本/URL 等如何断行。

<!-- min-content:按最小可断点换行 -->
<div class="cs-order">682362832625-666-1259236</div>

<style>
    .cs-order {
        width: min-content;  /* 按最小内容宽度 */
    }
</style>

<!-- 手动断句点 -->
<p>http://127<wbr>.0.0.1:5500/<wbr>treacher-yongHengDele</p>

<!-- 或强制换行 -->
<style>
    p { word-break: break-all }
</style>

关键点

  • width: min-content 按可断点收缩
  • <wbr> 建议换行点(软换行)
  • &#x200B; 零宽空格,同样作用

15. 文本的深入控制

1、white-space 保留换行

image.png
<p class="cs-enter">你觉得 "不如用 flex"
    的感觉完全正确
</p>

<style>
    .cs-enter {
        white-space: pre-line;  /* 保留换行,合并空格 */
    }
</style>

2、work-break:keep-all 词组换行(移动设备场景)

image.png
<!-- 模拟移动端 -->
<table style="width: 350px;">
    <tr>
        <th>会议时间</th>
        <th>会议地点</th>
        <th>会议人员(3)</th>
        <th>会议内容</th>
    </tr>
    <tr>
        <td>2021年2月28日</td>
        <td>6号楼三楼复习会议室</td>
        <td class="keep-all">张三 李四 王二麻子</td>
        <td>讨论自负单元终端与换行 </td>
    </tr>
</table>

<style>
    table {        border-collapse: collapse    }
    th,td {        border: 1px solid #000    }

    th,
    td.keep-all {
        /* 名字自动换行 */
        word-break: keep-all;
    }
</style>

3、解决超长词组的溢出

image.png
<div class="cs-test-break">
    o23eiojiweotuio90uiweuwteuioteuiowetuio
</div>
<style>
    .cs-test-break {
        width: 200px;
        background-color: pink;
        word-break: break-all;
    }
</style>

4、CJK 文本断词控制

/* 尽量不断词 */
word-break: keep-all;
/* 但长单词允许溢出断行 */
word-wrap: break-word;  /* 同 overflow-wrap: break-word */

/* 中文标点也可断行 */
line-break: anywhere;
image.png

1、word-break:keep-all 区分词组,但不阻止溢出(比如连续破折号、数字、英文)
2、word-break:break-all 强换行,但不区分词组
3、如果两种效果都要怎么办,keep-all 搭配 overflow-wrap

<style>
    .cjk-test {
        width: 150px;
        padding: 10px;
        border: 1px solid deepskyblue;
    }

    .cjk-test-break {
        /* word-break: break-all; */
        /* 这两很搭配 */
        word-break: keep-all;
        word-wrap: break-word;
        /* overflow-wrap: break-word; */
    }

    /* 中文标点符号可换行 */
    .cjk-line-break {
        line-break: anywhere;
    }
</style>
<p class="cjk-test">这个“CJK文本” 被折断</p>
<p class="cjk-test cjk-test-break">这个“CJK文本” 完好
    11111111111111111
</p>
<p class="cjk-test cjk-test-break cjk-line-break">
    这个“CJK文本” 完好
    11111111111111111
    完好后面大量空白
</p>

5、两端对齐优化

.book-content {
    text-align: justify;
    text-justify: inter-word;  /* 词间均匀分配空白 */
    word-break: keep-all;      /* CJK 优化 */
}

关键点

  • white-space: pre-line:保留源码换行
  • word-break: keep-all + word-wrap: break-word 是黄金组合
  • text-justify 优化两端对齐效果

16. 文字渐变、图片定位简写

image.png
<h1>我是渐变色文字</h1>

<style>
    h1 {
        background: linear-gradient(45deg, pink, blue);
        background-clip: text;
        color: transparent;
    }
</style>
image.png
<!-- 避免多写一个img标签子绝父相定位 -->
<div class="example"></div>
<style>
    .example {
        width: 300px;
        height: 200px;
        border: 1px solid #000;
        
       /**caclc写法**/
background: url(./1、shape-outside\ 圆形环绕.png) no-repeat calc(100% - 20px) calc(100% - 20px) / 100px 50px; 

        /* 方向写法 */
background: red url(./1、shape-outside\ 圆形环绕.png) no-repeat right 20px bottom 20px / 100px 50px;
    }
</style>
}
  • background-clip: text + color: transparent 实现渐变字
  • 背景定位:right 20px bottom 20px = 距右边 20px,距底边 20px
  • 简写:position / size 用斜杠分隔

17. column 与 flex 简写

image.png

column 多列布局(替代 flex 套盒)

<ul>
    <li>城市1</li><li>城市2</li>...<li>城市10</li>
</ul>

<style>
    ul {
        column-count: 2;    /* 分两列 */
        column-gap: 10px;   /* 列间距 */
    }
</style>
.span-all {
    column-span: all;  /* 横跨所有列 */
}

column-span 跨列
image.png

顶部一条,中间多个内容,底部一条
不需要 table、grid、flex,
使用 column 就可以完成布局

<div class="container">

     <header class="span-all">店铺订单信息</header>
     <data>订单信息</data>
     <data>商品信息</data>
     <data>仓库信息</data>
     <data>操作信息</data>
     <footer class="span-all">底部信息</footer>
     
</div>

<style>
    .container {
        column-count: 4;
        column-gap: 1%;
        background-color: skyblue;
    }

    .span-all {
        column-span: all;
        background: saddlebrown;
    }

    data {
        display: block;
        background-color: red;
    }

</style>

flex-flow

flex-flow:row wrap 等于 flex-direction:row 加上 flex-wrap:wrap

ul {
    display: flex;
    /* flex-direction: row; */
    /* flex-wrap: wrap; */
    flex-flow: row wrap;  /* 两者合并 */
}

flex:auto | none

/* flex: auto = flex: 1 1 auto */
/* 充分利用剩余空间,可收缩可扩展
*/
button:first-child {
    flex: auto;
}

/* flex: none = flex: 0 0 auto */
/* 固定尺寸,不参与弹性 */
button {
    flex: none;
}

Tab 导航自适应

nav span {
    flex: auto;  /* 等分剩余空间 */
}

场景:tab文字是不固定,根据内容进行自动划分等份 image.png

<!-- 优雅状tab,自适应宽度 -->
<nav class="flex">
    <span>首页</span>
    <span>排行榜</span>
    <span>我的订单</span>
    <span>个人中心</span>
</nav>
<style>
    nav {
        width: 500px;
        display: flex;
        background-color: yellow;
    }

    nav span {
        flex: auto;        /* 等于flex:1 1 0% */
        text-align: center;
        border: 1px solid #000;
    }
</style>
  • column-count 实现简单多列,无需嵌套
  • column-span: all 标题跨列
  • flex: auto 自适应,flex: none 固定
  • flex-flow = direction + wrap

18. flex-basis 优雅响应式

自动划分等比例:
image.png
宽度不足,自动弹性适配:
image.png
image.png
image.png

原理:基于最小宽度 + 自动扩展的响应式布局。

<div class="flex">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
</div>

<style>
    .flex {
        width: 400px;
        resize: both;
        overflow: auto;
        display: flex;
        flex-flow: wrap;
    }
    .item {
        /* 核心:最小是 100px,有空间就拉伸 */
        flex-basis: 100px;  /* 基础宽度 */
        flex-grow: 1;       /* 有剩余就增长 */
    }
</style>

关键点

  • flex-basis:理想/最小宽度
  • flex-grow: 1:空间够就平分
  • 容器缩小到一定程度自动换行
  • 响应式卡片布局的纯 CSS 方案

19. flex 中的 overflow 无效问题

image.png

原理:Flex 子项有"最小内容宽度保护"。

image.png
<!-- 单行省略失效 -->
<div class="container">
    <div class="item">宽度不确定</div>
    <div class="item">
        <p class="ellipsis">纯棉透气短袖 T 恤 夏季宽松百搭</p>
    </div>
</div>

<style>
    .container {
        width: 350px;
        display: flex;
    }
    .ellipsis {
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
    }
</style>

问题:上面 .ellipsis 不会出现省略号,因为 flex item 最小宽度保护。

解决方案一:min-width: 0

.min-width-0 {
    min-width: 0;  /* 打破最小宽度保护 */
}

解决方案二:overflow 非 visible

/* overflow 非 visible 时,min-width 自动重置为 0 */
.item.ellipsis {
    overflow: hidden;  /* 这行让 ellipsis 生效 */
}

关键点

  • Flex item 默认 min-width: auto,保护内容不被压缩
  • min-width: 0overflow: hidden 打破保护
  • 单行省略/截断必须先打破保护

附录

参考资源

  • 《CSS新世界》- 张鑫旭