Build1 distinct publisher3 min readUpdated
A dev.to post shows how transition-duration: calc(infinity * 1s) makes a hover style stick without JavaScript. The paint changes; the DOM does not, and that is the whole tradeoff.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
A post from frontendfacile on dev.to documents a CSS trick for making a hover effect stick: give the base state an infinite transition duration and the interactive state a normal one, and the element never travels back [1][3]. That is the smallest available substitute for a very common JavaScript pattern, adding a class on pointer entry and never removing it, and it is worth knowing exactly what it gives up.
The mechanism depends on the fact that a transition runs in two directions: forward when the element enters `:hover` or `:focus`, and back to the base style when it leaves, with one `transition-duration` normally governing both [2]. The post splits them:
```css a, h1 { color: black; transition-property: color; transition-duration: calc(infinity * 1s); } a:hover, a:focus, h1:hover, h1:focus { color: red; transition-duration: 0.5s; } ```
The `calc()` is not decoration. According to the post, `transition-duration` requires a time in `s` or `ms`, and `infinity` is a valid CSS number but not a time on its own, so multiplying it by `1s` produces a duration [5]. Pointer in, the colour reaches red in 0.5s; pointer out, the return transition is scheduled for infinity, so in practice the element stays red [6].
Two notes on the framing. Despite the headline's "one line," the effect needs two declarations across two rules, one for the base duration and one for the hover duration [10]. And the post is explicit that this is not a toggle in the application sense: no state is stored, and the persistence is only the visual consequence of a return that is postponed indefinitely [7].
That second point is where the cost lands. The rules change nothing but `color` and `transition-duration` [4], so there is no attribute, no class, and no DOM change for anything else to read [12]. Nothing to submit with a form, nothing for a sibling selector to key off, nothing to restore after a re-render. The selector list also includes `:focus` [4], which means keyboard traversal latches too: tab across a page of links and every one you pass through stays in the hovered style, with no way back [11]. If you want a real persistent state that survives clicks, focus changes and keyboard navigation, the post itself points to `:checked` with input and label, `:target`, or JavaScript [8]. Its stated fit is narrower: demos, prototypes, playful microinteractions, and temporary highlights that do not need to be true at the state level [9].
What to watch: the post does not discuss browser support for `calc(infinity * 1s)`, nor what happens if the element's computed styles are recalculated while a nominally infinite transition is in flight [13]. Test the latch under a media query change, a class swap on an ancestor, and a framework re-render before you ship it anywhere the highlight is meant to mean something. If it has to mean something, use the checkbox.
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
A dev.to post from frontendfacile, titled in Italian as making a hover permanent with a single line of CSS and without JavaScript, describes a trick using transition-duration and calc() so that the element's return to its base state takes 'infinite' time.
The post explains a transition has two moments: the forward change when the element enters :hover or :focus, and the return to the base style when it leaves; normally a single transition-duration applies in both directions.
The technique sets an infinite duration in the base state, so the return never occurs (it requires infinite time), and a normal duration such as 0.5s in the :hover / :focus state to animate the forward change.
Per the post: on hovering the element it goes to red in 0.5s; on leaving it should return to the base colour, but the return transition lasts infinity, so in practice it stays red.
The post's own caveat: this is not a persistent toggle in the application sense, because no state is being stored; it is a visual effect based on the return being postponed indefinitely.
The post's minimal example is: a, h1 { color: black; transition-property: color; transition-duration: calc(infinity * 1s); } and a:hover, a:focus, h1:hover, h1:focus { color: red; transition-duration: 0.5s; }
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Self-contained snippet, single unverified source
The mechanism is fully specified in the source with runnable CSS and a correct explanation of why calc() is needed to turn the infinity keyword into a time value, which makes the claim inspectable. But evidence stops there: one publisher, one author, no spec citation, no browser support data, and no discussion of style recalculation while the pending infinite return transition exists. Nothing here has been independently reproduced within the cluster.
No adoption signal in supplied sources
The cluster contains no release, deployment, usage disclosure, benchmark or other adoption event. The source is a tutorial about a CSS pattern and reports no instances of the technique shipping anywhere, so adoption cannot be scored without inventing facts.
Framing outruns the mechanism, though the author self-corrects
Positive but moderate. The headline sells a 'permanent' hover in 'one line of CSS' when the published recipe needs two transition-duration declarations across two rules, and 'permanent' is really an indefinitely postponed return with no stored state. The overstatement is partly offset in-body: the author flags that nothing is memorised, scopes the trick to demos and playful microinteractions, and names :checked, :target and JS as the correct tools for real state. What remains unbalanced is the silence on browser support and on :focus latching styles for keyboard users.
Mild self-promotion, no commercial stake
The post is a syndicated copy that closes by linking to the author's original article on his own site (frontendfacile.it), so there is an audience-building incentive and a headline written for clicks ('permanent', 'one line', 'without JavaScript'). There is no vendor, product, funding or licensing interest visible in the supplied material, and the author volunteers the technique's central limitation, which argues against strong distortion.
Claims are clear but singly sourced
Confidence is moderate. What the post says is unambiguous and its mechanism is small enough to be verified by inspection, so the canonical claims about the technique are secure. Confidence is held down by the cluster having exactly one publisher, zero adoption evidence, and no compatibility or recalculation information, which leaves the practical reliability of the trick unresolved.
build
The third answer: a dead-code tool allowed to say "not traced yet"1 distinct publisher
build
Your overlay is in the wrong coordinate space, and scroll is the tell1 distinct publisher
build
Container queries pay off component by component, not as a breakpoint purge1 distinct publisher
build
A 200-post blog audit found three defects, none of them visible on the author's own screen1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 14, 2026