普通视图

发现新文章,点击刷新页面。
昨天以前首页

极简版前端版本检测方案

2026年2月24日 10:39

前端版本检测实现方案

功能概述

实现前端发版后的版本检测功能,通过自动生成版本文件并定期检查,确保用户始终使用最新版本。

实现步骤

1. 配置 Vite 插件自动生成 version.json

vite.config.ts 中添加自定义插件,打包时自动生成版本文件:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { writeFileSync } from 'fs'
import { resolve } from 'path'

//  封装版本生成函数
const versionPlugin = () => ({
  name: 'version-plugin',
  writeBundle() {
    const versionData = { version: Date.now() }
    writeFileSync(
      resolve(__dirname, 'dist/version.json'),
      JSON.stringify(versionData)
    )
  }
})

export default defineConfig({
  plugins: [
             vue(), 
     //  使用插件
             versionPlugin()       
  ],
})

2. 版本检测工具函数

创建 src/utils/versionCheck.ts

// 检查版本是否一致
const checkVersion = async () => {
  try {
    const res = await fetch('/version.json?timestamp=' + Date.now())
    const { version: remoteVersion } = await res.json()
    const localVersion = localStorage.getItem('app_version')
    
    if (localVersion && localVersion !== String(remoteVersion)) {
      localStorage.setItem('app_version', String(remoteVersion))
      alert('发现新版本,请刷新页面')
      location.reload()
    }
    
    localStorage.setItem('app_version', String(remoteVersion))
  } catch (e) {
    console.error('版本检测失败', e)
  }
}

export const initVersionCheck = () => {
  checkVersion()
  setInterval(checkVersion, 5 * 60 * 1000)
}

3. 在应用入口初始化版本检测

src/main.ts 中引入:

import { createApp } from 'vue'
import App from './App.vue'
/**   引入工具函数   **/
import { initVersionCheck } from './utils/versionCheck'

const app = createApp(App)
app.mount('#app')
/** 初始化版本检测 **/
initVersionCheck()

工作原理

  1. 打包阶段:Vite 插件在 writeBundle 钩子中生成 version.json,包含当前时间戳作为版本号
  2. 运行阶段:应用启动时和每隔 5 分钟检查一次版本
  3. 版本对比:对比本地存储的版本号和远程版本号,不一致时提示刷新

优势

  • 自动化生成版本文件,无需手动维护
  • 定时检测,及时提醒用户更新
  • 无需额外样式和复杂逻辑

🔥真正高级的前端,早就用这 10 个 CSS 特性干掉 80% 冗余代码

2026年2月19日 19:44

🔥 一键夜间模式,告别手动配置暗主题

你是否还在单独写变量控制夜间模式?
使用 prefers-color-scheme 媒体查询结合 filter 属性,
实现一键切换夜间模式,无需单独配置暗黑色值。

/* 夜间模式查询(可选), */ 

@media (prefers-color-scheme: dark) { 
       body { 
       /* 一行代码搞定 */
          filter: invert(1) hue-rotate(180deg); 
          background-color: #000
       } 
       
       /* 图片还原真实颜色(避免被整体反色影响) */ 
       img { filter: invert(1) hue-rotate(180deg); } 
  }

2. 🔥 一键适配!纯 CSS 搞定 REM 自适应

clamp()+calc()实现 16-22px 根字体流体排版

<style>
    html {
        font-size: clamp(16px, calc(16px + 2 * (100vw - 375px) / 39), 22px);
    }
</style>

<p>39是(768-375)/6 ≈ 39的简化, 所以公式等价 , 只是写法不同 </p>

3. currentColor 一行实现智能换肤

8..png

借 color: inherit 继承主题色,currentColor关联 color, [data-theme] 属性区分不同主题

<section class="module">
    <h4>模块标题</h4>
    <content>
        <ul><li>文字描述</li><li>文字描述</li><li>文字描述</li></ul> 
        <button>了解更多</button>
    </content>
</section>

<section class="module" data-theme="a">
    <h4>模块标题</h4>
    <content>
        <ul><li>文字描述</li><li>文字描述</li><li>文字描述</li></ul> 
        <button>了解更多</button>
    </content>
</section>

<section class="module" data-theme="b">
    <h4>模块标题</h4>
    <content>
        <ul><li>文字描述</li><li>文字描述</li><li>文字描述</li></ul> 
        <button>了解更多</button>
    </content>
</section>

