因?yàn)?styled-components 允許使用任意的輸入作為插值使用,我們必須謹(jǐn)慎處理輸入使其無(wú)害.使用用戶輸入作為樣式可能導(dǎo)致用戶瀏覽器中的CSS文件被攻擊者替換.
以下這個(gè)例子展示了糟糕的輸入導(dǎo)致的 API 被攻擊:
// Oh no! The user has given us a bad URL! const userInput = '/api/withdraw-funds' const ArbitraryComponent = styled.div` background: url(${userInput}); /* More styles here... */ `
請(qǐng)一定謹(jǐn)慎處理!這雖然是一個(gè)明顯的例子,但是CSS注入可能隱式的發(fā)生并且產(chǎn)生不良影響.有些舊版本的 IE 甚至?xí)?url 聲明中執(zhí)行 JavaScript.
There is an upcoming standard to sanitize CSS from JavaScript有一個(gè)即將推出的標(biāo)準(zhǔn),可以用于無(wú)害化 JavaScript 中的 CSS, CSS.escape. 這個(gè)標(biāo)準(zhǔn)還沒有被瀏覽器很好的支持 .
如果想將 styled-components 和現(xiàn)有的 CSS 共同使用,有很多實(shí)現(xiàn)的細(xì)節(jié)必須注意到.
styled-components 通過(guò)類生成實(shí)際的樣式表,并通過(guò)className prop將這些類附加到響應(yīng)的 DOM 節(jié)點(diǎn). 運(yùn)行時(shí)它會(huì)被注入到 document 的 head 末尾.
使用styled(MyComponent) 聲明, MyComponent 卻不接收傳入的 className prop, 則樣式并不會(huì)被呈現(xiàn). 為避免這個(gè)問題,請(qǐng)確保組件接收 className 并傳遞給 DOM 節(jié)點(diǎn):
class MyComponent extends React.Component { render() { // Attach the passed-in className to the DOM node return <div className={this.props.className} /> } }
對(duì)于已存在類名的組件,可以將其余傳入的類合并:
class MyComponent extends React.Component { render() { // Attach the passed-in className to the DOM node return <div className={`some-global-class ${this.props.className}`} /> } }
將styled-components類與全局類混用,可能會(huì)導(dǎo)致出乎意料的結(jié)果.如果一個(gè)property在兩個(gè)類中被定義且兩個(gè)類的優(yōu)先級(jí)相同,則后者會(huì)覆蓋前者.
// MyComponent.js const MyComponent = styled.div`background-color: green;`; // my-component.css .red-bg { background-color: red; } // For some reason this component still has a green background, // even though you're trying to override it with the "red-bg" class! <MyComponent className="red-bg" />
上述例子中styled-components類的樣式覆蓋了全局類,因?yàn)閟tyled-components在運(yùn)行時(shí)向<head>末尾注入樣式.
一種解決方式是提高全局樣式的優(yōu)先級(jí):
/* my-component.css */ .red-bg.red-bg { background-color: red; }
如果在一個(gè)不能完全控制的頁(yè)面上部署styled-components,可能需要采取措施確保 component styles 不與 host page 上其他樣式?jīng)_突.
常見的問題是優(yōu)先級(jí)相同,例如 host page 上持有如下樣式:
body.my-body button { padding: 24px; }
因?yàn)槠浒粋€(gè)類名和兩個(gè)標(biāo)簽名,它的優(yōu)先級(jí)要高于 styled component 生成的一個(gè)類名的選擇器:
styled.button` padding: 16px; `
沒有讓 styled component 完全不受 host page 樣式影響的辦法.但是可以通過(guò)babel-plugin-styled-components-css-namespace
來(lái)提高樣式的優(yōu)先級(jí), 通過(guò)它可以為 styled components 的類指定一個(gè)命名空間. 一個(gè)好的命名空間,譬如#my-widget,可以實(shí)現(xiàn)styled-components 在 一個(gè) id="my-widget"的容器中渲染, 因?yàn)?id 選擇器的優(yōu)先級(jí)總是高于類選擇器.
一個(gè)罕見的問題是同一頁(yè)面上兩個(gè)styled-components實(shí)例的沖突.通過(guò)在 code bundle 中定義 process.env.SC_ATTR 可以避免這個(gè)問題. 它將覆蓋 <style> 標(biāo)簽的data-styled屬性, (v3 及以下版本使用 data-styled-components), allowing each styled-components instance to recognize its own tags.
更多建議: