cssinjs / jss

JSS is an authoring tool for CSS which uses JavaScript as a host language.
https://cssinjs.org
MIT License
7.07k stars 399 forks source link

[jss-nested] $ref inside of a @media should look up on the top level #446

Closed sergiop closed 5 years ago

sergiop commented 7 years ago

I have some problems (limits?) with nested rules in quite simple situations, for example:

JSX code:

<div
  className={cx(
    classes.myDiv,
    active && classes.active
  }
>
  <span className="classes.insetSpan">My text</span>
  <span className="classes.insetSpan2">My text</span>
</div>

As you can see, on wrapper div I have a conditional .active class, rendered only if active variable is equal to true.

JSS code: I want to give a particular styles to .insetSpan and .insetSpan2 only if .myDiv has class .active and only if the windows size is more than 600px.

active: {
  color: '#000',

  '@media (min-width: 600px)': {
    '& $insetSpan': {
      color: '#fff',
    },

    '& $insetSpan2': {
      color: 'red',
    },
  },
},

Rendered CSS:

.active-3103423013 {
  color: #000;
}
@media (min-width: 600px) {
  ..active-3103423013 .insetSpan-2315792072-2517626156 {
    color: #fff,
  }
  ..active-3103423013 .insetSpan2-4039903270-1886687286 {
    color: red,
  }
}

Note in the media query the doubled dot before active-3103423013 class, and the doubled hash after .insetSpan and .insetSpan2.

Can someone help me sto solve? Thanks.

kof commented 7 years ago

Looks like a bug. It will take some time to fix it. To fix it for you right now you have a bunch of other ways: for e.g. add active class conditionally to each insetSpan and define the @media query on the .active.

kof commented 7 years ago

I have got a different result than you on the repl http://cssinjs.org/repl. Currently $ref inside of a media query is looking for rules inside of the media query. It should be looking on the top level.

return {
  insetSpan: {
    width: 20,
  },
  insetSpan2: {
    width: 20,
  },  
  active: {
    color: '#000',

    '@media (min-width: 600px)': {
      '& $insetSpan': {
        color: '#fff',
      },

      '& $insetSpan2': {
        color: 'red',
      },
    },
  }
}
sergiop commented 7 years ago

Thanks @kof, effectively I was wrong, sorry. I experienced that output with this code (you can reproduce the error on repl).

return {
  insetSpan: {
    width: 20,
  },
  insetSpan2: {
    width: 20,
  },  
  active: {
    color: '#000',

    '& $insetSpan': {
      '@media (min-width: 600px)': {
        color: '#fff',
      }
    },

    '& $insetSpan2': {
      '@media (min-width: 600px)': {
        color: 'red',
      },
    },
  }
}

But this solution, with two nested media query, is more contorted than the first I posted. In my project I have solved it already as you suggested, because I needed to release a new functionality, thanks.

bstream commented 7 years ago

Another reproducible case:

return {
  button: {
    '&.otherclass': {
      '@media (min-width: 1024px)': {
        position: 'fixed',
        background: '#222',
      },

      '& + .clone': {
        '@media (min-width: 1024px)': {
          display: 'flex',
        },
      },
    },
  },
};

image Picture from http://cssinjs.org/repl

kof commented 5 years ago

Fixed in #900, please follow #795 for updates on release date.