<style>
    .module {        border: 1px solid    }
    .module content {        display: block;        padding: 10px    }
    .module ul {        color: #333    }
    
    .module h4 {
        margin: 0;
        padding: 5px 10px;
        -webkit-text-fill-color: #fff;
        background-color: currentColor;
    }

    .module button {
        border: 0;
        width: 100px;
        height: 32px;
        -webkit-text-fill-color: #fff;
        color: inherit;
        background-color: currentColor;
        margin-top: 10px;
    }

    /* 主题颜色设置 */
    [data-theme="a"] {        color: skyblue    }
    [data-theme="b"] {        color: pink    }
</style>

4. 移动端安全边距

使用 env(safe-area-inset-*) 函数,为刘海屏、底部安全区等设备提供适配。

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!--  设置meta的content,确保 safe-area-inset-* 出现准确边距  -->
    <meta name="viewport" content="viewport-fit=cover">
    
    <style>
        /* 移动端的 4个安全内边距值,设置兜底尺寸值 */
        body {
            padding-top: env(safe-area-inset-top, 20px);
            padding-bottom: env(safe-area-inset-bottom, 0.5vh);
            padding-left: env(safe-area-inset-left, 1.4rem);
            padding-right: env(safe-area-inset-right, 1em);
        }
    </style>

</head>

5. vh 经典底部栏动态居底部

使用 Flexbox 布局,实现底部栏始终固定在页面底部,无论内容多少

<div class="container">
    <section>
        <button>少贴视窗底,多随内容底</button>
        <ul class="content"> 。。。。。。。。。。 </ul>
    </section>
    <footer>自动跟随</footer>
</div>

<style>
    * {margin: 0;padding: 0;box-sizing: border-box}

    .container {
        /* 核心代码 */
        display: flex;
        flex-direction: column;
        min-height: 100vh;
    }

    footer {
        height: 4rem;
        background-color: #333;
        /* 核心 */
        margin-top: auto;
    }
</style>

<script>
// 模拟内容极少不足、内容超过 100vh  两者情况
    const content = document.querySelector('.content')
    document.querySelector('button').onclick = function () {
        for (let i = 0; i <= 30; i++) {
            content.innerHTML += `<p>假如中间有很多内容</p>`
        }
    }
</script>

6. 任意字符强调效果

这种排版很神奇, text-emphasis-style 添加自定义强调标记,避免手动 flex 撸效果

9.shu.png

<p>
    宝贝,
    <span class="emphasis">爱你</span><span class="emphasis">比心</span></p>

<style>
    .emphasis {
        /*        强调装饰符         */
        -webkit-text-emphasis-style: '❤';
        text-emphasis-style: '❤';
        /*         控制文字方向         */
        writing-mode: vertical-rl;
        text-emphasis-position: over right;
    }
</style>

7. 增强版滚动

scroll-behavior: smooth 让上下滚动更顺滑

<!-- HTML: -->
<div class="box">
    <div class="list"><input id="one" readonly>1</div>
    <div class="list"><input id="two" readonly>2</div>
    <div class="list"><input id="three" readonly>3</div>
    <div class="list"><input id="four" readonly>4</div>
</div>
<div class="link">
    <label class="click" for="one">1</label>
    <label class="click" for="two">2</label>
    <label class="click" for="three">3</label>
    <label class="click" for="four">4</label>
</div>

<style>
    /* 核心CSS: */
    .box {
        width: 20em;
        height: 10em;
        /* 平滑滚动:scroll-behavior: smooth,.box 中的 scroll-behavior: smooth 是体验优化:
        让浏览器滚动到聚焦元素的过程是 “平滑过渡”,而非瞬间跳转,提升交互体验。 */
        scroll-behavior: smooth;
        overflow: hidden;
    }

    .list {
        height: 100%;
        background: #ff4c4c;
        text-align: center;
        position: relative;
    }

    .list>input {
        position: absolute;
        top: 0;
        height: 100%;
        width: 1px;
        border: 0;
        padding: 0;
        margin: 0;
        clip: rect(0 0 0 0);
    }
</style>

8. 阻止连带滚动

内部滚动牵动外部滚动是常见坑,overscroll-behavior : contain 可限定滚动域,防止穿透

<!-- 阻止连带滚动 -->
<zxx-scroll>
    你想了解 overscroll-behavior: contain 和 -ms-scroll-chaining: contain 这两个 CSS
    属性的作用,以及它们在实际开发中的价值,我会用通俗易懂的方式拆解这两个属性的核心功能、使用场景和差异。
    核心作用: 解决 “滚动穿透” 问题
    这两个属性的核心目标是阻止滚动行为的 “链式传递” ( 俗称 “滚动穿透” ) ,简单说:
    当你在一个可滚动的小容器 ( 如弹窗、侧边栏 ) 内滚动到顶部 / 底部时,继续滑动,页面的外层容器 ( 如整个网页 ) 不会跟着滚动
    没有这个属性时,小容器滚动到底部后,再滑动会触发整个页面的滚动,破坏交互体验 ( 比如弹窗内滑动导致背景页面滚动 ) 。
    逐属性拆解
    1. overscroll-behavior: contain ( 标准属性 )
    定位: W3C 标准 CSS 属性,现代浏览器 ( Chrome/Firefox/Safari/Edge ) 均支持
    核心值:
    contain: 限制滚动行为在当前元素内,不会传递给父元素
    auto ( 默认 ) : 允许滚动穿透
    none: 不仅阻止滚动穿透,还会禁用浏览器的默认滚动反馈 ( 如 iOS 的弹性回弹 ) 。
</zxx-scroll>
<!-- 连带滚动 -->
<p class="test">你想了解 overscroll-behavior: contain 和 -ms-scroll-chaining: contain 这两个 CSS
    属性的作用,以及它们在实际开发中的价值,我会用通俗易懂的方式拆解这两个属性的核心功能、使用场景和差异。
    核心作用: 解决 “滚动穿透” 问题
    这两个属性的核心目标是阻止滚动行为的 “链式传递” ( 俗称 “滚动穿透” ) ,简单说:
    当你在一个可滚动的小容器 ( 如弹窗、侧边栏 ) 内滚动到顶部 / 底部时,继续滑动,页面的外层容器 ( 如整个网页 ) 不会跟着滚动
    没有这个属性时,小容器滚动到底部后,再滑动会触发整个页面的滚动,破坏交互体验 ( 比如弹窗内滑动导致背景页面滚动 ) 。
</p>
<p>


</p>

<style>
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }

    zxx-scroll {
        display: block;
        width: 180px;
        height: 100vh;
        padding: .5em 1em;

        border: solid deepskyblue;
        overflow: auto;

        /* 核心css */

        overscroll-behavior: contain;
        -ms-scroll-chaining: contain;
    }

    .test {
        width: 180px;
        height: 300px;
        overflow: auto;
    }
