reactjs / reactjs/react.dev

[Suggestion]: Add note with some CSS selector side effects depending on DOM presence to `Activity` troubleshooting

未關閉
#8,354 1 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

type: documentation
主要語言
JavaScript
星號
11.8k
分支
7.9k
平均合併
1 天 11 小時
30 天內合併 PR
11

描述

Summary

Docs in Activity troubleshooting section,

My hidden components have unwanted side effects, lists <video>, <audio>, and <iframe> as common examples of side effects, but it does not yet cover the category of CSS selectors.

Some common CSS selectors, such as :has() and :is(), may continue to match after the content is hidden by <Activity>, leading to unexpected residual styles.

Page

https://react.dev/reference/react/Activity#troubleshooting

Details

Description

<Activity mode="hidden"> is designed to preserve DOM nodes (applying display: none), which is an intentional design choice. However, most CSS selectors only check the DOM structure and do not consider whether the element is actually visible.

This aligns with the existing explanation in the documentation:

"since a hidden component's DOM is not destroyed, any side effects from that DOM will persist, even after the component is hidden."

The persistent matching of CSS selectors is the exact same kind of DOM side effect, just occurring at the CSS layer,

But, docs doesn't have specific guidance for this type of CSS side effect on DOM. I have some problem to ask for suggestions:

  • Does the useLayoutEffect cleanup pattern mentioned in the docs for <video> also apply to handling this kind of CSS side effect?
  • Or is this a known limitation of the <Activity> design that should be explicitly stated in the documentation so developers are aware of it in advance?

Affected Selectors

:has()

/* ⚠️ Still applies after PageA is hidden by Activity */
body:has([data-has="a"]) .banner { background: red; }

:is() / :where()

/* ⚠️ Hidden elements are still matched, causing adjacent sibling styles to persist */
:is(section[data-sibling="a"]) ~ .footer { color: red; }
:where([data-page="a"]) .title { font-weight: bold; }

Demo

https://github.com/fufuShih/demo-react-activtiy-problem

The demo have two toggle modes (unmount / activity) and two page comps (A / B):

  • HasDemo: Uses body:has([data-has="a"]) .banner to detect if Page A is visible. After switching to Page B, the banner should revert to its default color.
  • SiblingDemo: Uses :is(section[data-sibling="a"]) ~ .footer to detect adjacent sibling elements. After switching to Page B, the footer should revert to its default color.

Both behave normally in unmount mode. However, when switched to activity mode, Page A is hidden by <Activity mode="hidden"> but remains in the DOM, causing both selectors to continue matching and preventing the styles from resetting.

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

從 Activity 的疑難排解章節和連結的示範儲存庫開始,搭配 :has()、:is() 和 :where() 範例檢視現有的持續性 DOM 副作用說明。確認 CSS 選擇器匹配的預期指引,然後使用準確的註記和解釋該行為的範例更新疑難排解文件。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
css, react
領域
documentation
Issue 類型
文件
難度
3/5
預估耗時
1-2 天
活躍度
冷清
描述清晰度
基本清楚
新手友好度
52/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。