Creating a YouTube-style dimming effect with JavaScript and CSS

Hey everyone! I’m working on a Chrome extension and I want to add a cool feature. You know how YouTube dims everything except the video player when you’re watching in theater mode? I want to do something similar in my app.

I’m trying to figure out how to use JavaScript to darken all the content on a webpage except for one specific element. Since it’s Chrome-only, I can use CSS3 if that helps.

Has anyone done something like this before? What’s the best way to approach it? I’ve tried a few things but can’t seem to get it right. Any tips or code snippets would be super helpful!

Here’s a basic example of what I’ve tried so far:

function dimPage(elementToKeep) {
  const overlay = document.createElement('div');
  overlay.style.cssText = `
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.8);
    z-index: 9999;
  `;
  document.body.appendChild(overlay);
  elementToKeep.style.position = 'relative';
  elementToKeep.style.zIndex = '10000';
}

But this doesn’t quite work as I expected. Any ideas on how to improve it?

hey miat, i’ve done something similar before. your approach is on the right track, but you might wanna consider using a css class instead of inline styles. it’s easier to manage and toggle. also, try adding a transition for a smoother effect. here’s a quick example:

.dimmed { filter: brightness(0.2); transition: filter 0.3s; }

Then just toggle this class on body. hope this helps!

I’ve implemented a similar feature in a project before. Your approach is solid, but you might want to consider using the CSS clip-path property for more precise control. It allows you to create a ‘hole’ in the overlay for your target element.

Here’s a refined version of your code:

function dimPage(elementToKeep) {
  const overlay = document.createElement('div');
  const rect = elementToKeep.getBoundingClientRect();
  
  overlay.style.cssText = `
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.8);
    z-index: 9999;
    clip-path: polygon(0% 0%, 0% 100%, 100% 100%, 100% 0%, ${rect.left}px ${rect.top}px, ${rect.left}px ${rect.bottom}px, ${rect.right}px ${rect.bottom}px, ${rect.right}px ${rect.top}px);
  `;
  
  document.body.appendChild(overlay);
}

This creates an overlay that covers everything except the target element. The clip-path adjusts dynamically based on the element’s position and size.