gabrielobholz-corner-smoothing
About gabrielobholz-corner-smoothing
gabrielobholz-corner-smoothing is a design skill for implementing Apple- or iOS-style smoothed corners. It uses path geometry rather than simply increasing CSS border radius, and covers radius clamping, layout stability, and path animation.
Key features
- 01Generate smoothed paths from dimensions
- 02SVG, CSS, Canvas, and WebGL guidance
- 03Clamp radius to half the shorter side
- 04Use 60% as the Apple-style target
- 05Animate the path without shifting layout
Use cases
- 01Implement Figma-style smoothed corners
- 02Generate paths for DOM or SVG rectangles
- 03Draw shapes in Canvas or WebGL
- 04Keep layout size stable during corner animation
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ gabrielobholz/ corner-smoothing-skill --skill gabrielobholz-corner-smoothingAfter installing, type/gabrielobholz-corner-smoothingin Claude Code to confirm it loaded.
Bundled filesagents/openai.yamlreferences/implementation.md
Details
From the project READMEApple Corner Smoothing
Use path-based geometry when a design asks for Apple/iOS-like corner smoothing, especially the common 60% Figma Corner Smoothing look. CSS border-radius alone cannot express this shape.
Quick Reference
| Need | Use |
|---|---|
| DOM/SVG rectangle | Generate a <path d="..."> from width, height, radius, smoothing |
| CSS-only component | Use clip-path: path("...") when acceptable, otherwise inline SVG |
| Canvas/WebGL | Use the same sampled superellipse points as a polygon/path |
| Figma parity | Treat 60% as the Apple/iOS-style target |
| Plain rounded corner | Use smoothing: 0 |
For copy-paste code, read implementation.md.
Core Principles
1. Do Not Fake It With Bigger Radius
Increasing border-radius changes the radius, not the corner transition. Apple-like smoothing keeps the same radius but eases the transition between straight edges and the corner.
2. Prefer Paths
Use SVG path data, clip-path: path(...), Canvas Path2D, or framework-specific vector paths. This avoids layout hacks, nested masks, pseudo-elements, and broken edge cases.
3. Keep Radius Clamped
Always clamp radius to min(width, height) / 2. This prevents self-intersecting paths when components become small or responsive.
4. Make 60% The Apple Target
When a user asks for Apple/iOS-style corners and gives no other value, use smoothing: 60. Use 0% for normal circular border-radius, 100% only for maximum stylization.
5. Preserve Layout
The smoothing path should affect only drawing/clipping. Do not change element width, height, padding, or layout metrics while animating smoothing.
6. Animate The Path, Not The Box
When animating smoothing, keep width, height, and radius stable and update only the generated path. If also animating labels or numbers, use fixed-size containers and tabular numbers.
Implementation Workflow
- Read the requested width, height, radius, and smoothing percent.
- If the target can be SVG, render a
<path>and set itsdattribute. - If the target must be HTML/CSS, use
clip-path: path(...)only when browser support and scaling are acceptable; otherwise put an SVG behind or in front of the element. - Use
smoothing: 60for Apple/iOS-style unless the user specifies another value. - Validate at small sizes and at maximum radius.
Common Mistakes
| Mistake | Fix |
|---|---|
border-radius: 52px and calling it smoothing | Generate a smoothed path |
| Radius larger than half the box | Clamp radius |
| Layout changes during smoothing animation | Keep layout fixed and update path only |
| Using one-off path strings | Use a reusable function with radius and smoothing |
| Applying 100% by default | Use 60% for Apple/iOS-style |
| Using CSS masks that blur edges | Prefer SVG path or clean vector clip |
Review Checklist
- Radius is clamped to half the smaller side
-
smoothing: 60is used for Apple/iOS-style unless specified otherwise - The shape is path-based, not a border-radius-only approximation
- Width, height, and layout do not shift during smoothing changes
- The generated path works for square and rectangular shapes
- The component has a fallback or acceptable behavior if
clip-path: path()is unsupported