Skip to content

refactor(Toast)!: move the transition to CSS with @starting-style - #707

Merged
mrholek merged 1 commit into
v6-devfrom
refactor/toast-css-transitions-v6
Aug 7, 2026
Merged

refactor(Toast)!: move the transition to CSS with @starting-style#707
mrholek merged 1 commit into
v6-devfrom
refactor/toast-css-transitions-v6

Conversation

@mrholek

@mrholek mrholek commented Aug 7, 2026

Copy link
Copy Markdown
Member

Toast was the last component in the library driving its animation from JavaScript: it toggled .fade, forced a reflow, then juggled .show, .showing and a deprecated .hide class to fake an exit animation. Menu and the picker popup already express this in CSS, so Toast now does the same — @starting-style supplies the state to animate from, and a discrete display transition keeps the toast laid out until the fade-out finishes. JavaScript only toggles .show.

Compiled output:

.toast { display: none; … }
.toast:not(.toast-instant) {
  opacity: 0;
  transition: opacity var(--cui-toast-transition-duration) var(--cui-toast-transition-timing),
              display var(--cui-toast-transition-duration) allow-discrete;
}
.toast.show { display: block; opacity: 1; }
@starting-style { .toast:not(.toast-instant).show { opacity: 0; } }

display: block on .show is what the toast rendered as before (the base rule only said :not(.show) { display: none }), so nothing moves on the page.

Breaking

  • The animation option and data-coreui-animation are gone. Add .toast-instant to skip the animation.
  • .showing and the deprecated .hide class are gone, and toasts no longer take the generic .fade class. The stale "we still toggle .hide for backwards compatibility" callout goes with them.
  • isShown() returns false as soon as hide() is called, rather than when the fade-out ends.

Recorded in the v6 migration guide; docs get an Instant section and lose the animation row.

Worth a look before merging

.toast-instant is the first -instant class in this tree. Upstream introduced it alongside .dialog-instant / .drawer-instant, which we do not have — our Modal and Offcanvas still take animation from the .fade class in markup, and Tooltip still has an animation option. If you would rather keep animation as the public knob for now, say so and I will drive the class from the option instead of dropping it.

Not covered by tests

The unit suite exercises the JS (32 specs, incl. two new ones asserting shown/hidden fire synchronously for an instant toast), but it does not load the compiled CSS, so @starting-style and the discrete display transition are unverified by automation. Toast is not in the visual suite yet — a candidate when that suite grows.

Unrelated observation

Every toast example in the docs (v5 and v6, and upstream too) is markup without .show, which .toast { display: none } hides — the published page at coreui.io/bootstrap/docs/components/toasts renders empty boxes held open by .docs-example-toasts { min-height: 240px }. Not touched here; worth its own fix.

Ported from twbs/bootstrap#42783.

Toast was the last component driving its animation from JavaScript: it
toggled `.fade`, forced a reflow, then juggled `.show`, `.showing` and a
deprecated `.hide` class to fake an exit animation. Menu and the picker popup
already express this in CSS, so Toast now does the same — `@starting-style`
supplies the state to animate from, and a discrete `display` transition keeps
the toast laid out until the fade-out finishes. JavaScript only toggles
`.show`.

BREAKING CHANGE: the `animation` option and `data-coreui-animation` are gone;
add `.toast-instant` to skip the animation. The `.showing` class and the
deprecated `.hide` class are gone with them, and toasts no longer take the
generic `.fade` class. `isShown()` now returns `false` as soon as `hide()` is
called, rather than when the fade-out ends.

Ported from twbs/bootstrap#42783.
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 31188239378

Coverage decreased (-0.005%) to 92.97%

Details

  • Coverage decreased (-0.005%) from the base build.
  • Patch coverage: 6 of 6 lines across 1 file are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 8666
Covered Lines: 8271
Line Coverage: 95.44%
Relevant Branches: 4819
Covered Branches: 4266
Branch Coverage: 88.52%
Branches in Coverage %: Yes
Coverage Strength: 363.12 hits per line

💛 - Coveralls

@mrholek
mrholek merged commit bdc7a12 into v6-dev Aug 7, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants