Prevent global css to affect my react npm package elements

Viewed 1025

I've developed a react npm package, containing element. when installed in a react project, ul css of the parent project affect the of the npm package,

How to encapsulte the npm package to prevent any global css to affect it ? without using Iframe.

for example :

Global project using the npm package

ul {
 padding : 30px
}

all element inside my npm package will have padding 30px ...

4 Answers

This is interesting. So my thought process would be like this -

First Try

  1. Wrap your package element with some class name to indicate that below this, styles should not pass. Ex. class="restricted-from-project-styles"
  2. Then to your projects add styles like this -
body :not(.restricted-from-project-styles) {
 // Apply all your project styles here.
}

But this doesn't work, because it ignores only first-level elements.

Ex. - Try running this on stack-overflow. Element directly inside top-bar is ignored but it's children are not.

body :not(.top-bar) * {
  display: none;
}

Second Try

  • All elements of npm-package must have a class prefix such that it is difficult to have such class on parent project. I can use BEM naming convention to do this.

But this doesn't work either, because styles applied to tag-names will still be passed on.

Hmm.... I would want random class names to limit styles being passed from parent. But I would also like to ignore HTML-tag styles.

Third try

  • Apply reset css styles scoped to package element's root

For managing styles efficiently there is a new boy in town styled-components.

See this video for introduction

I hope this gives you a starting point.

Best you can do is to use CSS all property:

.my-app-container * {
    all: initial;
    // or
    // all: unset;
}

The all shorthand CSS property resets all of an element's properties

The initial CSS keyword applies the initial (or default) value of a property to an element. This initial value is set by the browser.

I also have made private npm package where I have isolateed my css from global

you can use

  1. LESS
  2. Chokidar (watcher)

to prevent global css to effect our local css while making brand new package

less generated new file with prefix class of your css and watcher continuously build your css with prefix class

suppose you have styles1.css file and have blow code

ul {
 padding : 30px
}

then you can attach prefix class to your class by

.style1 {
    @import (less) 'style1.css';
}

then generated file have blow code

.style1 ul {
 padding : 30px
}

then you can add .style1 class to your parent div of your package like this

<div className="style1">
  <ul>
     <li>1</li>
     <li>2</li>
     <li>3</li>
  </ul>
</div>

you can test my EXAMPLE (chokidar + less) project

If you add a specific class name to your elements, global rules without that class name are going to be overridden by your rule. For example:

Your components:

    <div class="my-component">
        <ul> ... </ul>
    </div>

Your CSS:

.my-component ul {
    padding: 10px;
}

Now if someone adds

ul {
    padding: 30px;
}

it will not affect your component. That's because your CSS rule is more specific (since it requires the my-component class).

Do note that rules you do not specify will be affected by the global CSS.

Related