如何处理 Next.js 中不受支持的 CSS 属性或在 Chakra-UI 中使用 @supports 指令
How to handle unsupported CSS properties in Next.js or use @supports directives in Chakra-UI
我正在使用 React component 根据是否支持 CSS backdrop-filter
指令使用不同的不透明度值:
background={(() => {
const opacity = isBackdropFilterSupported() ? 0.75 : 0.98
return (
`linear-gradient(
180deg, rgba(76, 63, 143, ${opacity}) 62.76%,
rgba(184, 169, 255, ${opacity}) 100%
)`
)
})()}
问题是网站是使用 Next.js 在服务器端生成的。 CSS.supports('backdrop-filter', 'blur(1px)')
returns false
在服务器上,因此无论客户端属性如何,该值始终为 false
。
一种解决方案是使用 CSS,例如:
.drawer {
--opacity: 0.75;
background: linear-gradient(
180deg, rgba(76, 63, 143, var(--opacity)) 62.76%,
rgba(184, 169, 255, var(--opacity)) 100%
);
}
@supports not (backdrop-filter: blur(1px)) {
.drawer { --opacity: 0.98; }
}
这应该由客户端解释并避免服务器端呈现问题,但我没有发现关于如何将这种样式集成到它所基于的 Chakra-UI 中的指示。
我在原来的 post 中没有提到它,但我收到了如下错误:Prop id did not match. Server: "toggle--gxfg3t7xwo" Client: "toggle--ki0j10p2l"
。
原来这意味着浏览器生成的 DOM 与 Next.js 生成的 DOM 不匹配。发生这种情况时 Next.js 放弃尝试重新水合文档,这就是我获取服务器呈现值的原因。
解决方案是使用挂钩来确定组件何时安装(这只发生在客户端)。那个钩子看起来像:
export const useMounted = () => {
// https://www.joshwcomeau.com/react/the-perils-of-rehydration/
const [hasMounted, setHasMounted] = React.useState(false);
React.useEffect(() => {
setHasMounted(true);
}, []);
return hasMounted;
};
然后不透明度的确定变成:
const hasMounted = useMounted()
⋮
const opacity = hasMounted && isBackdropFilterSupported() ? 0.75 : 0.98
我正在使用 React component 根据是否支持 CSS backdrop-filter
指令使用不同的不透明度值:
background={(() => {
const opacity = isBackdropFilterSupported() ? 0.75 : 0.98
return (
`linear-gradient(
180deg, rgba(76, 63, 143, ${opacity}) 62.76%,
rgba(184, 169, 255, ${opacity}) 100%
)`
)
})()}
问题是网站是使用 Next.js 在服务器端生成的。 CSS.supports('backdrop-filter', 'blur(1px)')
returns false
在服务器上,因此无论客户端属性如何,该值始终为 false
。
一种解决方案是使用 CSS,例如:
.drawer {
--opacity: 0.75;
background: linear-gradient(
180deg, rgba(76, 63, 143, var(--opacity)) 62.76%,
rgba(184, 169, 255, var(--opacity)) 100%
);
}
@supports not (backdrop-filter: blur(1px)) {
.drawer { --opacity: 0.98; }
}
这应该由客户端解释并避免服务器端呈现问题,但我没有发现关于如何将这种样式集成到它所基于的 Chakra-UI 中的指示。
我在原来的 post 中没有提到它,但我收到了如下错误:Prop id did not match. Server: "toggle--gxfg3t7xwo" Client: "toggle--ki0j10p2l"
。
原来这意味着浏览器生成的 DOM 与 Next.js 生成的 DOM 不匹配。发生这种情况时 Next.js 放弃尝试重新水合文档,这就是我获取服务器呈现值的原因。
解决方案是使用挂钩来确定组件何时安装(这只发生在客户端)。那个钩子看起来像:
export const useMounted = () => {
// https://www.joshwcomeau.com/react/the-perils-of-rehydration/
const [hasMounted, setHasMounted] = React.useState(false);
React.useEffect(() => {
setHasMounted(true);
}, []);
return hasMounted;
};
然后不透明度的确定变成:
const hasMounted = useMounted()
⋮
const opacity = hasMounted && isBackdropFilterSupported() ? 0.75 : 0.98