</style>

9. 丝滑滚动急停

使用 scroll-snap-type 和 scroll-snap-align 属性,实现滚动时的自动对齐效果。

<!-- 
 scroll-snap-align: center:定义图片在滚动容器中的吸附对齐点(center = 居中,还可设 start/end)
 配合容器的scroll-snap-type,实现滑动后图片自动居中对齐。
 -->
<div class="scroll-x">
    <img src="./图片/风景.webp">
    <img src="./图片/image.png">
    <img src="./图片/image copy.png">
    <img src="./图片/image copy 2.png"> 
</div>
 

<style>
    .scroll-x {
    max-width: 414px; height: 420px;
    margin: auto;
    scroll-snap-type: x mandatory;
    white-space: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
}
.scroll-x img {
    width: 300px; height: 400px;
    scroll-snap-align: center;/* 图片居中吸附 */
}
</style>
  • scroll-snap-type:设置滚动容器的吸附类型
  • scroll-snap-align:设置子元素的吸附对齐点
  • 强制吸附:实现滚动后的精确定位

10. 滚动锁定急停

使用 scroll-snap-type 的不同值,实现不同的滚动吸附效果。

<section>
    <h4>垂直滚动 - mandatory</h4>
    <div class="scroll scroll-y mandatory">
        <img src="wallpaper-1.jpg">
        <img src="nature-1.jpg">
        <img src="wallpaper-3.jpg">
        <img src="nature-2.jpg">
    </div>
</section>
<section>
    <h4>垂直滚动 - proximity</h4>
    <div class="scroll scroll-y proximity">
        <img src="wallpaper-1.jpg">
        <img src="nature-1.jpg">
        <img src="wallpaper-3.jpg">
        <img src="nature-2.jpg">
    </div>
</section>
 
<style>
.scroll {    overflow: auto    }
.scroll-y {    max-width: 300px;    height: 150px    }
.mandatory {   scroll-snap-type: y mandatory     }
.proximity {    scroll-snap-type: y proximity     }
.scroll img {    scroll-snap-align: center       }
</style>
  • scroll-snap-type: mandatory:强制吸附到最近的对齐点
  • scroll-snap-type: proximity:仅在接近对齐点时吸附
  • 垂直滚动:实现类似轮播图的效果

参考资源

  • 《CSS新世界》- 张鑫旭

CSS Grid 案例

2026年2月19日 02:55

CSS Grid 案例详解

1、min-content、max-content、auto 空间计算

单列 auto 布局:内容宽度决定列宽,剩余空间自动分配

auto-1.png

双列 auto 布局:两列宽度根据内容自动调整

auto-2.png

三列 auto 布局:多列布局时内容宽度的分配方式

auto-3.png

四列 auto 布局:列数增加时的空间分配逻辑

auto-4.png

max-content:列宽等于内容最大宽度,不换行

max-content.png

min-content:列宽等于内容最小宽度,尽可能换行

min-content.png

min-content 最小宽度,max-content 完整内容宽度, auto 自动分配剩余空间 列宽等于内容最小宽度,尽可能换行

