Styled-jsx: How to style non-DOM components?

Created on 20 Dec 2016  路  7Comments  路  Source: vercel/styled-jsx

All of the examples only show how to style core DOM nodes in JSX, like <p>:

  <div>
    <p>only this paragraph will get the style :O</p>
    { /* you can include <Component />s here that include
         other <p>s that don't get unexpected styles! */ }
    <style jsx>{`
      p {
        color: red;
      }
    `}</style>
  </div>

Is it possible to use styled-jsx to pass styles into components, like <Button>? Having a hard time understanding how that would work, or how this library is a true solution to CSS without that? Would I need to require one of the other CSS-in-JS solutions to theme things?

Most helpful comment

Yes for sure. This is one way:

const Button = ({ large }) => (
  <button className={ large && 'large' }>
     { props.children }
     <style jsx>{`
        button {
          padding: 20px;
          background: #eee;
          color: #999
        }
        .large {
          padding: 50px
        }
     `}</style>
  </button>
)

Inline style for overrides is another.

All 7 comments

  1. <Button> would have its own <style jsx>. To customize components, we pass props which configure inline styles in addition to the static CSS
  2. To override 3rd-party components, many receive a class. You can pass an unprefixed class for that.

In general what we find is that you most likely pass properties like <Button large> and then toggle a class name, and your CSS contains both classes. This is much more performant than dynamic CSS, since the CSS gets parsed and compiled once, and toggling is much faster

Would be awesome to see an example in the Readme showing a property like primary or large inside a common "core" component like <Button> being toggled, to understand what the idiomatic way to do that with styled-jsx is. Right now the only mention of scoped classes was for targeting the root node, so it wasn't immediately obvious to me that I'd use a bunch of classes in a single <styled jsx> and then use something like classnames to toggle things on and off.

Yes for sure. This is one way:

const Button = ({ large }) => (
  <button className={ large && 'large' }>
     { props.children }
     <style jsx>{`
        button {
          padding: 20px;
          background: #eee;
          color: #999
        }
        .large {
          padding: 50px
        }
     `}</style>
  </button>
)

Inline style for overrides is another.

Added a section describing the two main techniques:
https://github.com/zeit/styled-jsx#dynamic-styles

@ianstormtaylor does it LGTY?

@rauchg yup that is perfect, thank you!

Hi. Correct me if I'm wrong, but this wouldn't work, unless we use global styles, right?

const Button = ({ href, onClick, children }) => {
  const Component = href ? 'a' : 'button';
  const params = href ? { href } : { onClick };
  return (
    <Component
      className="button"
      {...params}
    >
      {children}
      <style jsx>{`
      .button {
        display: block;
        border-radius: 1px;
        width: 100%;
      }
    `}</style>
    </Component>
  );
};
Was this page helpful?
0 / 5 - 0 ratings

Related issues

rauchg picture rauchg  路  25Comments

rauchg picture rauchg  路  18Comments

bernhardc picture bernhardc  路  15Comments

jacobmischka picture jacobmischka  路  28Comments

slaskis picture slaskis  路  16Comments