2015-04-03 15 views
7

Mi piace molto il modo in cui React purifica gli eventi per te, quindi sono stato sorpreso di non aver prefisso gli stili CSS anche per il tuo!Prefixing per gli stili di flexbox per React

In ogni modo, ho iniziato a implementare la mia prefixer di base come questo:

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; 
}; 

Ma poi ho realized a big problem, Reagire utilizza un oggetto per gli stili e come prefisso adeguatamente il FlexBox, è necessario anteporre i valori, non il proprietà. Così, non riesco a comprendere tutte le seguenti stili allo stesso tempo:

.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+ */ 
} 

Delle idee come ottenere intorno a questo?

+1

La funzionalità di stile in linea è limitata oggi. Suggerirei semplicemente di usare una classe tradizionale/'className' in queste istanze. – WiredPrairie

+0

Oppure puoi rilevare le versioni del browser, ma le classi sono probabilmente la strada da percorrere. – FakeRainBrigand

+1

ah, capisco. Speravo di eliminare definitivamente i preprocessori CSS e CSS – Chet

risposta

0

Preferisco semplicemente mettere i miei stili in file separati e usare Autoprefixer.

È abbastanza facile da configurare con grunt e altri task runner e può indirizzare i browser specifici che si desidera supportare. Controlla il database di caniuse per mantenere le cose aggiornate e rimuove anche eventuali prefissi non necessari dal tuo css.

Può anche funzionare con meno e sass come post-compilatore.

Spero che questo aiuti!

2

Beh, in realtà con un trucco XSS davvero piccolo puoi facilmente ottenere ciò che desideri. Non aver paura, noi non andiamo al "lato oscuro";)

solo con l'aggiunta piccola funzione si può scrivere il CSS Reagire come questo

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' ] 
    } 
}); 

Tutte le proprietà si applicano allo stesso ordine come sono rappresentati in serie. Cool non è vero? :)

La funzione è di per sé è abbastanza semplice

// 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; 
} 

lavoro Demo:

https://jsfiddle.net/z5r53tdh/1/

PS: evento tu che utilizzando tecniche di XSS - noi non possono introdurre nuovi problema di sicurezza. Anche la protezione XSS standard funzionerà qui.

0

Il prefisso automatico del fornitore è stato dichiarato come qualcosa che il team React non desidera mantenere. Il che ha davvero senso, ogni app ha requisiti diversi su quali browser supportare. A seconda di quanto arriverà il supporto, il problema aumenta esponenzialmente.

credo Reagire, fuori dalla scatola dovrebbe avere il supporto per il fornitore preceduto valori, come è, con inline styling da solo non è possibile utilizzare FlexBox (Ciao web moderno !?).

Pensare che la sintassi letterale dell'oggetto abbia poco valore che non si possa trovare altrove e per lo più aggiunge attrito allo stile. Supponendo che abbia qualcosa a che fare con il supporto per la compatibilità con le versioni precedenti e che sia in grado di passare oggetti CSS come oggetti di scena e non voler forzare le persone su ES5/ES6 dove si può usare la sintassi di stringhe di template (``). Sarebbe piuttosto brutto se aggiungessimo stringhe insieme agli operatori + per incollare le nostre variabili in ... ma non è più necessario con i letterali dei template!(vedi mdn)

Non era soddisfatto di tutti gli altri pacchetti che hanno attaccato questo problema, quindi è stato il più semplice a dominarli tutti. Pacchetto chiamato Style It che ti consente semplicemente di scrivere CSS. Anche gli ambiti di sottostruttura automagically in modo da non essere nello spazio nomi globale con il tuo CSS (simile-ish a inline ma non così alta specificità). Simile agli stili in linea è anche XSS sicuro per impostazione predefinita (sfugge al CSS usando gli stessi usi di React), isomorfo e minuscolo a 1.8kb gzip. Oh e nessun passo di costruzione.

npm install style-it --save

funzionale Sintassi (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 Sintassi (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 tirato da A Complete Guide to Flexbox post di Chris Coyier.

Problemi correlati