<body>
    <div class="grid">
        <div class="item">内容1</div>
        <div class="item">内容2</div>
        <div class="item">内容3</div>
        <div class="item">内容4</div>
    </div>
</body>
<style>
    .grid {
        display: grid;
        /*  左(自动分配剩余)
            右(内容最大或最小) */
        grid-template-columns: auto max-content;
        
        /* 单列,两列,三列,四列 */
        grid-template-columns: auto;
        grid-template-columns: auto auto;
        grid-template-columns: auto auto auto;
        grid-template-columns: auto auto auto auto;
        grid-template-columns: auto min-content;

        /* 加间距,方便看列的边界 */
        grid-column-gap: 5px;
        grid-row-gap: 5px;
        background-color: #c1c1c1;
        padding: 5px;
    }

    .item {
        /* 加背景,直观区分列 */
        border: 1px solid #000;
        padding: 2px;
    }
</style>

<!-- 
★ auto 特性:优先适应父容器宽度,剩余空间自动分配,内容超出时会换行
★ max-content:列宽=内容不换行时的最大宽度(内容不会折行)
★ min-content:列宽=内容能折行时的最小宽度(内容尽可能折行收缩)
★ 多列 auto:列数=auto的个数,列宽优先适配自身内容,剩余空间平分 
-->

2、space-between

2、stretch 内容填充.png

两个内容自动撑开, 左右排列
<div class="container">
    <div class="item">用户123</div>
    <div class="item">很多内容</div>

    <div class="item">内容</div>
    <div class="item">很多内容很多内容</div>
</div>

<style>
    .container {
        width: 300px;
        display: grid;
        grid-template-columns: auto auto;
        /** 两个内容自动撑开, 左右排列 **/
        justify-content: space-between;
        background-color: blueviolet;
    }

    .item {
        background-color: skyblue;
    }
</style>

3、auto-fit、minmax 填满剩余空间

单列布局,当容器宽度不足时自动调整为单列

3、一列.png

两列布局:容器宽度足够时自动扩展为多列

3、两列.png

三列布局:自适应容器宽度的多列排列

3、三列.png

四列布局:充分利用可用空间的自适应布局

3、铺满四列.png

<main>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
</main>

<style>
    main {
        display: grid;
        grid-gap: 5px;
        /* 1、minmax 定义尺寸范围 */

        /* 2、
              auto-fill 在宽度足够的条件下预留了空白
              auto-fit 在宽度足够的条件下充分利用空间
              */
        grid-template-columns: repeat(auto-fit, minmax(600px, 1fr));
        border: 3px dashed;
    }

    div {
        background-color: deepskyblue;
        height: 100px;
    }
</style>

4、grid 命名格子

使用grid-template-areas,通过命名区域实现复杂的网格布局

4、grid 命名格子.png

代码

<div class="container">
    <div class="item putao">葡萄</div>
    <div class="item longxia">龙虾</div>
    <div class="item yangyu">养鱼</div>
    <div class="item xigua">西瓜</div>
</div>

<style>
    .container {
        height: 400px;
        display: grid;
        /* grid-template-columns: repeat(3, 1fr);
        grid-template-rows: repeat(4, 1fr);
        grid-template-areas:
            "葡萄 葡萄 葡萄"
            "龙虾 养鱼 养鱼"
            "龙虾 养鱼 养鱼"
            "西瓜 西瓜 西瓜"
        ; */
        /* 简写 */
        grid: "葡萄 葡萄 葡萄" 1fr "龙虾 养鱼 养鱼" 1fr "龙虾 养鱼 养鱼" 1fr "西瓜 西瓜 西瓜" 1fr / 1fr 1fr 1fr;
    }

    .putao {
        grid-area: 葡萄;
        background-color: greenyellow;
    }

    .longxia {
        grid-area: 龙虾;
        background-color: plum;
    }

    .yangyu {
        grid-area: 养鱼;
        background-color: slategray;
    }

    .xigua {
        grid-area: 西瓜;
        background-color: crimson;
    }

    .container .item {
        display: flex;
        align-items: center;
        justify-content: center;
    }
</style>

5、隐形网格

image.png 隐式网格: 超出显式网格范围的项目自动创建新行

代码

<div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5隐式网格</div>
</div>
<style>
    .container {
        display: grid;
        grid: 1fr 1fr/1fr 1fr;
        grid-auto-rows: 100px;
    }

    .item:nth-of-type(1) {
        background-color: rgb(239, 255, 170);
    }

    .item:nth-of-type(2) {
        background-color: rgb(182, 184, 255);
    }

    .item:nth-of-type(3) {
        background-color: rgb(255, 195, 253);
    }

    .item:nth-of-type(4) {
        background-color: rgb(210, 255, 179);
    }

    .item:nth-of-type(5) {
        background-color: rgb(185, 185, 185);
    }
