我真的很喜欢React如何为你净化事件所以我很惊讶地发现他们也没有为你的CSS样式添加前缀!
无论如何,我开始实现我自己的基本前缀:
var prefixes = ["ms", "Moz", "Webkit", "O"];
var properties = [
'userSelect',
'transform',
'transition',
'transformOrigin',
'transformStyle',
'transitionProperty',
'transitionDuration',
'transitionTimingFunction',
'transitionDelay',
'borderImage',
'borderImageSlice',
'boxShadow',
'backgroundClip',
'backfaceVisibility',
'perspective',
'perspectiveOrigin',
'animation',
'animationDuration',
'animationName',
'animationDelay',
'animationDirection',
'animationIterationCount',
'animationTimingFunction',
'animationPlayState',
'animationFillMode',
'appearance',
'flexGrow',
];
function vendorPrefix(property, value) {
var result = {}
result[property] = value
if( properties.indexOf(property) == -1 ){
return result;
}
property = property[0].toUpperCase() + property.slice(1);
for (var i = 0; i < prefixes.length; i++) {
result[prefixes[i] + property] = value;
};
return result;
}
React.prefix = function(obj) {
var result = {};
for(var key in obj){
var prefixed = vendorPrefix(key, obj[key])
for(var pre in prefixed){
result[pre] = prefixed[pre]
}
}
return result;
};
但是我realized a big problem,React使用一个对象作为样式并适当地为flexbox添加前缀,你需要为值前缀,而不是属性。因此,我不能同时包含以下所有样式:
.page-wrap {
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER - IE 10 */
display: -webkit-flex; /* NEW - Chrome */
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
}
任何想法如何解决这个问题?
答案 0 :(得分:3)
嗯,实际上,通过非常小的XSS技巧,您可以轻松实现您想要的效果。不要害怕,我们不会去“黑暗面”;)
只需添加小功能,您就可以像这样编写React CSS
var divStyle = multipleValues({
color: 'white',
padding: '10px 20px',
// if you want property to have multiple values
// just write them all in the array
display: [
'-webkit-box',
'-webkit-flex',
'-ms-flexbox',
'flex'
],
background: ['red', 'blue'],
extraStyles: {
background: [ 'yellow', 'pink' ]
}
});
所有属性的应用顺序与数组中表示的顺序相同。酷不是吗? :)
它自己的功能非常简单
// function that will do a "magic" XSS-ish trick
function multipleValues(style) {
var result = {};
// feel free to replace for..in+hasOwnProperty with for..of
for (var key in style) {
if (style.hasOwnProperty(key)) {
var value = style[key];
if (Array.isArray(value)) {
// by adding semicolon at the begging we applying
// a trick that ofthen used in XSS attacks
result[key] = ';' + key + ':' + value.join(';' + key + ':');
} else if (typeof value === "object" && value !== null) {
// here we doing recursion
result[key] = multipleValues(value);
} else {
// and here we simply copying everything else
result[key] = value;
}
}
}
return result;
}
工作演示:
https://jsfiddle.net/z5r53tdh/1/
PS:我们使用XSS技术 - 我们不会引入任何新的安全问题。标准的XSS保护也适用于此。
答案 1 :(得分:0)
我更喜欢将我的样式放在单独的文件中并使用Autoprefixer。
使用grunt和其他任务运行器进行设置非常简单,并且可以定位您想要支持的特定浏览器。它会检查caniuse数据库以保持最新状态,甚至可以从您的CSS中删除任何不必要的前缀。
它也可以作为后编译器使用less和sass。
希望有所帮助!
答案 2 :(得分:0)
自动供应商前缀已被声明为React团队不想维护的内容。这真的很有意义,每个应用程序都有不同的要求,支持哪些浏览器。根据支持的距离,问题呈指数级增长。
认为React开箱即用应该支持供应商前缀值,因为仅使用内联样式就不能使用flexbox(Hello现代网络!?)。
认为对象文字语法几乎没有其他地方没有的价值,并且大多增加了样式的摩擦力。猜测它与向后兼容性支持有关,并且能够将CSS对象作为道具传递,并且不想强迫人们使用ES5 / ES6,其中可以使用模板字符串(``)语法。如果我们将+
运算符与字符串一起添加到我们的变量中,那将会非常难看......但是模板文字不再需要了! (见mdn)
对所有其他攻击此问题的软件包感到不满意,因此最简单的方法就是将它们全部排除在外。名为Style It的包只是让你编写CSS。同样也是自动子树范围,因此您不能使用CSS在全局名称空间中(类似于内联但不具有高特异性)。与内联样式类似,默认情况下它也是XSS安全的(使用相同的lib React使用它来逃避你的CSS),是同构的,并且在1.8kb gzip压缩时很小。哦,没有建立步骤。
npm install style-it --save
功能语法(JSFIDDLE)
import React from 'react';
import Style from 'style-it';
class Intro extends React.Component {
render() {
return Style.it(`
.flex-container {
padding: 0;
margin: 0;
list-style: none;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
justify-content: space-around;
}
.flex-item {
background: tomato;
padding: 5px;
width: 200px;
height: 150px;
margin-top: 10px;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
}
`,
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
</ul>
);
}
}
export default Intro;
JSX语法(JSFIDDLE)
import React from 'react';
import Style from 'style-it';
class Intro extends React.Component {
render() {
return (
<Style>
{`
.flex-container {
padding: 0;
margin: 0;
list-style: none;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
justify-content: space-around;
}
.flex-item {
background: tomato;
padding: 5px;
width: 200px;
height: 150px;
margin-top: 10px;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
}
`}
<ul class="flex-container">
<li class="flex-item">1</li>
<li class="flex-item">2</li>
<li class="flex-item">3</li>
<li class="flex-item">4</li>
<li class="flex-item">5</li>
<li class="flex-item">6</li>
</ul>
</Style>
}
}
export default Intro;
HTML / CSS取自Chris Coyier的A Complete Guide to Flexbox帖子。