pwan
pwan

Reputation: 707

Blur all but one element in the body

I'm trying to blur everything on the screen except the loading animation. This is what I have tried.

$("#addall").click(function() {
  $('#loading').show();
  $('body:not(#loading)').css("filter", "blur(3px)");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="simple-loading" style="display: none" id="loading">
  <div class="active dimmer">
    <div class="text loader">Loading...</div>
  </div>
</div>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec placerat id nisi eget egestas. <a id="addall" href="javascript:void(0)">Load.</a> Nullam luctus ac ipsum vel blandit. Cras eu felis ac lorem porta egestas. Sed interdum cursus ligula, sit amet euismod velit volutpat at. Fusce luctus scelerisque mollis. Praesent ligula neque, vehicula elementum justo sed, egestas accumsan eros. Suspendisse at est eget nunc efficitur vestibulum. Suspendisse potenti. Pellentesque quis fermentum ligula.</div>

Also I have tried

$("body").each(function(event) {
    if (event.target.id != "loading") {
        $(this).css("filter","blur(3px)");
    }
});

and it never works... Is there any good solution?

Upvotes: 26

Views: 30317

Answers (8)

Nipuna
Nipuna

Reputation: 362

A better solution from 2023

I'm using backdrop-filter: blur() instead of filter: blur() to make sure the elements behind the .backdrop are blurred, instead of the element itself.

I hope the code is self-explanatory (the complete code on CodePen). But for those who are wondering, it's just the .backdrop positioned over all the elements using position: fixed; and z-index:9998;. And then the .except is placed over the .backdrop using z-index: 9999; which is one level higher than the .backdrop but only using position: relative; so it's at the same place as it was before.

This way you can blur everything including the backgrounds except for the desired element and you don't need to reposition the .except element somewhere else this way.

Let me know if I've missed something.

.except {
    background: white;
    position: relative;
    z-index: 9999;
}

.backdrop {
    position: fixed;
    z-index: 9998;
    top: 0; bottom: 0; left: 0; right: 0;
    background: #33333377;
    backdrop-filter: blur(4px);
}
<div class="wrap">
    <div class="content">Some text</div>  
    <div class="content except">Some text</div>  
    <div class="content">Some text</div>
    <div class="content">Some text</div> 
</div>

<div class="backdrop"></div>

Demo with the complete code on CodePen

Upvotes: 3

Grant
Grant

Reputation: 6329

If someone is still scratching their head about this, despite the answers provided. You have to start your wildcard blurring from the immediate parent to the child you want unblurred. In my case, I had to do something like this:

body.modal-open > #wrapper > #page-content-wrapper > #app > div > *:not(#newApplicationModal)

Because if I had simply done

body.modal-open > *:not(#newApplicationModal)

It still blurred everything, because the nested children of body were parent containers of my desired unblurred item, resulting in the parent being blurred and the contents blurring along with it regardless.

Upvotes: 4

Juan Angel
Juan Angel

Reputation: 726

This worked for me:

body > *:not(#loading > *){
    filter: blur(3px);
}

Upvotes: 2

Alexander Suraphel
Alexander Suraphel

Reputation: 10613

Unfortunately you cannot blur an HTML node without blurring its children.

One solution is to put your contents and loading image in two divs inside a parent div like the following.

<div id="parent_div" style="position:relative;height:300px;width:300px;">
    <div id="background" style="position:absolute;top:0;left:0;right:0;bottom:0;background-color:red;filter: blur(3px);z-index:-1;"></div>
    <div id="loading">Spinner...</div>
</div>

To blur/unblur just do $('#background').css('filter', 'blur(3px)).

Upvotes: 6

Just a student
Just a student

Reputation: 11040

The problem is that your selector works on all body elements and then picks the ones that do not have ID loading. Since there is only one body element and it indeed does not have this ID, it is selected. Of course, this is not what you want. You want to select all children of the body element and then filter those that do not have the loading ID.

The selector needs to be body > *:not(#loading).

To clarify: this selector selects all elements (*)...
...that are children of the body (body > *)
...and do not have ID loading (*:not(#loading)).

This uses the child selector (spec) and negation pseudo-class :not() (spec).

body > *:not(#loading) {
  background: #ffd83c;
  filter: blur(3px);
}

div, p {
  margin: 10px;
  padding: 5px;
}
<div>Some DIV.</div>
<div id="loading">Loading DIV</div>
<div>Some other DIV.</div>
<p>A paragraph.</p>

Upvotes: 31

prog1011
prog1011

Reputation: 3495

Try This

You can achieve this using css only. NO NEED TO JQUERY

Please see the below code

body > *:not(#loading) {
  filter: blur(3px);
}
<div>Some DIV.</div>
<div id="loading">Loading DIV
    <div style='padding:15px;'>Some other DIV inside loading div.</div>
</div>
<div>Some other DIV.</div>
<p>A paragraph.</p>

enter image description here

Upvotes: 15

Muhammad Qasim
Muhammad Qasim

Reputation: 1712

This is simple. Try the following:

$('body').not("#loading").css("filter","blur(3px)");

The above selector is selecting the whole body except element with id loading.

However I've corrected the syntax but this wont blur except loading because everything under body will be blurred. You have to change your html structure like:

 <body>
    <div id="loading">Here your logic image..text or whatever</div>
    <div id="bodyContainer">Your whole html that was in your body</div>
 </body>

Now in jquery you can do the following:

 $('#bodyContainer').css("filter","blur(3px)");

Upvotes: 2

Rahul
Rahul

Reputation: 18557

Try this,

$("#addall").click( function() {
    $('#loading').show();
    $('body').not("#loading").css("filter","blur(3px)");
});

I have changed, the way syntax worked. Hope this helps.

Upvotes: 3

Related Questions