DEV Community

loading...

Styled Web Components

alfredosalzillo profile image Alfredo Salzillo 🐺 ・1 min read

Styled Components for React is awesome.
Why can't we style web components to?

With masquerades we can do that.

Pros

With styled web components:

  • We can write CSS in js files, using tagged string
  • we can write reactive CSS based on props value
  • no need to think about unique class names or id
  • we can style native web components and custom web components
  • generated styled-web-components can be used inside light and shadow root, without manual manage stylesheet adoption

Example

Create a styled Native Button:

import styled from 'masquerades';

// Create the button
const StyledButton = styled.button`
  background: ${({ disabled }) => (disabled ? 'grey' : '#f1c40f')};
  color: #fff;
  border: 3px solid #fff;
  border-radius: 50px;
  padding: 0.8rem 2rem;
  font: 24px "Margarine", sans-serif;
  outline: none;
  cursor: pointer;
  position: relative;
  transition: 0.2s ease-in-out;
  letter-spacing: 2px;
  ${({ disabled }) => disabled && styled.css`
    border-radius: 15px;
  `}
`
// set up observedAttributes
  .observeAttributes(['disabled']);

// Define the styled button as extension of the native button
customElements.define('styled-button', StyledButton, {
  extends: 'button',
});
Enter fullscreen mode Exit fullscreen mode

and use it

<button is="styled-button">Styled Button</button>
<button is="styled-button" disabled>Styled Button</button>
Enter fullscreen mode Exit fullscreen mode

In the end

Styled components are awesome and are so useful why not use them whit web-components?

Discussion (6)

Collapse
wintercounter profile image
Victor Vincent

I decided not to touch WebComponents until we can drop support for every IE and non-Chromium Edge as polyfills are just slow and limited. That's still a really long time to wait :(

Collapse
ashubham profile image
Ashish Shubham

This creates copies of your styles in each instance of the component. Hence not reccommended

Collapse
alfredosalzillo profile image
Alfredo Salzillo 🐺 Author • Edited

This is not true.

Styles are not injected inside a <style></style>, nor in the style attribute, but are injected inside a shared instance of CSSStyleSheet adopted by the shadow root (if using it) and the outer root (light or shadow) of the element.

Every time the style is recalculated, the style for the unique class name, calculate using only the CSS text of the parsed style, is injected in the CSSStyleSheet if not present.

As a plus, not only instances of the same component, share the same set of class names, but also different element with equals parsed CSS string.

For example:

styled.div`
  background-color: black;
`
styled.span`
  background-color: black;
`
styled.button`
  background-color: black;
`

The instances of the three styled-components share the same class name.

Collapse
ashubham profile image
Ashish Shubham

Well, if the instances share the same styles, how are you able to reactively change the styles based on props ? The styles for all instances would change based on props passed to a single instance ?

Thread Thread
alfredosalzillo profile image
Alfredo Salzillo 🐺 Author

An unique class name, based on the style, is created and added to the element every time props changes. The old class name if present is removed.
Take a look at the code.

Collapse
codelitically_incorrect profile image
codelitically_incorrect

lame, bad practice

Forem Open with the Forem app