{
  "doc": {
    "id": "app/component-testing/styling-components",
    "title": "Test your component's styles | Cypress Documentation",
    "description": "Learn how to test your component's markup, styles, and script logic with Cypress Component Testing",
    "section": "app",
    "source_path": "/llm/markdown/app/component-testing/styling-components.md",
    "version": "ce02913654e2655ee63448bdc92bb92c7b46a619",
    "updated_at": "2026-04-22T19:37:51.587Z",
    "headings": [
      {
        "id": "app/component-testing/styling-components#styling-components",
        "text": "Styling Components",
        "level": 1
      },
      {
        "id": "app/component-testing/styling-components#what-youll-learn",
        "text": " What you'll learn",
        "level": 5
      },
      {
        "id": "app/component-testing/styling-components#why-test-your-components-styles",
        "text": "Why Test Your Component's Styles?",
        "level": 2
      },
      {
        "id": "app/component-testing/styling-components#rendering-components-correctly",
        "text": "Rendering Components Correctly",
        "level": 2
      },
      {
        "id": "app/component-testing/styling-components#component-support-file",
        "text": "Component Support File",
        "level": 2
      },
      {
        "id": "app/component-testing/styling-components#3rd-party-css-libraries-tailwind-bootstrap-popperjs",
        "text": "3rd Party CSS Libraries (Tailwind, Bootstrap, PopperJS)",
        "level": 2
      },
      {
        "id": "app/component-testing/styling-components#importing-stylesheets",
        "text": "Importing Stylesheets",
        "level": 2
      },
      {
        "id": "app/component-testing/styling-components#rules-for-setting-up-your-styles",
        "text": "Rules for Setting Up Your Styles",
        "level": 2
      },
      {
        "id": "app/component-testing/styling-components#global-app-styles",
        "text": "Global App Styles",
        "level": 3
      },
      {
        "id": "app/component-testing/styling-components#css-reset-or-normalize-isnt-applied",
        "text": "CSS Reset or Normalize isn't applied",
        "level": 3
      },
      {
        "id": "app/component-testing/styling-components#fonts-everything-is-rendering-in-times-new-roman",
        "text": "Fonts: Everything is rendering in Times New Roman",
        "level": 3
      },
      {
        "id": "app/component-testing/styling-components#icon-fonts-none-of-my-icons-are-rendering",
        "text": "Icon Fonts: None of my icons are rendering",
        "level": 3
      },
      {
        "id": "app/component-testing/styling-components#theme-providers-my-components-dont-look-right-compile-because-they-cant-access-providers",
        "text": "Theme Providers: My components don't look right/compile because they can't access providers",
        "level": 3
      }
    ]
  },
  "content": {
    "type": "root",
    "children": [
      {
        "type": "heading",
        "depth": 1,
        "children": [
          {
            "type": "text",
            "value": "Styling Components"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 5,
        "children": [
          {
            "type": "text",
            "value": " What you'll learn"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Why you should test your component's styles"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "How to render components correctly with their CSS styles"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "How to handle 3rd party CSS libraries"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Why Test Your Component's Styles?"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Stylesheets are a critical part of your component's business logic. One of the\nbest examples of this is a modal component. Common modal bugs include: z-index\nissues, inability to dismiss the overlay, and inability to interact with the\nparent page after dismissing the modal."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Node-based test runners like Jest or Vitest can't catch these kinds of issues\nbecause they render your styles in emulated DOM environments like JSDom.\nJSDom doesn't have a box model and certain kinds of assertions, such as if a\nparent is covering a child and preventing clicks, are not possible to test\nwithout a more realistic environment."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "On the other hand, browser-based runners like Cypress allow you to render your\napplication's styles and components and allow Cypress's Driver to take advantage\nof the real box-model and style rendering engine. Cypress's commands like\n`cy.click` and assertions like `should('be.visible')` have business logic that\nmakes sure the UI you're trying to assert on and interact with is visible and\ninteractible for your end users. This is a benefit unique to browser-based test\nrunners."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Rendering Components Correctly"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The first time you mount any new component, you may notice that the component\ndoesn't look like it should. Unless your application is written exclusively\nusing Component-scoped CSS (e.g. Styled Components or Vue's Scoped Styles) you\nwill need to follow this guide in order to get your component looking and\nbehaving like it will in production."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Ensure that whatever you're doing in production is happening within either the\nComponent HTML file or the Component Support File."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Component Support File"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "When you load a component or end-to-end spec file, it will first load something\ncalled a supportFile. By default, this is created for you during first-time\nsetup of Cypress Component Testing and is located at\n`cypress/support/component.js`. This file gives you the opportunity to set up\nyour spec's environment."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For component specs, you use this file to set up page-level concerns that would\nusually exist by the time you mount the component. Some examples include:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": true,
        "start": 1,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Run-time JavaScript code (state management, routers, UI libraries)"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Global styles (style resets, Tailwind)"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "As a rule, your Component Support File should look very similar to your\napplication's main JavaScript (ie: main.js, index.js) and main CSS (ie:\nmain.css, index.css) files."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "3rd Party CSS Libraries (Tailwind, Bootstrap, PopperJS)"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Components can have three parts: markup, styles, and script logic. All three of\nthese work together in order to deliver a working component."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Styles are business logic, too."
          }
        ]
      },
      {
        "type": "list",
        "ordered": true,
        "start": 1,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Tailwind"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "CSS Modules"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Scoped Styled"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Styled Components"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Regular Stylesheets"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "UI Libraries"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This guide will help you setup your test infrastructure to render your\ncomponent's styles properly."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Depending on how your application is built, the first time you mount a new\ncomponent, it may be completely or somewhat unstyled."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This makes sense. Many applications have some amount of one-time setup that is\nrun outside of the component file."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "We build our applications within the context that they're supposed to run in,\nand we make assumptions that our components will always be rendered within a\nroot-level component (such as an `<App>`) or a top-level selector with style\nrules (such as `#app { /* styles in here */ }` )"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "When we attempt to isolate our component to put it under test, we need to put\nthat environment back together. We'll go into that in a moment. First, let's\ntalk about stylesheets, testing, and one of Cypress's biggest differences in\ncontrast to other component testing tools."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Importing Stylesheets"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Each application or component library imports styles a little differently. We'll\ngo over a few methods and describe how you can quickly restructure your\ncomponents to become more testable."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you do not follow this guide, your components will mount, but they won't look\ncorrect and you may not be able to benefit from some of the most valuable parts\nof Cypress. Namely, implicit checks for width, height, and overflow to ensure\nthat your components not only exist in the page's HTML but are also visible."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Rules for Setting Up Your Styles"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "All of your application's styles need to end up in Cypress so that when your\ncomponent mounts, it looks right."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "We expose two hooks for you to configure your styles:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": true,
        "start": 1,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "An HTML file called `cypress/support/component-index.html`"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "A JavaScript support file called `cypress/support/component.js`"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "When creating a production-like test environment, you should always mimic your\nown application's setup. If your application has multiple `<link>` tags to load\nfonts or other stylesheets within the `head`, ensure that the\n`cypress/support/component-index.html` file contains the same `<link>` tags. The\nsame logic follows for any styles loaded in your Application's `main.js` file.\nIf you import a `./styles.css` at the top of your `main.js` file, make sure to\n`import` it in your `cypress/support/component.js` file."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For this reason, it's strongly suggested to make a `src/setup.js` file that will\nbe re-used in your `main.js` entrypoint as well as in your test setup. An\nexample project structure would look like so:"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "> /cypress\n>   /support\n>    /component.js\n> /src\n>  /main.js\n>  /main.css\n>  /setup.js"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The contents of setup.js may look like so:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "import '~normalize/normalize.css'\nimport 'font-awesome'\nimport './main.css'\n\nexport const createStore = () => {\n  return /* store */\n}\n\nexport const createRouter = () => {\n  return /* router */\n}\n\nexport const createApp = () => {\n  return <App router={createRouter()} store={createStore()}></App>\n}"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "and its usage in `main.js` could look like so:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "import { createApp } from './setup.js'\n\nReactDOM.render(createApp())"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "and Cypress would re-use it in its support file"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "/* And that's it! */\nimport '../../src/setup.js'"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The rest of this section is dedicated to discussing specific style problems you\nmay have, including: Fonts, Icon Fonts, Style Resets, Global App Styles, and 3rd\nparty component library styles."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Global App Styles"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Your global application styles are usually in one of the following places:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": true,
        "start": 1,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "A `styles.css` file you import within the `head` of your application."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This should be loaded within your Cypress Index HTML file."
          }
        ]
      },
      {
        "type": "list",
        "ordered": true,
        "start": 2,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Within a root-level component like `App.jsx`, `App.vue`, `App.svelte`, etc."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Decouple your Root CSS from your App or Entrypoint component by pulling out\nthese global styles into a top-level stylesheet. Both Vue and Svelte embed\nglobal application styles into the main entry point components. The rest of your\napplication expects to be rendered within those components, and so any\nassumptions you made when writing those components must be replicated in your\ntest environment or else your components won't look right."
          }
        ]
      },
      {
        "type": "code",
        "lang": "html",
        "meta": null,
        "value": "<style>\n  /* In certain scaffolds, the App.vue file does not have a separate styles file */\n\n  #app {\n    font-family: Sans-serif;\n  }\n</style>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Should become"
          }
        ]
      },
      {
        "type": "code",
        "lang": "html",
        "meta": null,
        "value": "/* App.vue */ <style src=\"./app.css\" />"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "and"
          }
        ]
      },
      {
        "type": "code",
        "lang": "html",
        "meta": null,
        "value": "/* cypress/support/component.js */ import '../../src/app.css'"
      },
      {
        "type": "list",
        "ordered": true,
        "start": 3,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Within the `main.js` file of your application (which subsequently mounts your\nroot-level component)."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Re-using stylesheets that are imported in the beginning of your application was\ncovered in the last section."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "import './main.css'"
      },
      {
        "type": "list",
        "ordered": true,
        "start": 4,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Within a configuration file like `next.config.js`."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You're usually providing public paths to these stylesheets. You can import the\nsame paths within your `cypress/support/component-index.html` file."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "CSS Reset or Normalize isn't applied"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Are you importing your normalize file within\n`cypress/support/component-index.html` or within `cypress/support/component.js`?"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Fonts: Everything is rendering in Times New Roman"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Most applications handle fonts in one of two ways."
          }
        ]
      },
      {
        "type": "list",
        "ordered": true,
        "start": 1,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Your `index.html` loads external fonts in the `head` tag."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "code",
        "lang": "html",
        "meta": null,
        "value": "<head>\n  <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n  <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n  <link\n    href=\"https://fonts.googleapis.com/css2?family=Readex+Pro:wght@200;300;400;500;600;700&family=Roboto&display=swap\"\n    rel=\"stylesheet\"\n  />\n</head>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Or via an `@import` statement"
          }
        ]
      },
      {
        "type": "code",
        "lang": "html",
        "meta": null,
        "value": "<head>\n  <style>\n    @import url('https://fonts.googleapis.com/css2?family=Readex+Pro:wght@200;300;400;500;600;700&family=Roboto&display=swap');\n  </style>\n</head>"
      },
      {
        "type": "list",
        "ordered": true,
        "start": 2,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Your main stylesheet loads fonts"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "code",
        "lang": "css",
        "meta": null,
        "value": "/* main.css */\n@font-face {\n  font-family: 'Fira Sans';\n  src: url('fonts/fira/eot/FiraSans-Regular.eot');\n  src:\n    url('fonts/fira/eot/FiraSans-Regular.eot') format('embedded-opentype'),\n    url('fonts/fira/woff2/FiraSans-Regular.woff2') format('woff2'),\n    url('fonts/fira/woff/FiraSans-Regular.woff') format('woff'),\n    url('fonts/fira/woff2/FiraSans-Regular.ttf') format('truetype');\n  font-weight: normal;\n  font-style: normal;\n}"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Icon Fonts: None of my icons are rendering"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Theme Providers: My components don't look right/compile because they can't access providers"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Theme Provider or other application-level wrappers like I18n or Material UI work\nby injecting themselves around your application. When you're component testing,\nyou haven't rendered the component hierarchy surrounding your component."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To solve issues like these, people review the Custom Commands and Wrappers"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To first explain why it's not right, you first have to explain what\nproduction-like even means."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "So we have this before & after up, and now our job is to step through the\ncomponent under test and try to figure out where the differences between\nProduction and Test are."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Sometimes these are as simple as colors or fonts not lining up. Other times, the\nentire component or sections of it may not compile."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The reason this doesn't look right is because:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": true,
        "start": 1,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "My browser supports dark mode"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The `<App>` component provides its own styles"
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  },
  "token_estimate": 1981
}