</style>

6、隐式网格2

隐式网格的列布局: grid-auto-columns设置隐式列的宽度

image.png

<div class="container2">
    <div class="item-a">a</div>
    <div class="item-b">b</div>
</div>
<style>
    .container2 {
        display: grid;
        grid-template: 1fr 1fr/1fr 1fr;
        /* 额外列(第 3 列 +)宽度固定 60px; */
        grid-auto-columns: 60px;
        border: 1px solid #000;
    }

    .item-b {
        /* 让 item-b 占第 3 列(第 3-4 根列线之间) */
        grid-column: 3/4;
        background-color: aqua;
    }
</style>

7、grid-auto-flow 流向

默认row 流向: 左到右、从上到下排列

7、grid-auot-flow 流向.png

column流向: 上到下、从左到右排列

7、grid-auto-flow 流向2.png

<div class="container">
    <div class="item">格子1</div>
    <div class="item">格子2</div>
    <div class="item">格子3</div>
    <div class="item">格子4</div>
    <div class="item">格子5</div>
    <div class="item">格子6</div>
    <div class="item">格子7</div>
    <div class="item">格子8</div>
    <div class="item">格子9</div>
</div>
<style>
    .container{
        display: grid;
        line-height: 40px;
        background-color: skyblue;
        
        /* 默认流向是左往右,再下一行左往右,重复前面方式 */
        grid-template-columns: 1fr 1fr;
        grid-auto-flow: row;

        /* 换一个方向,上往下 */
        /* grid-template-rows: 1fr 1fr;
        grid-auto-flow: column; */
    }
    .item{
        outline: 1px dotted;
    }
</style>

8、grid-auto-flow 图片案例

第一个图片占据两行空间,其他图片自动排列

image.png
<div class="container">
    <div class="item"><img src="./图片/shu.webp"></div>
    <div class="item"><img src="./图片/1.webp"></div>
    <div class="item"><img src="./图片/2.webp"></div>
    <div class="item"><img src="./图片/3.webp"></div>
    <div class="item"><img src="./图片/4.webp"></div>
 
</div>
<style>
 .container {
    display: grid;
    background-color: skyblue;
 
    /* 1. 修复:去掉 grid-auto-flow: column,用默认 row 按行排列 */
    /* 2. 修复:用 minmax(0, 1fr) 防止单元格被图片撑大 */

    grid-template: 
        "a . ." minmax(0, 1fr)
        "a . ." minmax(0, 1fr)
        / minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
    grid-gap: 6px;
    
}

/* 第一个元素占网格区域 a(2行1列) */
.container .item:first-child {
    grid-area: a;
}

/* 修复:图片不溢出、不变形 */
.container img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover; /* 按比例裁剪,填满单元格 */
}
</style>

9、dense 填补

dense填补: 自动填补空缺位置,优化空间利用 image.png

<div class="container">
    <div class="item">各自1</div>
    <div class="item">各自2</div>
    <div class="item">各自3</div>
    <div class="item">各自4</div>
    <div class="item">各自5</div>
    <div class="item">各自6</div>
    <div class="item">各自7</div>
    <div class="item">各自8</div>
    <div class="item">各自9</div>
</div>

<style>
    .container {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        grid-auto-flow: dense;
    }

    .container .item {
        outline: 1px dotted;
    }

    /* 模拟空缺位置 */
    .container .item:first-child {
        grid-column-start: 2;
    }
</style>

10、grid 简写

<style>

    /*
       1、 none 表示设置所有子项属性值为初始化值
        grid:none

       2、template 
        单独:
        grid-template-rows:100px 300px;
        grid-template-columns:3fr 1fr;

        简写:
        grid:100px 300px / 3fr 1fr;
        
        4、auto-flow 
        单独 
        grid-template-rows: 100px 300px;
        grid-auto-flow: column;
        grid-auto-columns: 200px; 

         合并
        grid: 100px 300px / auto-flow 200px;

      3、template-areas
      完整:
       grid-template-columns: repeat(3, 1fr);
       grid-template-rows: repeat(4, 1fr);
       grid-template-areas:
            "葡萄 葡萄 葡萄"
            "龙虾 养鱼 养鱼"
            "龙虾 养鱼 养鱼"
            "西瓜 西瓜 西瓜"; 

        简写:
        grid: 
         "葡萄 葡萄 葡萄" 1fr
         "龙虾 养鱼 养鱼" 1fr 
         "龙虾 养鱼 养鱼" 1fr 
         "西瓜 西瓜 西瓜" 1fr 
         / 1fr 1fr 1fr;
    */
</style>

11、place-items 完整写法

image.png

place-items:项目在单元格内的居中对齐方式

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

