Next.js中<style jsx>如何使用条件语句实现条件样式?
实现方式
你可以根据项目兼容需求选以下两种方案,都能完美适配<style jsx> + TailwindCSS的技术栈,不需要改动现有Tailwind类名。
方案1:纯CSS实现(推荐,现代浏览器原生支持)
直接用CSS原生的:has()伪类即可,这个选择器的作用就是匹配「包含指定子元素」的父元素,完全匹配你需要的判断逻辑,不需要写任何额外JS代码。
直接把你原来<style jsx>中的CSS替换为以下内容即可:
/* 首个p标签默认样式,无iframe时padding-top为0 */ .description_content p:first-child { position: relative !important; overflow: hidden !important; width: 100% !important; padding-top: 0 !important; } /* 当首个p标签内存在iframe子元素时,覆盖padding-top值 */ .description_content p:first-child:has(iframe) { padding-top: 56.25% !important; } /* iframe自适应样式保持不变 */ .description_content p iframe { position: absolute !important; top: 0 !important; left: 0 !important; bottom: 0 !important; right: 0 !important; width: 100% !important; height: 100% !important; margin: 0 auto !important; }
兼容性说明:
:has()目前已支持Chrome 105+、Firefox 121+、Safari 15.4+,覆盖95%以上的全球用户浏览器场景,C端项目如果没有极低版本浏览器兼容要求可以直接用。
方案2:JS判断+类名控制(兼容所有浏览器)
如果需要兼容更老版本的浏览器,可以在内容渲染完成后通过JS判断DOM结构,动态给符合条件的p标签加类名,再通过类名控制样式。
对应JSX代码调整如下:
import { useEffect, useRef } from 'react' function ProductDetail({ productDetail }) { const descContainer = useRef(null) // 每次富文本内容更新后检查DOM结构 useEffect(() => { const container = descContainer.current if (!container) return const firstParagraph = container.querySelector('p:first-child') // 首个p标签存在且内部包含iframe时,添加标记类 if (firstParagraph?.querySelector('iframe')) { firstParagraph.classList.add('has-iframe') } }, [productDetail?.description]) return ( <div ref={descContainer} className="mt-20 description_content text-center flex flex-col justify-center items-center text-gray-500 mx-5" dangerouslySetInnerHTML={{ __html: productDetail?.description, }} > <style jsx>{` .description_content p:first-child { position: relative !important; overflow: hidden !important; width: 100% !important; padding-top: 0 !important; } /* 匹配带标记类的p标签 */ .description_content p:first-child.has-iframe { padding-top: 56.25% !important; } .description_content p iframe { position: absolute !important; top: 0 !important; left: 0 !important; bottom: 0 !important; right: 0 !important; width: 100% !important; height: 100% !important; margin: 0 auto !important; } `}</style> </div> ) }
这个方案没有任何浏览器兼容问题,逻辑也很直观:默认给首个p标签设置padding-top: 0,只有检测到里面有iframe的时候才加类名,把padding改成视频比例需要的56.25%。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

