Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[jss-isolate][jss-nested] jss-isolate isolates nested rules #698

Closed
yakhinvadim opened this issue Apr 6, 2018 · 13 comments
Closed

[jss-isolate][jss-nested] jss-isolate isolates nested rules #698

yakhinvadim opened this issue Apr 6, 2018 · 13 comments
Labels
question Documentation is not good enough.

Comments

@yakhinvadim
Copy link

Consider the code:

const styles = {
    link: {
        color: 'green',
        '&:hover': {
            textDecoration: 'underline'
        }
    } 
}

With jss-isolate, I'd expect the following behaviour:

.link-123456 {
    color: green;
}

/* isolated */
.link-123456:hover {
    /* color is inherited from the rule above */
    text-decoration: underline;
}

but got:

.link-123456 {
    color: green;
}

/* isolated */
.link-123456:hover {
    /* color is set to black by isolation */
    text-decoration: underline;
}

According to this comment, it's not the expected behaviour: #334 (comment)

I've found three ways to workaround this:

  1. add isolate: false

    const styles = {
        link: {
            color: 'green',
            '&:hover': {
                isolate: false,
                textDecoration: 'underline'
            }
        } 
    }

    This exposes the rule to external styles, so 😕

  2. duplicate rules

    const styles = {
        link: {
            color: 'green',
            '&:hover': {
                color: 'green',
                textDecoration: 'underline'
            }
        } 
    }

    This may lead to the situation, where developers forget to change both rules, so 😕 too

  3. extract rules to variable

    const linkStyles = {
        color: 'green',
    }
    
    const styles = {
        link: {
            ...linkStyles,
            '&:hover': {
                ...linkStyles,
                textDecoration: 'underline'
            }
        } 
    }

    This is the best so far, but too verbose.

Is there any other way to get the expected behaviour?

@kof
Copy link
Member

kof commented Apr 7, 2018 via email

@kof kof added enhancement No kittens die if we don't do that. help wanted question Documentation is not good enough. labels Apr 8, 2018
@yakhinvadim
Copy link
Author

Thanks! I guess, we'll use "isolate: false" approach for now, because our environments are not that hostile.

I was also thinking about using jss-compose, but it doesn't support nested rules.
Then, I was trying to use jss-extend like this:

const styles = {
    link: {
        color: 'green',
        '&:hover': {
            extend: 'link',
            textDecoration: 'underline'
        }
    } 
}

But that led to infinite recursion. What do you think about adding an exception for jss-extend, so calling it from nested rule won't cause infinite recursion?

I'm afraid a separate plugin for pseudo selectors will confuse users, because it kind of does the same thing as jss-nested with a little different syntax.

@kof
Copy link
Member

kof commented Apr 9, 2018

If you are not integrating a widget that has to work in an uncontrolled environment, then you might want to consider isolate({isolate: 'root'}) https://github.com/cssinjs/jss-isolate#isolation-by-convention. In this case every rule named 'root' will be isolated. In this case you can rely on inheritance within one component.

@kof kof closed this as completed Apr 9, 2018
@kof kof removed enhancement No kittens die if we don't do that. help wanted labels Apr 9, 2018
@kof
Copy link
Member

kof commented Apr 9, 2018

Also in this case you don't have to set isolate: false for pseuodo selectors

@yakhinvadim
Copy link
Author

I have a little different question, but it's highly related, so I'll ask it here.

Isolation by convention is great: we protect our components from all inherited styles, but still, allow inheritance inside components.

But what about non-inherited styles set globally?

Let's say we develop a simple component with <h1> in it. We don't set margin explicitly, assuming it will be browser's default: margin-top: 0.67em; margin-bottom: 0.67em.
But our component is used in app, where bootstrap styles are present:

h1, h2, h3, h4, h5, h6 {
  margin-top: 0;
  margin-bottom: 0.5rem;
}

(see https://github.com/twbs/bootstrap/blob/v4-dev/dist/css/bootstrap-reboot.css#L52)

So, in this app our components will end up with broken styles.

It would be great if we could use two types of isolation together:

  • For 'root' classes - isolation by convention of all properties
  • For other classes - isolation of all non-inherited properties

I've tried to come up with an option object for jss-isolate, which would add this behavior, but as I understand, it is now impossible to combine these two types.

So, my questions are:

  1. Is it possible? And if not:
  2. Do you think such setup will be useful?

@kof
Copy link
Member

kof commented Apr 11, 2018

But what about non-inherited styles set globally?

thats why I asked if you control the environment, if you do - don't use global declarations

@kof
Copy link
Member

kof commented Apr 11, 2018

@kof
Copy link
Member

kof commented Apr 11, 2018

Do you think such setup will be useful?

yeah I think this could be useful, currently it won't work, it would require a way to define this

@yakhinvadim
Copy link
Author

yeah I think this could be useful, currently it won't work, it would require a way to define this

Good, then if you don't mind, I'll try to make a PR for this in a couple of weeks.

@kof
Copy link
Member

kof commented Apr 13, 2018

Sure!

@kof kof assigned yakhinvadim and unassigned yakhinvadim Apr 13, 2018
@kof
Copy link
Member

kof commented Apr 13, 2018

Lets create a new issue with a spec?

@yakhinvadim
Copy link
Author

Sure, I've made a new issue for that. Right now it's kind of a placeholder, so I'll make it more complete later. Actually, I might not fully understand what is needed in the spec, so feel free to correct me :)

@DiesIrae
Copy link

DiesIrae commented Apr 8, 2020

We just bumped on this issue in my organization. We are putting a widget in a hostile environment, this is why we would like to use jss-isolate in the first place, not to be polluted by global changes. All solutions exposed by @yakhinvadim are impractical for us.

Making compatible jss-isolate and jss-nested is still not a priority? Is this a strong technical challenge, or is this plugin simply not evolving any more (I see the last code change dates from 2 years ago)?

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Documentation is not good enough.
Projects
None yet
Development

No branches or pull requests

3 participants