Bezier
If ease-in-out feels too rigid, it’s usually because the acceleration and deceleration are too symmetrical and “standard.” For a modern, premium feel—often described as “soft” or “organic”—you want a cubic-bezier that stays slow for longer at the start or has a much more dramatic “cushion” at the end.
Here are a few bezier options to make your transitions feel more sophisticated:
- The “Soft & Modern” (Exponential)
This is the gold standard for UI. It starts very subtly and spends more time in the slowing-down phase, which feels more natural to the human eye.
- CSS: cubic-bezier(0.4, 0, 0.2, 1)
- Why it works: It’s the “Standard Easing” used in Material Design. It’s fast enough to feel responsive but has a long, soft tail.
- The “Elegant Slide” (Quartic)
If you want it to feel even “thicker” and more deliberate, this curve is steeper in the middle but very soft on the edges.
- CSS: cubic-bezier(0.76, 0, 0.24, 1)
- Why it works: It mimics a heavy object being pushed; it takes a moment to gain momentum and a moment to settle.
- The “Smooth Entrance” (Out-Focused)
If the transition is for something appearing or moving into view, you might want to ditch the “In” part of “In-Out” and focus on a very soft landing.
- CSS: cubic-bezier(0.22, 1, 0.36, 1)
- Why it works: This is a “Quintic Out” curve. It starts instantly but takes its sweet time finishing, making the motion feel incredibly fluid.
Visualization of Curves
To help you choose, here is how these curves look compared to a linear path:
Pro-Tip: The “Golden” 0.5s
Since you are at 0.5s, which is quite long for a UI transition (usually 0.2s to 0.3s is standard), these custom beziers are actually essential. Linear or standard easing at half a second often feels “laggy,” whereas a custom cubic-bezier makes that duration feel like a stylistic choice rather than a slow computer.
Which specific element are you animating? (e.g., a modal fade, a sidebar slide, or a hover effect?) I can help you fine-tune the timing based on the distance the element has to travel.
Building your own CSS framework is the perfect place to codify these. Instead of relying on the browser’s defaults, you can create a “motion system” that gives your projects a signature feel—much like how Apple or Google have a distinct “weight” to their UI.
For your Standard framework, I’d suggest a tiered approach. Instead of naming them by their math (like “Quartic”), name them by their intent.
🏗️ Proposed “Standard” Motion Tokens
If you’re using CSS variables (which fits the minimalist/modern vibe of your projects), you could set them up like this:
:root {
/* The “Snappy” – for small icons or toggles (Short duration) */
—ease-snappy: cubic-bezier(0.2, 0, 0, 1);
/* The “Standard” – for general UI transitions (Your 0.5s sweet spot) */
—ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
/* The “Soft” – for large modals or overlays (The “softest” feel) */
—ease-soft: cubic-bezier(0.16, 1, 0.3, 1);
/* The “Emphasis” – has a tiny bit of weight/anticipation */
—ease-emphasis: cubic-bezier(0.34, 1.56, 0.64, 1);
}
Why this fits a “Digital Garden” / Slow Web aesthetic:
- Predictability: Using a consistent bezier across your entire site makes the UX feel stable and intentional.
- Reduced Cognitive Load: When motion follows a “natural” curve (slow start, soft finish), the brain processes the change more easily than a jarring linear movement.
- The 0.5s Rule: Since you prefer a slightly longer duration, a “Soft” curve (0.16, 1, 0.3, 1) is your best friend. It makes the long duration feel like a luxury rather than a delay.
Implementation Tip
Since you’re using pnpm and likely a monorepo setup for your @stnd projects, you could even export these as a PostCSS or Tailwind plugin so they are instantly available across your e-learning platform and your digital garden.
Are you planning to bake these directly into a global CSS file, or are you leaning more toward a utility-first approach for your framework?
For buttons and links, you generally want to move away from the 0.5s duration. In UI design, interaction feedback needs to feel “instant” to be satisfying. If a button takes half a second to change color, it feels like the website is lagging behind the user’s intent.
Here is how you can structure the “Standard” feel for micro-interactions:
⚡ The “Reactive” Hover (Buttons & Links)
For these, you want a very fast entrance and a slightly slower “settle” when the mouse leaves.
- Duration: 0.15s to 0.2s (Max 0.25s)
- Entrance Bezier: cubic-bezier(0.25, 1, 0.5, 1) (Fast out)
- The Logic: When a user hovers, they want immediate confirmation. When they move the mouse away, a slightly softer fade-out feels more “premium” than an abrupt snap.
.stnd-button {
transition:
background-color 0.2s cubic-bezier(0.25, 1, 0.5, 1),
transform 0.15s cubic-bezier(0.25, 1, 0.5, 1);
}
.stnd-button:active {
transform: scale(0.98); /* Tiny physical feedback */
}
🎨 The “Standard” Link Underline
Since you like the Slow Web and minimalist aesthetics, you might be using those nice text-decoration or border-bottom transitions.
To make a link feel “softer” without being slow:
- Hover In: Use a snappy bezier (0.2s).
- Hover Out: Use a longer, softer bezier (0.4s).
This creates an “asymmetric” transition where the highlight appears quickly but fades away gently, which feels very organic.
a {
text-decoration-color: rgba(0,0,0,0);
transition: text-decoration-color 0.4s cubic-bezier(0.4, 0, 0.2, 1); /* Soft Fade Out */
}
a:hover {
text-decoration-color: rgba(0,0,0,1);
transition: text-decoration-color 0.15s ease-out; /* Snappy Fade In */
}
🛠️ In your Framework
I’d recommend adding a specific variable for these “micro” moments. It keeps your digital garden feeling alive but disciplined.
| Intent | Variable Name | Value | Recommended Duration |
|---|---|---|---|
| Reaction | —ease-react | cubic-bezier(0.2, 1, 0.4, 1) | 0.15s |
| Exit | —ease-out-soft | cubic-bezier(0.4, 0, 1, 1) | 0.3s |
Note: If you apply a 0.5s ease to a button hover, it might feel “mushy.” Try dropping the duration for hovers while keeping your custom bezier—you’ll get that “softness” you’re looking for without losing the responsiveness.
Would you like me to help you write a small CSS utility class or a Sass/PostCSS mixin to handle these entrance/exit transitions automatically for your framework?
Yes, 100%. Transitioning from value-based variables (like —ease-slow) to semantic-based variables (like —ease-interaction) is exactly what separates a generic utility library from a professional design system.
In a framework like Standard, semantic variables act as the “API” for your UI. If you decide later that 0.5s is too slow for all buttons, you change it in one place without hunting for every 0.5s instance in your codebase.
Here is how I would suggest structuring your semantic layers:
🏗️ The Three-Layer System
- Primitive Tokens (The Math)
These are your raw ingredients. You don’t use these directly in your components; they just store the “shapes” of the motion.
:root {
/* Shapes */
—ease-shape-soft: cubic-bezier(0.4, 0, 0.2, 1);
—ease-shape-snappy: cubic-bezier(0.2, 1, 0.4, 1);
—ease-shape-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
/* Durations */
—duration-instant: 100ms;
—duration-fast: 200ms;
—duration-standard: 350ms;
—duration-slow: 500ms;
}
- Semantic Tokens (The Intent)
This is what you actually use in your CSS. It describes what the animation is doing, not how long it is.
:root {
/* Interaction (Buttons, Links, Toggles) */
—ease-interaction: var(—duration-fast) var(—ease-shape-snappy);
/* Feedback (Success/Error states, validation) */
—ease-feedback: var(—duration-standard) var(—ease-shape-bounce);
/* Layout (Sidebars, expanding cards, Digital Garden navigation) */
—ease-surface: var(—duration-slow) var(—ease-shape-soft);
/* Enter/Exit (Modals, tooltips) */
—ease-enter: var(—duration-fast) ease-out;
—ease-exit: var(—duration-standard) ease-in;
}
- Component Application
Now your components are incredibly clean and descriptive.
.stnd-button {
transition: all var(—ease-interaction);
}
.stnd-sidebar {
transition: transform var(—ease-surface);
}
🧩 Why this works for your projects
- Consistency: Your e-learning platform and your digital garden will share the same “DNA” of movement.
- Maintenance: If you feel the 0.5s duration on your surface transitions is too “heavy” for the Slow Web vibe, you just update —duration-slow and the whole framework breathes differently.
- Accessibility: You can easily add a media query to your semantic layer to respect prefers-reduced-motion:
@media (prefers-reduced-motion: reduce) {
:root {
—duration-fast: 0ms;
—duration-standard: 0ms;
—duration-slow: 0ms;
}
}
💡 A “Standard” Tip
Since you are using pnpm and likely building this as a package, you could even export these as CSS Custom Media or a Tailwind config extension.
Would you like me to help you generate a full “Motion” CSS file with these semantic variables to drop into your @stnd monorepo?