为React添加前缀flexbox样式
我真的很喜欢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;
};
但后来我意识到了一个很大的问题,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+ */
}
任何想法如何解决这个问题?
那么,实际上,使用非常小的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保护也可以在这里使用。
我更喜欢将我的样式放在单独的文件中并使用Autoprefixer。
使用grunt和其他任务运行器进行设置非常简单,并且可以定位您想要支持的特定浏览器。 它会检查caniuse数据库以保持最新状态,甚至会从您的css中删除任何不必要的前缀。
它也可以使用less和sass作为后期编译器。
希望有所帮助!
自动供应商前缀已被声明为React团队不想维护的内容。 这真的很有意义,每个应用程序都有不同的需求,以支持哪些浏览器。 取决于支持的程度,问题呈指数增长。
不要认为React应该支持供应商前缀值,因为单独使用内联样式,您不能使用flexbox(Hello modern web !?)。
认为对象文字语法几乎没有其他地方可能存在的价值,并且大多增加了样式的摩擦。 猜测它与向后兼容性支持有关,并且能够作为道具传递CSS对象,并且不希望强迫人们使用模板字符串(``)语法可以使用的ES5 / ES6。 如果我们将字符串与+
运算符一起添加以将变量粘贴到...中,那么将会非常难看,但对于模板文字,这不再必要! (见mdn)
对所有其他攻击这个问题的软件包感到不满,因此最简单的软件就可以统治所有这些问题。 名为Style的包它只是让你写CSS。 同样也是自动的子树范围,所以你不在CSS的全局名称空间中(类似于内联但不如特性高)。 与内联样式类似,默认情况下它也是XSS安全的(使用相同的libReact使用来转义您的CSS),是同构的,并且在1.8kb处很小。 哦,没有建设的一步。
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的Flexbox post完整指南中提取。
链接地址: http://www.djcxy.com/p/25335.html上一篇: Prefixing flexbox styles for React
下一篇: Is possible to communicate via Bluetooth PAN in iOS with tethered devices