How are you using Styled Components?
Nitzan Hen

Nitzan Hen @nitzanhen

About: Full stack developer & undergrad student of Mathematics; very passionate about both. Enthusiastic about learning, teaching, writing, open source, linguistics and more.

Joined:
Aug 10, 2021

How are you using Styled Components?

Publish Date: Nov 27 '21
65 24

Hello!
Have you ever used style-components in a React project before? And, more generally, what are your thoughts of it?

I'm asking because we want to implement styled-components support for Agrippa, the React CLI for component generation! In fact, it's the second issue opened on our GitHub repository!

However, I unfortunately have never personally used styled-components in a production project, and while I did propose an implementation on the GitHub issue, it would definitely be better to hear an experienced input.

From what I've seen, different teams have used this tool in many different ways over the years.
Therefore, I'd love to hear your own experience with it, and how you're using it!
Even if you've used it in a small project or casually, speak up! the more experiences, the better - we could all learn something new as a result.

If you prefer, you're also more than welcome to join the discussion on the mentioned GitHub issue at Add support for styled components, and join the Agrippa community!

Thank you for your time!

(Cover image is from styled-components' docs, at https://styled-components.com/meta.png)

Comments 24 total

  • Nitzan Hen
    Nitzan HenNov 27, 2021

    My implementation, in a simple example, goes something like this:

    import React from 'react';
    import styled from 'styled-components'; // 1. Import styled-components
    
    const AComponentStyled = styled(AComponent)`` // 2. Create styled variant
    
    function AComponent({ className }) { // 3. Receive className prop
    
      //...
    
      return (
        // 4. Pass className prop to JSX root
        <div className={className} /> 
      )
    } 
    
    export default AComponentStyled; // 5. Export styled variant
    
    Enter fullscreen mode Exit fullscreen mode

    Of course, the CLI generalizes this example to any component, and supports Typescript, using a named export (instead of the default export), etc.

    Most examples out there used the component-specific variants, such as styled.h1, but to me it felt that the more generic styled(component) are more useful - however if you are using the component-specific variants, do tell!

    • Ben Heidemann
      Ben HeidemannNov 29, 2021

      I use component specific variants quite regularly. Generally, as long as it's a simple component consisting of a single styled element (e.g. a div) I will use the component specific variants as I find them easier to read. However, I work a lot with Material UI and when styling MUI components I use styled(MuiComponent). Do you use the styled(Component) syntax you describe above for consistency or is there another reason?

      • Nitzan Hen
        Nitzan HenNov 29, 2021

        This makes a lot sense!

        I actually have used Material UI a lot as well, and I think I originally tended towards the generic styled(Component) syntax simply because I was used to MUI's way of doing things - where the definition of the styles for a component is closely tied to the component itself (at least that's how it was when MUI still used JSS).

        However, I'm realizing more and more how useful and neat the tag-specific variants are! Cheers!

  • Lars Ejaas
    Lars EjaasNov 27, 2021

    Yeah, I have worked quite a bit with styled components actually. It is hands down my prefered way of styling things in React projects.
    It can be a bit difficult to set up with TypeScript and the syntax for variables is a bit verbose - but it works extremely well!

    • Lars Ejaas
      Lars EjaasNov 27, 2021

      I prefer to write the styling in a seperate file and import the components where I need them. I normally use a global style file for some basic styles and then use *.style.ts files for anything else. Futhermore I will set up varous themes in seperate files.
      I also tend to seperate stuff like breakpoints, margins, etc. that I use across themes into seperate files. I then import them where needed:

      import {
        breakPoints,
        margins,
      } from "styles/...";
      
      Enter fullscreen mode Exit fullscreen mode

      Regarding variables I tend to use destructuring when refering to props in styling:

      background-color: ${({ theme }) => theme.color.backgroundSecondary};
      
      Enter fullscreen mode Exit fullscreen mode

      You can also refer to props on the component like this:

      type CloseButtonProps = {
        modalType: TmodalType;
      };
      
      export const Closebutton = styled.button<CloseByttonProps>`
        position: absolute;
        right: ${(props) => (props.modalType === "search" ? "10px" : "16px")};
        ...
      
      Enter fullscreen mode Exit fullscreen mode
      • Nitzan Hen
        Nitzan HenNov 27, 2021

        Thanks!! This is really helpful info, and seems like a good pattern.

        Just to make sure I understand correctly, a typical component X's styles would be defined in X.style.ts/X.styles.js? And styles in that file would typically be declared using the tag-specific variants (e.g. styled.div, styled.h1)?

        Also, based on your experience, is declaring styled-components styles inside the component file (X.tsx) itself a standard practice? Or do most developers use separate files for them (like you do)?

        Lastly, do you perhaps have an example repo (yours or anyone else's) following this pattern? I'd love to have one as a point of reference.

        Thanks again!

        • Lars Ejaas
          Lars EjaasNov 27, 2021

          Hi Nitzan

          I only have an older repo to share, and honestly I would probably refactor the code a bit today, but feel free to take a look at it at: github.com/LarsEjaas/bruce-willis-app

          It's a small page/web app - it's live here at bruce-willis.rocks/en

          I am unsure that there is a best practice regarding separating code into separate files or not, but I like to do it this way. We use the same approach in the team where I work.

          Let's say I am doing an "awesome button"

          Then I would create a folder named AwesomeButton in the components folder.

          This would contain:

          AwesomeButton.tsx for the functional component,
          AwesomeButton.styles.ts for the styles,
          AwesomeButton.test.tsx for the tests and maybe
          Awesome.stories.tsx if you use storybook.

          Furthermore I would make an index.ts file where I would export the functional component like this:

          export {default} from AwesomeButton.tsx
          
          Enter fullscreen mode Exit fullscreen mode

          This way I can import my AwesomeButton component like this inside my project:

          import AwesomeButton from 'components/AwesomeButton'
          
          Enter fullscreen mode Exit fullscreen mode

          I think this pattern works well for large projects.

          • Lars Ejaas
            Lars EjaasNov 27, 2021

            Ahh, missed the part regarding tag-specific variants:

            I use both of these:

            export const StyledHeadline = styled.h1`
             //...styles
            `
            
            Enter fullscreen mode Exit fullscreen mode

            and

            import UnstyledComponent from 'components/...'
            
            export const StyledComponent = styled(UnstyledComponent)`
              //...styles
            `
            
            Enter fullscreen mode Exit fullscreen mode
            • Nitzan Hen
              Nitzan HenNov 28, 2021

              Thanks a lot for your detailed response!!!
              This will be of great help to me.

              • Lars Ejaas
                Lars EjaasNov 28, 2021

                Ahh, you are welcome! Feel free to drop me a message if something is difficult with Styled Components. It can be a bit difficult at first...

      • АнонимDec 1, 2021

        [deleted]

        • Lars Ejaas
          Lars EjaasDec 1, 2021

          Hmm, I really love this. However, I tried it and couldn't make it work. Do you need a workaround when using several different themes? I am unsure how this would work?

          • АнонимDec 1, 2021

            [deleted]

            • Lars Ejaas
              Lars EjaasDec 1, 2021

              Yeah, that makes sense! But I need to do some rework on the way I implement themes in styled components. Would like to optimize my workflow further, and your idea using lodash is really great, I defininitely need to include this!

  • Andrey Gurtovoy
    Andrey GurtovoyNov 28, 2021

    I use styled components gritting my teeth and getting nervous every time when I have to come into contact with it. I recommend that you do tooling, because right now it works very sadly in vscode sublime-text and and elsewhere. problems in the absence emmet, error-free work stylelint , and other nightmares. get busy with tools at last!

  • Nipuna Dodantenna
    Nipuna DodantennaNov 28, 2021

    Styled components are cool until it starts to affect other components

    • Lars Ejaas
      Lars EjaasNov 28, 2021

      @nipuna what issues have you come across? I haven't really experienced anything like that?

  • Jkierem
    JkieremNov 28, 2021

    Mostly for small reusable components. I try to keep it simple with styled components and not abuse them. I moved away from them for css heavy projects. Also theming is really easy so that is something I always use. I normally don't use all the features like style extension. I try to stay on the basic parts of the lib as the advanced features add a bit of complexity that make them harder to use in large code bases

    • Nitzan Hen
      Nitzan HenNov 28, 2021

      Good to know! I'll try to keep the implementation simple.

      If I may ask, what do you use for CSS heavy projects?

      • Jkierem
        JkieremNov 29, 2021

        Css modules with Sass or just Sass with a style loader so that I can import it in js.

  • RexGalilae
    RexGalilaeNov 28, 2021

    CSS modules is the cleanest approach for me.

    Styled components respect no separation of concerns and are verbose

    • Nitzan Hen
      Nitzan HenNov 28, 2021

      I'm actually a big fan of CSS modules too!
      However, as far as I can tell there are many developers who use styled-components, so I'd like to have support for it in Agrippa (it already has CSS modules by default, btw).

  • Kavindu Santhusa
    Kavindu SanthusaNov 29, 2021

    Both styled-components and emotion.js are using stylis.js to parse styles. So personally I prefer goober.js which is less than 1kb

    But please check the benchmarks before you change your library.

    Tip: use bundlephobia.com to inspect the size of styled-components

  • Justice Otuya
    Justice OtuyaNov 29, 2021

    so how i use styled components is that the main container in the component is a styled component and everything inside the components are normal classes,

    example

    COMPONENT.TSX
    const Container = ({...props}) => {
    
    return (<StyledContainer props={currentColor,...propsIWantToUseInTheCSS}>
                  <div className="box__red_or_blue">
                 ......
                  </div>
              </StyledContainer>)
    }
    
    Enter fullscreen mode Exit fullscreen mode
    COMPONENT.STYLE.TS
    export const StyledContainer = styled.div({currentColor:string}) => {
    //style here are for styling the component itself, then you can add classes which are elements inside the styled component
    
    padding:30px;
    margin:20px
    ....
    
    //element with a className inside the styled component, the styled component takes a  color props and passes it to the className
    
    .box__red_or_blue {
    color: ${props} => props.currentColor === "red" ? "red" : "blue"}
    }
    
    }
    
    Enter fullscreen mode Exit fullscreen mode

    since styled-components generate classes for each component, it will be hard to get clashes as the elements with classes and encapsulated and embedded with the styled component

Add comment