<style>
    .container {
        display: grid;
        grid: 1fr 1fr/1fr 1fr;
        height: 300px;
        background-color: skyblue;

        /* 单个,类似flex  
        
        justify-content: center;
        align-items: center;
        
        */

        /* 合并 */
        place-items: center right;
    }
    .item{
        outline: 1px solid;
    }
 
</style>

12、layout栏布局

经典的页面布局: 包含头部、侧边栏、主内容和底部四个区域 image.png

<style>
    .grid-container {
      width: 500px;
      height: 400px;
      margin: 20px auto;
      display: grid;
      /* 精简核心:去掉重复线名,换行简化,保留关键命名 */
      grid-template:
        [r1] "header header header" 1fr [r2]
        [r2] "sidebar main main"    2fr [r3]
        [r3] "sidebar footer footer" 1fr [r4]
        / [c1] 150px [c2] 1fr [c3] 1fr [c4];   
      gap: 8px;
    }

    /* 子项定位(极简写法) */
    .grid-container>div{display: flex;justify-content: center;align-items: center;}
    .header { grid-area: header; background: #409eff; color: #fff;  }
    .sidebar { grid-row: r2/r4; grid-column: c1/c2; background: #67c23a; color: #fff;  }
    .main { grid-area: main; background: #e6a23c; color: #fff;  }
    .footer { grid-row: r3/r4; grid-column: c2/c4; background: #f56c6c; color: #fff;  }
  </style>

<body>
  <div class="grid-container">
    <div class="header">头部</div>
    <div class="sidebar">侧边栏</div>
    <div class="main">主内容</div>
    <div class="footer">底部</div>
  </div>
</body>
<!-- Grid 布局示例,含命名网格线 + 区域命名,3 行 3 列分头部 / 侧边 / 主内容 / 底部 -->

13、grid-area 线条版

image.png grid重叠: 图片和标题在同一网格单元格内叠加

<figure>
    <img src="./图片/13.png">
    <figcaption>自然风景</figcaption>
</figure>

<style>
    figure {

        display: grid;
    }

    img {
        width: 100%;
    }

    figure>img,
    figure>figcaption {
        grid-area: 1 / 1 / 2 / 2;
    }

    figure>figcaption {
        align-self: end;
        text-align: center;
        background: #0009;
        color: #fff;
        line-height: 2;
    }
</style>

附录

参考资源

  • 《CSS新世界》- 张鑫旭

html与CSS伪类技巧

2026年2月16日 05:01

CSS选择器文档

本文档基于15个HTML示例文件介绍了CSS的各种技巧实践,旨在记录开发时候CSS的场景应用。

  1. 影子DOM样式隔离
  2. :not()伪类简化代码
  3. :is()伪类简化选择器
  4. :active伪类实现埋点统计
  5. :focus-within实现搜索交互
  6. <small>标签的使用
  7. <details><summary>实现折叠面板
  8. :placeholder-shown实现输入提示
  9. :default伪类标记默认选项
  10. <label>交互与计数器
  11. 表单校验与反馈
  12. <fieldset><legend>组织表单
  13. :empty伪类处理空内容
  14. :only-child伪类条件显示
  15. :not()伪类初始化样式

1. 影子DOM样式隔离

使用attachShadow()方法创建影子DOM,实现组件的样式隔离,避免样式冲突。

<body>
   <p>外部文字,颜色为黑色</p>
   <div id="hostElement"></div>
</body>

<script>
   const hostElement = document.querySelector('#hostElement')
   const shadow = hostElement.attachShadow({ mode: 'open' })
   shadow.innerHTML = `<p>可以实现组件的样式隔离,颜色为红色</p>`
   shadow.innerHTML += `<style>p{color:red}</style>`
</script>
  • 组件开发,特别是自定义元素
  • 第三方插件集成
  • 样式封装和隔离

2. :not()伪类简化代码

使用:not()伪类排除特定元素,简化CSS选择器,避免重复样式定义。

<ul>
      <li>列表1</li>
      <li>列表2</li>
      <li>列表3</li>
</ul>

<style>
    /*列表最后一项排除*/
    li:not(:last-child){
        border-bottom: 1px solid black;
        padding-bottom:8px;
        margin-bottom: 8px;
    }
</style>
  • 列表项样式处理(如最后一项无边框)
  • 导航菜单样式
  • 表单元素样式排除

3. :is()伪类简化选择器

使用:is()伪类将多个选择器组合成一个,简化CSS代码结构,提高可读性。

<body>
    <header> <a href='#'> 头部字体 </a>  </header>
    <main> <a href='#'> 主题字体 </a>  </main>
    <footer> <a href='#'> 底部字体 </a> </footer>
</body>

<style>
   /* 常见嵌套写法,需经过编译
    header,main,footer{  
       a{   color: red;   } 
    } 
   编译过后 
   header a,main a,footer a{  color: red  } 
   */

    /* :is() 是原生 CSS 语法,无需编译,浏览器直接识别 */
    :is(header, main, footer) a  {   color: red   }
</style>
  • 多个容器内相同元素的样式统一
  • 复杂选择器的简化

4. :active伪类实现埋点统计

使用:active伪类结合content属性,实现无JavaScript的埋点统计功能。

<body>
    <button class="button1">点我上传</button>
    <button class="button2">点我上传2</button>
</body>

<style>
    /* 第一次点击可以触发 */
.button1:active::after{
    content: url(./pixxel.gif?action=click&id=button1);
}
.button2:active::after{
    content: url(./pixxel.gif?action=click&id=button2);
}
</style>
  • 简单的用户行为统计
  • 按钮点击事件追踪
  • 无需JavaScript的埋点方案

5. :focus-within实现搜索交互

使用:focus-within伪类实现父元素在子元素获得焦点时的样式变化,适用于搜索框下拉菜单等交互场景。

<!-- 适合做 搜索框结果的 下拉 -->
<div class="cs-details">
    <a href="javascript:" class="cs-summary">我的消息</a>
    <div class="cs-datalist">
        <a href>我的回答<sup>12</sup></a>
        <a href>我的私信</a>
        <a href>未评价订单</a>
        <a href>我的关注</a>
    </div>
</div>


<style>
    .cs-datalist {
        display: none;
        position: absolute;
        border: 1px solid #000;
        background-color: #fff;
    }

    .cs-details:focus-within .cs-datalist {
        display: block;
    }
</style>
  • 搜索框下拉菜单
  • 导航菜单的子菜单显示
  • 表单元素的关联信息展示

6. <small>标签的使用

使用<small>标签表示小号文本,通常用于免责声明、注释等次要信息。

<small>你好</small>
<div>你好123</div>
  • 法律声明和条款
  • 文章注释和说明
  • 表单字段的辅助信息

7. <details><summary>实现折叠面板

使用<details><summary>标签实现原生的折叠面板功能,无需JavaScript。

<details style="user-select:none;">
    <summary>请选择</summary>
    <ul>
        <li>选项1</li>
        <li>选项2</li>
        <li>选项3</li>
    </ul> 
</details>  
  • 常见问题解答(FAQ)
  • 内容折叠展示
  • 配置选项面板

8. :placeholder-shown实现输入提示

使用:placeholder-shown伪类检测输入框是否显示占位符,实现输入状态的样式变化。

<input type="search" placeholder="请输入内容">
<small>尚未输入内容</small>

<style>
    :not(:placeholder-shown)+small {
        color: transparent;
    }
</style>
  • 输入框的状态提示
  • 表单验证的视觉反馈
  • 提升用户输入体验

9. :default伪类标记默认选项

使用:default伪类标记表单中的默认选项,如默认选中的单选按钮。

<!-- 更换选择,自动补充(推荐) -->
<p>请选择支付方式:</p>
<p><input name="pay" type="radio"><label>支付宝</label></p>
<p><input name="pay" type="radio" checked><label>微信</label></p>
<p><input name="pay" type="radio"><label>银行卡</label></p>

<style>
    input:default+label::after {
        content: '(推荐)';
    }
</style>
  • 表单默认选项标记
  • 推荐选项提示
  • 提高用户表单填写效率

10. <label>交互与计数器

使用<label>标签与复选框关联,结合CSS计数器实现选中项数量统计。

<body>
    <p>请选择你感兴趣的话题:</p>

    <input type="checkbox" id="topic1">
    <label for="topic1" class="cs-topic">科技</label>

    <input type="checkbox" id="topic2">
    <label for="topic2" class="cs-topic">体育</label>

    <input type="checkbox" id="topic3">
    <label for="topic3" class="cs-topic">军事</label>

    <input type="checkbox" id="topic4">
    <label for="topic4" class="cs-topic">娱乐</label>

    <p>您已选择 <span class="cs-topic-counter"></span>个话题。</p>

</body>

<style>
    .cs-topic {
        padding:5px 15px;
        cursor: pointer;
        border: 1px solid #000;
    }
    :checked+.cs-topic {
        border-color: skyblue;
        background-color: azure;
    }
    [type='checkbox'] {
        position: absolute;
        clip: rect(0 0 0 0);
    }

    body {
        counter-reset: topicCounter;
    }

    :checked+.cs-topic {
        counter-increment: topicCounter;
    }

    .cs-topic-counter::before {
        content: counter(topicCounter);
    }
</style>
  • 兴趣标签选择
  • 商品属性选择
  • 多选项表单交互

11. 表单校验与反馈

使用CSS伪类实现表单验证的视觉反馈,包括输入合法、非法和空值状态。

<!-- 表单校验 -->

<form id="csForm" novalidate>
    <p>
        验证码:
        <input class="cs-input" required pattern="\w{4}" placeholder="">
        <span class="cs-vaild-tips"></span>
    </p>

    <input type="submit" />
</form>

<style>
    /* 校验通过 */
    .cs-input:valid {
        background-color: green;
        color: #fff;
    }
    .valid .cs-input:valid+.cs-vaild-tips::before {
        content: '√';
        color: green;
    }

    /* 校验不合法提示 */
    .valid .cs-input:not(:placeholder-shown):invalid {
        border: 2px solid red;
    }
    .valid .cs-input:not(:placeholder-shown):invalid+.cs-vaild-tips::before {
        content: '不符合要求';
        color: red;
    }

    /* 空值提示 */
    .valid .cs-input:placeholder-shown+.cs-vaild-tips::before {
        content: '尚未输入值';
    }
</style>

<script>
    const form = document.querySelector('#csForm')
    const input = document.querySelector('.cs-input')

    // 即时的校验
    // form.addEventListener('input',(e)=>{
    //     form.classList.add('valid')
    // })

    // 优化:输入时实时更新校验提示(可选,提升体验)
    input.addEventListener('input', () => {
        if (form.classList.contains('valid')) {
            // 强制重绘,更新样式
            void form.offsetWidth;
        }
    })

    form.addEventListener('submit', (e) => {
        e.preventDefault()
        form.classList.add('valid') // 触发校验样式

        if (form.checkValidity()) {
            alert('校验通过')
        }
    })
</script>
  • 表单验证反馈
  • 实时输入校验
  • 提升表单填写体验

12. <fieldset><legend>组织表单

使用<fieldset><legend>标签组织表单内容,提高表单的结构性。

<form>
    <fieldset>
        <legend>问卷调查</legend>
        <ol>
            <li>1-3年</li>
            <li>3-5年</li>
            <li>5年以上</li>
            <h4>你从事前端几年了?</h4>
        </ol>
    </fieldset>
</form>
  • 复杂表单的分组
  • 提高表单的可访问性
  • 增强表单的语义结构

13. :empty伪类处理空内容

使用:empty伪类检测元素是否为空,为空白元素添加默认内容或样式。

<dl>
    <dt>姓名:</dt>   <dd>张三</dd>
    <dt>性别:</dt>   <dd></dd>
    <dt>手机:</dt>   <dd></dd>
    <dt>邮箱:</dt>   <dd></dd>
</dl>

<!-- :empty 兼容 ''、null,配合伪元素可填充自定义内容 -->
<style>
    dt {   float: left    }

    dd:empty::before {
        color: gray;
        /* content: '-'; */
        content: '暂无';
    }
</style>
  • 数据展示中的空值处理
  • 搜索结果为空的提示
  • 表单字段的默认显示

14. :only-child伪类条件显示

使用:only-child伪类检测元素是否为唯一子元素,实现条件性的样式显示。

<ul>
    <li> 仅剩一项时不可删除 <button>删除</button> </li>
    <li> 仅剩一项时不可删除 <button>删除</button> </li>
    <li> 仅剩一项时不可删除 <button>删除</button> </li>
</ul>

<style>
    li:only-child button { display: none  }
</style>


<script>
    // 点击删除 li
    const buttons = document.querySelectorAll('li button')
    buttons.forEach(btn => {
        btn.addEventListener('click', function () {
            btn.parentElement.remove()
        })
    })
</script>
  • 列表项的删除按钮控制
  • 条件性UI元素显示
  • 动态内容的样式调整

15. :not()伪类初始化样式

使用:not()伪类排除特定元素,实现样式的初始化和重置。

<!-- 激活面板优雅切换 -->
<!-- 
<div class="cs-panel">面板1</div>
<div class="cs-panel active">面板2</div>
<div class="cs-panel">面板3</div>

<style>  .cs-panel:not(.active) { display: none} </style>
 -->


<!-- 灵活性 -->
<div class="cs-panel">面板1</div>
<div class="cs-panel  flex">面板2</div>
<div class="cs-panel active grid">面板3</div>

<style>
    .cs-panel:not(.active) {  display: none  }
    
    .flex {    display: flex  }
    .grid {    display: grid   }
</style>
  • 选项卡面板切换
  • 激活状态的样式控制
  • 组件的默认状态管理

总结

本文档介绍了CSS新世界中的15个实用技巧,涵盖了样式隔离、选择器优化、表单交互、内容展示等多个方面。这些技巧充分利用了现代CSS的新特性,能够帮助开发者编写更简洁、高效、可维护的代码,同时提升用户体验。

随着CSS标准的不断发展,我们可以期待更多强大的特性和技巧出现。希望本文档能够为开发者提供参考,让大家在CSS的世界中探索更多可能性。

参考资源

  • 张鑫旭《css选择器》
❌
❌