styled-components / styled-components

Visual primitives for the component age. Use the best bits of ES6 and CSS to style your apps without stress 💅
https://styled-components.com
MIT License
40.49k stars 2.5k forks source link

[V2] :global(.ReactModalPortal) prefix render CSS rule with vendor prefix #552

Closed kopax closed 7 years ago

kopax commented 7 years ago

I am trying to customize react-modal.

This Component has to work with it's parents and body

body.ReactModal__Body--open > .ReactModalPortal > .modal > MyComponent

On 3 attempt, :global() injected twice correctly and last time fail because it adds a vendor prefix.

Version

2.0.0-5

Reproduction

http://www.webpackbin.com/NyNB1yG9z

You will have to open your developer console and copy the <style> element that own the css of MyComponent, then past it in a unminify in order to read it.

Steps to reproduce

I am trying to use :global() like this :

styled.div`
:global(body.ReactModal__Body--open) { overflow: hidden; }
:global(.modal) { ... }
:global(.ReactModalPortal) { ... }

Expected Behavior

but the css generated looks like this:

body.ReactModal__Body--open {
    overflow: hidden;
}

.modal {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1050;
    overflow: hidden;
    outline: 0;
    background-color: rgba(0, 0, 0, .5);
}

.ReactModalPortal .fade {
    opacity: 0;
    -webkit-transition: opacity .15s linear;
    transition: opacity .15s linear;
}

.ReactModalPortal .fade.show {
    opacity: 1;
}

.ReactModalPortal .collapse {
    display: none;
}

.ReactModalPortal .collapse.show {
    display: block;
}

.ReactModalPortal tr.collapse.show {
    display: table-row;
}

.ReactModalPortal tbody.collapse.show {
    display: table-row-group;
}

.ReactModalPortal .collapsing {
    position: relative;
    height: 0;
    overflow: hidden;
    -webkit-transition: height .35s ease;
    transition: height .35s ease;
}

Actual Behavior

but the css generated looks like this:

body.ReactModal__Body--open {
    overflow: hidden;
}

.modal {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1050;
    overflow: hidden;
    outline: 0;
    background-color: rgba(0, 0, 0, .5);
}

.bMEHgJ .ReactModalPortal .fade {
    opacity: 0;
    -webkit-transition: opacity .15s linear;
    transition: opacity .15s linear;
}

.bMEHgJ .ReactModalPortal .fade.show {
    opacity: 1;
}

.bMEHgJ .ReactModalPortal .collapse {
    display: none;
}

.bMEHgJ .ReactModalPortal .collapse.show {
    display: block;
}

.bMEHgJ .ReactModalPortal tr.collapse.show {
    display: table-row;
}

.bMEHgJ .ReactModalPortal tbody.collapse.show {
    display: table-row-group;
}

.bMEHgJ .ReactModalPortal .collapsing {
    position: relative;
    height: 0;
    overflow: hidden;
    -webkit-transition: height .35s ease;
    transition: height .35s ease;
}
thysultan commented 7 years ago

I think the bug surfaced because of :global() in a nested block, have patched this in stylis.

Though this does make it look like maybe styled-components is placing all the styles in a single nested block[1]. Since stylis supports flat css is there still a reason to do this cc @mxstbr @geelen ?

[1] https://github.com/styled-components/styled-components/blob/v2/src/models/ComponentStyle.js#L39

kopax commented 7 years ago

@thysultan I see. Apparently :global() only accept a valid selector as a parameter and the css content can only be real css value, no nested rules is that correct ?

I use utility for fade. I would be glad if I can use them in :global().

export function fade(enableTransitions = defaultProps['$enable-transitions'], transitionFade = defaultProps['$transition-fade']) {
  return `
    .fade {
      opacity: 0;
      ${transition(enableTransitions, transitionFade)}

      &.show {
        opacity: 1;
      }
    }
  `;
}

I am trying hard in order to have the correct ancestor starting the sibling within <MyComponent />., do you have an idea how I could pass that as valid class for .modal (.modal.fade.show)?

thysultan commented 7 years ago

... :global() only accept a valid selector as a parameter and the css content can only be real css value, no nested rules is that correct ?

@kopax That was a bug. I published a patch in v1.2.0, including the patch for apostrophes in a comment block.

mxstbr commented 7 years ago

Closing this as the bug is fixed, updating stylis and publishing a new version of s-c now.

Re: The injection stuff you have to ask Glen!