How to blur body when menu is opened?

Hi all, how are you doing? How to blur body when mobile menu is opened?
I tried something like this, but that affects my mobile menu I just want background to be blured not menu.

CSS:

body.blur > *:not(.menu) {
  filter: blur(5px);
} 

menu is just a ul and it is a sidebar on mobile devices

JS:

hamburger.addEventListener("click", () => {
  hamburger.classList.toggle("active");
  menu.classList.toggle("open");
  body.classList.toggle("fixed");
  body.classList.toggle("blur");
});

That should work if I understand correctly.

A very rough demo as just going out :slight_smile:

1 Like

That’s the result I want, but somehow my menu got affected with the body too.

There must be a typo or something.

I’m back on the morning if you have a link or a demo? It should be something quite simple.

> = “the direct child”

You’d have to show us your HTML to get better advice. We’d need to know the structure of your page.

2 Likes

Sorry for my English , I am doing my best.

Here is HTML:


<header id="header">
      <div class="container">
        <div class="row align-items-center">
          <div class="col d-flex align-items-center">
            <div
              class="hamburger d-flex flex-column justify-content-between d-md-none"
            >
              <span></span>
              <span></span>
              <span></span>
            </div>
            <div class="logo">
              <a href="#">
                <img src="img/logo.svg" alt="logo" />
              </a>
            </div>
            <nav id="nav">
              <ul class="menu">
                <li class="menu-item">
                  <a href="#" class="menu-link">Collections</a>
                </li>
                <li class="menu-item">
                  <a href="#" class="menu-link">Men</a>
                </li>
                <li class="menu-item">
                  <a href="#" class="menu-link">Women</a>
                </li>
                <li class="menu-item">
                  <a href="#" class="menu-link">About</a>
                </li>
                <li class="menu-item">
                  <a href="#" class="menu-link">Contact</a>
                </li>
              </ul>
            </nav>
          </div>
          <div class="col">
            <div class="float-end">
              <img src="img/icon-cart.svg" alt="cart" class="cart-icon" />
              <img
                src="img/image-avatar.png"
                alt="profile picture"
                class="profile-img"
              />
            </div>
          </div>
        </div>
        <hr class="line" />
      </div>
    </header>

And CSS of the body:

body {
  font-family: var(--primary-ff);
  min-height: 100vh;
  font-size: 1rem;
}

How to share HTML tags?

You’re doing fine :slight_smile:
For the HTML, stick it into a code block (put ``` on a blank line before it, and the same on a blank line after it), that’ll format it so we can see.

2 Likes

So the problem is I can’t grab menu like this and the reason why background color worked instead of blur is that I have a z-index:111 on menu. If you have any suggestion how could I do it differently that would help a lot. Basically , I want to blur everything when menu is open except menu.

do you want to blur the cart and avatar image?

yes.

well, there’s a couple ways to do it… simplest that strikes to my mind is to blur everything and then unblur the menu…

body.blur { filter: blur(5px); }
.menu { filter: none; }

This of course does assume you dont want to apply some other filter type to the menu at some other point in time.

That isn’t working .

body.blur {
  filter: blur(5px);
}

body.blur .menu {
  filter: none;
}

I can apply background color but filter none can’t , menu is still blured.

Well that isnt what i gave you to enter. :wink:

Thank you anyway.

What i mean is… you changed what i told you to put in there.

I told you this:

You put in this:

Okay , listen that isn’t working okay? If you don’t know how to do it, don’t answer just ignore this post. Thank you

At least try before answering if you want to help of course

The css filter is ‘atomic’.

You can’t unblur children :slight_smile:

If a parent is blurred then so are all the children and they can’t be unblurred.

That’s why in my demo the blurred elements and the unblurred elements are separate.

If you can’t extricate the html for your menu from its parent then the best you can do is shim a partially opaque fixed pseudo element under the menu but above everything else.

I’m out at a restaurant at the moment so can’t offer code :slight_smile:

Back tomorrow.

1 Like

Well I can’t very much say that i’m inclined to help if you’re going to take that attitude with people actually trying.

As Paul has outlined that the filter is atomic, it will need to be applied with more specificity.

body.blur > *:not(#header),
body.blur > #header img {
  filter: blur(5px);
}

Perhaps next time show some patience.

This code does assume that the header is a direct child of the body.

3 Likes

Actually , you can grab menu like this

body > *:not(.menu) {
  background-color: red !important;
}

The problem is it will apply to the menu too because he is child of the nav and they need to be seperated I will try tomorrow it was a long day.