阅读视图

发现新文章,点击刷新页面。

CSS进阶: background-clip

background-clip 是 CSS 中一个用于控制背景(背景颜色或背景图片)的显示范围的属性。简单来说,它可以决定背景是铺满整个盒子(包括边框)、只铺到边框内部,还是只铺到文字下方。

它的核心作用是限制背景的绘制区域

基本语法与三个主要属性值

1. border-box(默认值)

背景延伸到边框区域的下方(即背景会覆盖边框)。

  • 效果: 如果边框是半透明或点线样式,你能看到边框下面的背景。
  • 示例:
    .box {
        background-clip: border-box;
        /* 背景会铺满整个元素区域,包括边框部分 */
    }
    

image.png

2. padding-box

背景只延伸到内边距(padding)区域,边框下面没有背景

  • 效果: 背景在边框内部就停止了,边框保持纯色(通常是元素本身的背景色或透明)。
  • 示例:
    .box {
        background-clip: padding-box;
        /* 背景只铺到内边距边缘,边框区域无背景 */
    }
    

image.png

3. text(最炫酷、最常用)

将背景裁剪成文字的形态。

  • 效果: 背景只在文字的形状内显示,文字以外的区域背景不可见。
  • 关键配合: 通常需要配合 color: transparent 将文字颜色设为透明,才能看到被裁剪出来的背景。
  • 示例: 实现渐变文字、图片文字效果。
    .text {
        background-image: linear-gradient(45deg, #f00, #00f); /* 设置渐变背景 */
        color: transparent; /* 把文字本身的颜色变透明 */
        background-clip: text; /* 把背景裁剪成文字的形状 */
        -webkit-background-clip: text; /* 某些浏览器需要加前缀 */
    }
    

image.png

直观理解

想象一个带有内边距(padding)、边框(border)和背景色的盒子:

  • border-box:油漆刷满整个盒子,连边框(即使边框是虚线)也覆盖了背景色。
  • padding-box:油漆刷到边框内侧就停止了,边框区域没有油漆,保持原色。
  • text:油漆只涂在文字笔画上,其他地方(包括文字内部的镂空部分)都是透明的。

主要应用场景

  1. 渐变文字(最流行): 使用 background-clip: text 配合渐变色,制作醒目的标题。
  2. 特殊边框效果: 当希望边框是纯色,而背景在边框内部显示时(例如实现双层边框效果),可以使用 padding-box
  3. 精确控制背景平铺: 当不希望背景图延伸到边框下时,通过 padding-box 可以精确控制背景的边界。

浏览器兼容性

我们来具体看一下 background-clip 属性的浏览器兼容性情况。

总的来说,background-clip 的基础功能(border-boxpadding-boxcontent-box)兼容性非常好,可以放心使用。但它的“明星”功能 text 值兼容性稍复杂一些,需要特别注意写法。

我把它们的兼容性情况整理成了表格,方便你查看:

属性值 支持情况 主要细节 兼容性概览
基础值
(border-box, padding-box, content-box)
全面支持 所有现代浏览器及 IE9+ 均支持。 ✅ 很好
text 值
(background-clip: text)
广泛支持,但有细节 Chrome、Edge、Opera:从较早期版本就开始支持。
Safari:从 15.5 版本开始完全支持,早期版本(3.2-15.4)需加 -webkit- 前缀且为部分支持。
Firefox:从 49 版本开始支持,但早期版本(2-48)不支持。
Internet Explorer:全系不支持
移动端:主流浏览器(iOS Safari、Chrome for Android、Samsung Internet 等)基本都支持,但 Opera Mini 全系不支持。
🟡 良好,需注意

关键知识点与最佳实践

结合你之前问到的 background-clip 作用,这里有几个实践中的要点:

  1. text 值的标准写法 为了让 background-clip: text 在所有支持的浏览器上生效,必须同时使用带 -webkit- 前缀和不带前缀的写法。同时,记得将文字颜色设置为透明,背景图才能透出来。

    .gradient-text {
      background-image: linear-gradient(45deg, #ff6b6b, #4ecdc4);
      -webkit-background-clip: text; /* 为基于 WebKit 内核的浏览器添加 */
      background-clip: text;        /* 标准属性 */
      color: transparent;            /* 让文字颜色透明,露出背景 */
      -webkit-text-fill-color: transparent; /* 为 Safari 浏览器添加,增强兼容性 */
    }
    

    这里额外添加了 -webkit-text-fill-color: transparent,可以进一步增强在 Safari 等浏览器上的表现。

  2. Firefox 的特别注意事项 虽然 Firefox 从 49 版本开始支持 background-clip: text,但网上一些资料提到它在部分 Firefox 版本中可能存在问题,或者效果不如 Chrome/Safari 稳定。为了稳妥,可以结合 @supports 进行特性检测,为不支持(或支持不完美)的浏览器提供一个优雅的降级样式。

    .gradient-text {
      /* 默认样式(降级方案),比如一个纯色 */
      color: #ff6b6b;
    }
    
    /* 当浏览器支持 background-clip: text 时,应用渐变效果 */
    @supports (background-clip: text) or (-webkit-background-clip: text) {
      .gradient-text {
        background-image: linear-gradient(45deg, #ff6b6b, #4ecdc4);
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
        -webkit-text-fill-color: transparent;
      }
    }
    
  3. 避开已知的坑

    • 不要只写不带前缀的属性:在现代浏览器中,仅写 background-clip: text 可能被忽略。
    • 背景必须用 background-image:使用渐变或图片,纯色背景无法体现裁切效果。
    • 留意边缘渲染:在一些非整数缩放比例或高分辨率屏幕上,文字边缘可能会出现轻微发虚或锯齿。通常使用稍粗一点的字体 (font-weight: 600 或更粗) 可以缓解。

总结一下,background-clip 的基础功能可以无忧使用。如果要用 text 值实现炫酷的文字效果,遵循上述的双前缀、透明文字和降级方案这“三板斧”,就能在绝大多数现代浏览器上获得理想且稳定的效果。

一文搞懂Nextjs中的Proxy

在 Next.js 中,“Proxy” 这个概念实际上指向两个不同层面但同样重要的功能:一个是 Next.js 15 之后内置的、运行在边缘网络上的请求拦截器(原 Middleware),另一个则是通过配置文件实现的、用于转发 API 请求的 Rewrites 代理

简单来说,前者像是应用的门卫,后者则像是应用的传话员

为了帮你更清晰地理解,我把它们的核心区别整理成了一个表格:

特性 内置 proxy (原 Middleware) 配置 rewrites (反向代理)
核心定位 在请求到达页面之前,运行自定义代码进行拦截和处理。 将请求从一个路径“映射”到另一个路径(可以是内部或外部URL),对客户端透明。
主要用途 鉴权、A/B测试、国际化、日志记录、修改请求/响应头。 解决跨域问题、隐藏真实API地址、将旧站点路由平滑过渡到新应用、集成第三方服务。
运行时机 redirects 之后,beforeFiles rewrites 之前。 有三种时机:beforeFilesafterFilesfallback,可以在文件系统(页面/静态文件)检查前后执行。
代码位置 项目根目录下的 proxy.tsproxy.js 文件。 next.config.js 文件中的 async rewrites() 函数。
能力范围 可以编程式地返回 NextResponse,实现 redirectrewrite, 或直接响应。 声明式地配置 sourcedestination 映射关系,支持复杂的路径匹配规则。

深入理解:内置 proxy (原 Middleware)

从 Next.js 15 开始,原来的 middleware 文件被重命名为 proxy,其功能保持不变。你可以把它想象成一个在服务器上运行、在用户请求到达页面之前的“检查站”。

  • 关键特性与能力proxy 函数中,你可以访问 NextRequest 对象,并通过返回 NextResponse 来实现多种操作:

    1. 重写(Rewrite):在服务端将请求映射到另一个 URL,但客户端浏览器地址栏的 URL 不会改变。这非常适合做 A/B 测试或在同一个域名下托管不同版本的应用。
      // proxy.ts
      import { NextResponse } from 'next/server'
      import type { NextRequest } from 'next/server'
      
      export function proxy(request: NextRequest) {
        if (request.nextUrl.pathname.startsWith('/about')) {
          // 访问 /about 的用户,实际看到的是 /about-2 页面的内容
          return NextResponse.rewrite(new URL('/about-2', request.url))
        }
      }
      
    2. 重定向(Redirect):将请求引导至另一个 URL,浏览器地址栏会更新。适用于用户登录校验或永久移动的页面。
      // proxy.ts
      import { NextResponse } from 'next/server'
      import type { NextRequest } from 'next/server'
      
      export function proxy(request: NextRequest) {
        if (!isLoggedIn(request)) {
          // 未登录用户访问 dashboard 时,跳转到登录页
          return NextResponse.redirect(new URL('/login', request.url))
        }
      }
      
    3. 操作头信息与 Cookie:可以读取、设置或删除请求头和响应头,以及 Cookie,用于实现功能开关、用户追踪等。
    4. 直接响应:甚至可以直接在 proxy 层返回一个响应体,而不需要经过页面渲染,比如返回一个简单的 robots.txt 或维护页面。
  • 配置与执行 proxy 默认会作用于所有路由,因此强烈建议通过导出的 config 对象中的 matcher 选项来精确控制其生效路径,以优化性能。

    // proxy.ts
    export const config = {
      matcher: [
        /*
         * 匹配所有除了以这些开头的路径:
         * - api (API routes)
         * - _next/static (静态文件)
         * - _next/image (图片优化文件)
         * - favicon.ico, sitemap.xml (静态资源文件)
         */
        '/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml).*)',
      ],
    }
    

深入理解:配置 rewrites (反向代理)

rewrites 是定义在 next.config.js 中的一个异步函数,它更像是一种“声明式”的代理规则。它告诉 Next.js 服务器:“当用户请求路径 A 时,你悄悄地替我去路径 B 拿到内容,然后返回给用户。”

  • 核心价值与场景

    1. 解决跨域(CORS):这是开发中最常见的用途。通过将前端对 /api 的请求,在 Next.js 服务端转发到真实的后端 API 地址(如 https://api.example.com),从而绕过了浏览器的同源策略。
      // next.config.js
      module.exports = {
        async rewrites() {
          return [
            {
              source: '/api/:path*', // 前端请求的路径
              destination: 'https://api.example.com/:path*', // 实际转发的后端地址
            },
          ]
        },
      }
      
    2. 集成第三方服务:可以隐藏第三方服务的真实地址,将其“包装”成自己域名下的接口,避免被广告屏蔽器拦截,同时也更安全。
    3. 平滑迁移:当你将旧站点逐步迁移到 Next.js 时,可以用 fallback 类型的 rewrites,让所有不存在的页面都 fallback 到旧站点,实现渐进式重构。
  • 三种执行时机 rewrites 函数可以返回一个对象,包含三种数组,它们在不同的时机执行,提供了极大的灵活性:

    • beforeFiles:在检查 public 目录下的静态文件和页面路由之前执行。可以用来覆盖某些特定页面。
    • afterFiles:在检查完静态文件和页面路由之后,但在动态路由(如 pages/[slug].js)之前执行。
    • fallback:在所有路由(包括动态路由)都没有匹配到之后,返回 404 页面之前执行。非常适合作为“最后一道防线”代理到旧系统。
  • 高级匹配规则 rewritessource 路径支持参数化和正则表达式,并能根据 hasmissing 条件(如特定的 header、cookie 或 query 参数)来决定是否应用。

    // next.config.js
    module.exports = {
      async rewrites() {
        return [
          {
            source: '/blog/:slug',
            destination: '/news/:slug', // 将 /blog/hello 转发到 /news/hello
          },
          {
            source: '/old/:path*',
            destination: 'https://legacy-site.com/:path*', // 代理到外部 URL
          },
          {
            source: '/admin/:path*',
            has: [{ type: 'cookie', key: 'authorized', value: 'true' }],
            destination: '/dashboard/:path*', // 只有携带特定 cookie 时才转发
          },
        ]
      },
    }
    

总结与选择指南

简单来说,如何选择取决于你的业务逻辑:

  • 如果你的逻辑是编程式的、条件复杂的、需要读取或修改请求/响应头,例如“检查用户是否登录,未登录就跳转”,那么请使用 proxy
  • 如果你的逻辑是声明式的、纯粹的路径映射,例如“将所有 /api 请求转发到另一个服务器来解决跨域问题”,那么请使用 rewrites

在开发环境中,rewrites 通常是解决 API 跨域问题的最简单、最标准的方法。而在生产环境中,虽然 rewrites 也可以作为反向代理,但更常见的做法是在 Next.js 应用前面再加一层专业的反向代理服务器(如 Nginx),来处理负载均衡、SSL 终端和安全防护等更底层的网络问题。

❌