Styled-jsx: Support for nested <style jsx>

Created on 18 Dec 2016  ·  18Comments  ·  Source: vercel/styled-jsx

I haven't had the need myself to do this, but it might be interesting to be able to sub-scope:

<div>
  {
    stuff.map((child) => (
      <div>
         <style jsx /> /* scoped to sub-div */
      </div>
    ))
  }
  <style jsx />
</div>
discussion

Most helpful comment

Use selectors, or separate into a different component.

Not supporting that might actually end up encouraging good practices 🤔
On Thu, Dec 22, 2016 at 4:13 AM Giuseppe notifications@github.com wrote:

This looks like a single component to me why would you group styles like
that instead of using selectors?


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/zeit/styled-jsx/issues/42#issuecomment-268787659, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAAy8WrvyJtY2dvPrgfCNFZXBxL9w8PDks5rKml5gaJpZM4LQPhJ
.

All 18 comments

I ran into this limitation my first try using styled-jsx 😄 Here's what I tried to do:

<div className='root'>
  <header className='banner'>
    ...
    <style jsx>{`
      .banner {}
    `}</style>
  </header>

  <style jsx>{`
    .root {}
  `}</style>
</div>

I wanted to group the styles related to <header> and its children inside the <header> element itself, but got a compilation error when trying to do so.

This looks like a single component to me why would you group styles like that instead of using selectors?

Because I was thinking of it as <style scoped>, and wanted to group styles with their relevant elements. This would also make it quicker to refactor later. The situation I had here was an entire document with a few main sections and my first thought was that I could co-locate my styles within the element tree.

Use selectors, or separate into a different component.

Not supporting that might actually end up encouraging good practices 🤔
On Thu, Dec 22, 2016 at 4:13 AM Giuseppe notifications@github.com wrote:

This looks like a single component to me why would you group styles like
that instead of using selectors?


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/zeit/styled-jsx/issues/42#issuecomment-268787659, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAAy8WrvyJtY2dvPrgfCNFZXBxL9w8PDks5rKml5gaJpZM4LQPhJ
.

yup also the following already works:

export default class {
  renderHeader() {
    return (
      <header className='banner'>
        ...
        <style jsx>{`
          .banner {}
        `}</style>
      </header>
    )
  }

  render () {
    return (
      <div className='root'>
        {this.renderHeader()}
        <style jsx>{`
          .root {}
        `}</style>
      </div>
    )
  }
}

Very cool. Great example @giuseppeg

I do like the restriction of not supporting nested <style jsx> contexts within a JSX syntax tree. And 👍 on the example of the style scoping working with separate JSX syntax trees that are composed together via render functions.

I think where this lands is probably a better error message for the example I posted above. I got an error about trying to iterate on a non-iterable iirc.

I was about to say the same. The key is having really good error messages (as always)

Refer to https://github.com/zeit/styled-jsx/issues/50#issuecomment-269089363
The first one is Preact and it work as expected, but NextJS seem to have problem there. For workaround I have to copy css to inner component and it's look not quite right to me.

I think I'm seeing this issue in a different way with HOC, so hopefully this is accounted for in a solution:

const Color = color => props => (
  <div className='color-container'>
    {color}
    <div>{props.children}</div>
    <style jsx>{`
      .color-container {
        display: inline-block;
        min-width: 50px;
        padding: 5px;
        margin-right: 10px;
        background-color: ${color};
      }
    `}</style>
  </div>
)

const Blue = Color('blue')
const Red = Color('red');

so performing <Red><Blue /></Red> should give me this:

screen shot 2017-05-28 at 2 54 52 am

but instead gives me:

screen shot 2017-05-28 at 2 54 17 am

@gravitypersists right now you can only use constants in styled-jsx. That's why you get two blue boxes. We'll make it possible to use dynamic values soon.

Hi there,
I am using nextjs 3 beta and I am getting this issue when I separate my styles into another file
as described in the link below:

https://www.npmjs.com/package/styled-jsx#keeping-css-in-separate-files

Thanks.

BR
Alex

Hi @alexofob, same problem here, and I just spend hours to find out what's cause the problem, it's really tricky.

If the

Closing since I think that in order to stay close to the ShadowDOM behavior we should support this. Styles within a component affect the entire component.

Was this page helpful?
0 / 5 - 0 ratings