为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