FormidableLabs / radium

A toolchain for React component styling.
http://formidable.com/open-source/radium/
MIT License
7.39k stars 308 forks source link

Flexbox bug in IE10 when used with media queries – `!important` missing #621

Open tpreusse opened 8 years ago

tpreusse commented 8 years ago

-ms-flex-preferred-size is missing !important within the media query style tag.

Not sure if it's a inline-style-prefixer or Radium issue. But I assume Radium adds !important to ensure the media query overwrites the inline styles.

Example

var React = require('react');

var Radium = require('radium');
var {StyleRoot} = Radium;

const Flex = Radium(() => {
  var child = {
    padding: 10,
    flex: '1 100%'
  };
  var aside = {
    '@media (min-width: 600px)': {
      flex: '1 auto'
    }
  };
  var main = {
    '@media (min-width: 800px)': {
      flex: '3 0px',
      order: 2
    }
  };

  return (
    <div style={{display: 'flex', flexFlow: 'row wrap', textAlign: 'center'}}>
      <div style={[child, {background: 'tomato'}]}>Header</div>
      <div style={[child, main, {background: 'deepskyblue'}]}>
        <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
      </div>
      <div style={[child, aside, {background: 'gold', '@media (min-width: 800px)': {order: 1}}]}>Aside 1</div>
      <div style={[child, aside, {background: 'hotpink', '@media (min-width: 800px)': {order: 3}}]}>Aside 2</div>
      <div style={[child, {background: 'lightgreen', '@media (min-width: 800px)': {order: 4}}]}>Footer</div>
    </div>
  );
});

var App = React.createClass({
  render: function () {
    return (
      <StyleRoot>
        <Flex />
      </StyleRoot>
    );
  }
});
App = Radium(App);

module.exports = App;

Produced CSS in IE10

@media all and (min-width:800px)
{
.rmq-12e9603d {
    -ms-flex-positive: 3 !important; -ms-flex-negative: 0 !important; -ms-flex-preferred-size: 0px; -ms-flex-order: 2 !important;
}
}
@media all and (min-width:600px)
{
.rmq-18943b2 {
    -ms-flex-positive: 1 !important; -ms-flex-negative: 0 !important; -ms-flex-preferred-size: auto;
}
}
@media all and (min-width:800px)
{
.rmq-39c0cb0 {
    -ms-flex-order: 1 !important;
}
}
@media all and (min-width:800px)
{
.rmq-1dc36ff2 {
    -ms-flex-order: 3 !important;
}
}
@media all and (min-width:800px)
{
.rmq-112718d5 {
    -ms-flex-order: 4 !important;
}
}

Make sure to use document.querySelectorAll('style')[0].styleSheet.cssText to debug style tags in IE10 – innerText, innerHtml and dev tools do not provide the latest rules.

Currently

actual

Desired

expected

alexlande commented 8 years ago

This is pretty weird, and isn't really an issue with Radium or inline-style-prefixer.

You can reproduce this without any javascript at all, here's a JSBin to demonstrate: http://output.jsbin.com/yayoce

When you set -ms-flex with !important in IE10, the !important isn't respected in the -ms-flex-preferred-size that IE10 uses as the computed style.

screen shot 2016-03-25 at 12 50 21 pm

To fix your issue right now, you could use individual flex properties instead of the shorthand, which would work around this.

I'm not completely sure if Radium or inline-style-prefixer should care about this case. We could always split flex rules into individual declarations. Part of me thinks we should just document it as a known edge case since it's not our bug, but given that we rely on !important it might be worth fixing.

/cc @ianobermiller @rofrischmann @tptee

ianobermiller commented 8 years ago

+1 on the docs

tpreusse commented 8 years ago

Thanks for looking into this.

Interesting so the browser expands -ms-flex to those multiple styles? I thought inline-style-prefixer would go from flex to the "IE long form".

And because it works in aphrodite with inline-style-prefixer I assumed it's Radium specific but it actually just works there because both style (outside and inside the media query) are missing !important and are in a style tag (no need to force it).

alexlande commented 8 years ago

Yeah, it's pretty wacky.

I'm conflicted on this one. It's a weird edge case, which makes me think let's document it and move on, but it's also one that might be relatively common due to our necessary !important usage, which makes me think we should work around it so that users don't have to.

zdfs commented 8 years ago

I'm running into something similar when using -webkit-background-clip. If the property value is text, the property shows up, but when using text !important, it gets stripped out completely.