@cssints/squircle

中文文档
0.35.1发布于 2026/11/07MITTypeScriptES Module零依赖构建来源已验证近 30 天下载 7511

Squircle corners for cssints: native corner-shape: squircle, a CSS mask where a target lacks it

原始使用文档
文档目录5 节
  1. Browsers
  2. Why a mask
  3. Rules
  4. Limits
  5. Credits

@cssints/squircle

Squircle corners for cssints, as one chain member of cssints/plugin scope(): native corner-shape: squircle where the targets have it (Chrome 139), and a CSS mask that cuts the same curve where one lacks it. No script.

import { bg, cn, hover } from "cssints" with { type: "cssints" };
import { squircle } from "@cssints/squircle" with { type: "cssints" };

export const icon = cn(squircle().radius("24px"), bg("tomato"));
export const card = cn(squircle(), hover(squircle().radius("2rem")));
@layer _.k {
  ._squircle-core {
    border-radius: var(--squircle-r);
    corner-shape: squircle;
    --squircle-r: 1rem;
  }
  /* only when a browserslist target lacks corner-shape (Firefox, Safari today) */
  @supports not (corner-shape: squircle) {
    ._squircle-core {
      --squircle-m: url("data:image/svg+xml,%3Csvg … viewBox='-1 -1 2 2' preserveAspectRatio='none'%3E%3Cpath d='M1 0C1 .92 .92 1 0 1…Z'/%3E%3C/svg%3E");
      border-radius: 0;
      mask:
        var(--squircle-m) 0 0 / min(2 * var(--squircle-r), 100%) min(2 * var(--squircle-r), 100%)
          no-repeat,
        var(--squircle-m) 100% 0 / … no-repeat,
        var(--squircle-m) 0 100% / … no-repeat,
        var(--squircle-m) 100% 100% / … no-repeat,
        linear-gradient(#000 0 0) 50% / 100% max(0px, 100% - 2 * var(--squircle-r)) no-repeat,
        linear-gradient(#000 0 0) 50% / max(0px, 100% - 2 * var(--squircle-r)) 100% no-repeat;
    }
  }
}
@layer _.a {
  ._c2r73i {
    --squircle-r: 24px;
  }
}
@layer _.b {
  ._1xgz4ts:hover {
    --squircle-r: 2rem;
  }
}

Browsers

  • Native (css.properties.corner-shape.squircle): Chrome 139. Firefox and Safari have it in preview only; Playwright's WebKit build already has it.
  • The fallback is a runtime of CSS only (polyfills: ["css.properties.corner-shape", "css.properties.corner-shape.squircle"]), so it is in the sheet only when a browserslist target lacks the feature, and @supports not keeps it off in a browser that has it. The kernel's requires and the support warnings of its declarations are covered by it: no build warning. It needs mask with var() and min()/max() in its sizes: Firefox 75, Safari 15.4 (LightningCSS does not prefix a value with var()).
  • Checked in Chrome, Firefox and WebKit (bun run test:browsers): the corners and edges of a box read from a screenshot, from a build for Chrome 139 only, one for Firefox and Safari too, and that build with corner-shape cut out (the mask alone). Where both run, the mask's 40px corner is the native one to 2 pixels in 1 600 (Chrome) and 0 (WebKit).

Why a mask

  • A paint worklet (css-houdini-squircle, extra.css) runs in Chromium only, which has corner-shape now: it would cover no browser that lacks the feature, and it ships a script.
  • Plain border-radius costs nothing (a browser drops corner-shape and keeps the radius), but the corner is a circle: at the same radius it cuts almost twice as deep along the diagonal (0.29 of the radius against 0.16), and it reads as another shape.
  • The mask is the shape itself, at any size, with no script: one SVG of the superellipse |x|⁴ + |y|⁴ = 1 (corner-shape: squircle is superellipse(2)), four cubics within 0.5% of the curve, put at the four corners at twice the radius, and two bands of linear-gradient between them. Each corner layer is a squircle of a smaller box, so their union with the bands is the element's squircle; the sizes follow the element through percentages, with no measuring.

Rules

  • radius(<length-percentage [0,∞]>), once, optional (1rem). It sets --squircle-r, so it works under a condition (hover(squircle().radius("2rem"))). A percentage is of each side, as in border-radius (elliptical corners); a radius over half the box is clamped by the browser natively, and by min(…, 100%) in the mask.
  • No inheritance. The kernel sets --squircle-r on its class, so a squircle inside another one has its own radius.
  • Conflicts. squircle() sets the corners: a cn() that holds it and a border-*radius or corner-* property is a build error, derived from the kernel (written as styles): cssints: squircle: kernel core sets border-radius, corner-shape (this style also sets border-top-left-radius). Set the radius with radius().
  • Errors are the grammar's, in the types and at build time: squircle.radius: unexpected "-4px" in "-4px", expected <length-percentage [0,∞]>.

Limits

  • The mask clips what is drawn outside the shape. In the fallback a box-shadow, an outline (a focus ring) and the corners of a border are cut: the border is drawn square and the mask trims it, so it thins at the corners. Put the shadow on a wrapper (filter: drop-shadow() follows the mask), or a ring inside. The native path draws them along the curve.
  • One shape: no superellipse(k) smoothing, no per-corner radii or shapes. The mask is one SVG; another exponent would be another SVG per value (a build-time url() on a custom property), which waits for a use.
  • mask belongs to the fallback: a mask of your own on a squircle replaces it where the fallback runs.
cd packages/squircle && bun run test            # fixtures through the engine (output for both kinds of targets, conflicts, errors)
cd packages/squircle && bun run typecheck       # and the type test (test/types)
cd packages/squircle && bun run test:browsers   # Chrome, Firefox and WebKit through playwright-core

Credits

The curve is the superellipse of CSS Borders and Box Decorations Level 4 (corner-shape: squircle). The mask is drawn here; nothing is copied.

版本与发布记录

@cssints/squircle 共发布 43 个版本,首次发布于 2026/10/11;过去 12 个月发布了 43 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.35.1latest2026/11/073 天前
0.35.02026/11/073 天前
0.34.02026/11/073 天前
0.33.02026/11/046 天前
0.32.02026/11/046 天前
0.31.02026/11/047 天前

关于 @cssints/squircle 的常见问题

@cssints/squircle 是什么?

Squircle corners for cssints: native corner-shape: squircle, a CSS mask where a target lacks it

如何安装 @cssints/squircle?

在项目目录运行 npm install @cssints/squircle,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:cssints(^0.35.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@cssints/squircle 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cssints/squircle 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@cssints/squircle 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@cssints/squircle 可以商用吗?

@cssints/squircle 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cssints/squircle 的下载量有多少?

根据 npm 官方下载统计,@cssints/squircle 在 2026/10/11 – 2026/11/09 这 30 天内被下载 7,511 次,日均约 250 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cssints/squircle 还在维护吗?

最新版本 0.35.1 发布于 2026/11/07(3 天前);至今共发布 43 个版本,其中过去 12 个月发布了 43 个;首次发布于 2026/10/11。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。