This selects then hides everything inside the <body>
except #content_container
, its children and its parents.
class="hide"
is added to the HTML purely to indicate which elements will be hidden, but isn't programmatically useful.
It works by applying the class="hidden"
to every element within the <body>
, unless it's #content_container
or it contains #content_container
.
An !important
CSS rule then forces the children of #content_container
to remain visible
.
For demonstration, I have added a 1 second delay before the hiding occurs.
setTimeout( () => { // for demo
document.querySelectorAll( "body *:not( #content_container )" )
.forEach( ( v ) => {
if ( !v.querySelector( "#content_container" ) ) {
v.classList.add( "hidden" );
}
} );
}, 1000 );
body {
padding: .5rem;
background: lightgrey;
}
div {
padding: inherit;
border: 1px solid black;
background: lightblue;
}
#content_container {
background: lightgreen;
visibility: visible !important;
}
/* to hide the children, remove this rule */
#content_container * {
visibility: visible !important;
}
.hidden {
visibility: hidden;
}
<body>
<div>
<div class="hide">
<div class="hide">
<div class="hide">
<div class="hide"></div>
</div>
</div>
</div>
<div>
<div>
<div id="content_container">
<div>
<div>
<div></div>
</div>
</div>
</div>
<div class="hide">
<div class="hide">
<div class="hide">
<div class="hide"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
This solution doesn't maintain the visibility
of #content_container
's parents.
If #content_container
's children should also be hidden, only a minor change to the CSS will fix it.
I have highlighted the CSS that keeps the children visible.
setTimeout( () => { // for demo
document.querySelectorAll( "body *:not( #content_container )" )
.forEach( ( v ) => { v.classList.add( "hidden" ); } );
}, 1000 );
body {
padding: .5rem;
background: lightgrey;
}
div {
padding: inherit;
border: 1px solid black;
background: lightblue;
}
#content_container {
background: lightgreen;
visibility: visible !important;
}
/* to hide the children, remove this rule */
#content_container * {
visibility: visible !important;
}
.hidden {
visibility: hidden;
}
<body>
<div>
<div class="hide">
<div class="hide">
<div class="hide">
<div class="hide"></div>
</div>
</div>
</div>
<div>
<div>
<div id="content_container">
<div>
<div>
<div></div>
</div>
</div>
</div>
<div class="hide">
<div class="hide">
<div class="hide">
<div class="hide"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
A far more efficient and simpler alternative to the previous solution is to hide the <body>
(and therefore everything else on the page) whilst forcing the visibility of #content_container
and its children.
This is a more direct route, faster to apply and easier to reverse if required; my first solution sets a lot of redundant classes.
setTimeout( () => { // for demo
document.querySelector( "body" ).classList.add( "hidden" );
}, 1000 );
body {
padding: .5rem;
background: lightgrey;
}
div {
padding: inherit;
border: 1px solid black;
background: lightblue;
}
#content_container {
background: lightgreen;
visibility: visible !important;
}
.hidden {
visibility: hidden;
}
<body>
<div>
<div class="hide">
<div class="hide">
<div class="hide">
<div class="hide"></div>
</div>
</div>
</div>
<div>
<div>
<div id="content_container">
<div>
<div>
<div></div>
</div>
</div>
</div>
<div class="hide">
<div class="hide">
<div class="hide">
<div class="hide"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>