DEV Community

loading...

Is there a way to exclude elements with a particular default styling from a CSS selector?

baenencalin profile image Calin Baenen ・1 min read

I have a CSS selector, body * {display:inline-block;} (example code). But, I'd like to hide elements that are hidden by default, or have the styling to be hidden. Is there anything like body *:not([style="hidden"]) (which I've tried (and doesn't work)), that will work on all elements that are hidden by default (and/or by stylistic choice)?

Discussion (10)

pic
Editor guide
Collapse
aileenr profile image
Aileen Rae

I'm not sure what you mean by "hidden by default" so please let me know if I've misinterpreted your question.

The :not() selector is how you exclude some elements from a CSS selector. If that's what you're trying to do you're on the right track.

body *:not([style="hidden"]) {
  /* your style rules */
}
Enter fullscreen mode Exit fullscreen mode

would apply your style rules to all elements in your <body> tag, except elements with a style="hidden" attribute. For example it would only apply to the h1 here:

<body>
  <h1>Title</h1>
  <div style="hidden"></div>
  <p style="hidden"></p>
</body>
Enter fullscreen mode Exit fullscreen mode

It's worth noting that style="hidden" isn't a valid style attribute and it won't do anything if you add it to your HTML. If you are trying to hide elements with CSS it's better to use a class. e.g.

.hidden {
  display: none;
}
Enter fullscreen mode Exit fullscreen mode

The you can use it to hide your HTML elements like so:

<div class="hidden">This div willl be hidden</div>
Enter fullscreen mode Exit fullscreen mode
Collapse
baenencalin profile image
Calin Baenen Author

What I meant by "hidden by default" is things like <script>, <link>, etc...
And just so I
1) don't have to manually write all that out.
AND (especially) 2) so I don't have to update my CSS, if new or existing elements are updated to be hidden by default.

Collapse
aleksandrhovhannisyan profile image
Aleksandr Hovhannisyan

Interesting... Your question made me learn something new today!

I'd never thought about styling script, link, and other "hidden" tags. That thought just never occurred to me as something you can do. But apparently it can be done. Stick this on any script tag in your body, for example:

    display: block;
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    background: red;
    z-index: 2000000;
Enter fullscreen mode Exit fullscreen mode

But I understand that you want the opposite: to prevent styles from getting applied to these elements. You don't actually have to worry about this, though, because these tags get display: none set by default, so they don't show up at all. You can verify this by inspecting any "hidden" element in your browser's dev tools:

Thread Thread
baenencalin profile image
Calin Baenen Author

I KNOW they have it by default, but I'm using body *, but I want to negate this styling from the specific elements that begin with (or (only) POSSIBLY have) styling none, so that I don't have to specify all of the ones that are hidden, or update my CSS in the future (if more default-hidden elements are put into HTML).

Thread Thread
aileenr profile image
Aileen Rae • Edited

I have also never thought about applying styling to tags like script. Is the problem you are having that styles are being applied to <script> elements in the body of your page?

It's a strange problem you've run into. It's because body * is a very generous selector. Too generous for changing the display property. As you've highlighted, this makes script elements visible. As a best practice you'll want to be more specific with what elements you apply style rules to.

An alternative here would be to create an extra "container" element for all your visible elements. For example:

<body>
  <div class="container">
    <h1>Title</h1>
    <!-- all your "visible" elements here -->
  </div>
  <script>/* Script tags and any other "hidden" elements outside the container */</script>
</body>
Enter fullscreen mode Exit fullscreen mode

Then you can be more specific with your style rules, without affecting the script elements:

body .container *{
  display: inline-block;
  /* your other style rules */
}
Enter fullscreen mode Exit fullscreen mode

link elements are more commonly placed in the <head> of a web document, so you shouldn't need to worry about styles being applied to them if you move them to the <head>.

I hope that helps solve your problem. But if you do want to exclude elements like link and script, you should be able to do so with:

body *:not(script),
body *:not(link) {
  display: inline-block;
}
Enter fullscreen mode Exit fullscreen mode
Collapse
kallmanation profile image
Nathan Kallman

Tangential to the help question; I'm not sure the #watercooler tag is right for this question. #watercooler is typically used in off-topic/development tangential questions/discussions and actually receives a slight negative weight in the dev.to feed so that it won't be full of off-topic posts.

This is very much on-topic and I've even learned some things today; so thank you!

Collapse
alvaromontoro profile image
Alvaro Montoro • Edited

You cannot target the internal styles of an element. So there's no way to do it exclusively with CSS unless: a) the styles are inline; or b) you use the hidden HTML attribute to hide elements instead of the CSS display: none.

To select all the elements that don't have an inline style of display: none, you could do something like:

/* You'd need to add different cases for different spaces. A pain. */
*:not([style*="display:none"i]) { ... }
Enter fullscreen mode Exit fullscreen mode

To select all the elements not hidden with the hidden attribute, you could do:

*:not([hidden]) { ... }
Enter fullscreen mode Exit fullscreen mode
Collapse
adam_cyclones profile image
Adam Crockett

Let's start at the beginning, what is the use case 😅

Collapse
baenencalin profile image
Calin Baenen Author

I want to style ALL elements in my body EXCEPT any like <script> or <link>, that I OR an external program may put in the HTML document.

Collapse
adam_cyclones profile image
Adam Crockett

But why? 😎

I know this sounds anoying to keep asking why but I have a feeling you are trying to blanket target all elements and style them in some way, in the standard model of css, it is easy to avoid styling elements which don't need to be styled by styling explicitly those that you do want to style. So I guess I want to know how did you arrive at such a problem?