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