admin管理员组

文章数量:1287790

My goal is to achieve something like the Inspector Tool element selector. So, I should not change the layout/style. I just need to add an translucent overlay and border. I did this:

  .highlight-overlay {
        position: relative;
  }
  .highlight-overlay::after {
        content: "";
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: rgba(255, 166, 0, 0.2);
        border: 2px solid blue;
        pointer-events: none;
   }

The above works great. But the big downside is position: relative; . It sometimes break the existing HTML layout (if the container's original position was fixed or absolute or something else).

Another solution is to use position fixed and use Javascript to account for scrolling.

function addOverlay(targetElement) {
  const overlay = document.createElement('div');
  const rect = targetElement.getBoundingClientRect();

  overlay.style.position = 'absolute';
  overlay.style.top = `${window.scrollY + rect.top}px`;
  overlay.style.left = `${window.scrollX + rect.left}px`;
  overlay.style.width = `${rect.width}px`;
  overlay.style.height = `${rect.height}px`;
  overlay.style.backgroundColor = 'rgba(255, 166, 0, 0.2)';
  overlay.style.border = '2px solid blue';
  overlay.style.pointerEvents = 'none';
  overlay.style.zIndex = '9999';

  document.body.appendChild(overlay);

  // Update position on scroll
  window.addEventListener('scroll', () => {
    const rect = targetElement.getBoundingClientRect();
    overlay.style.top = `${window.scrollY + rect.top}px`;
    overlay.style.left = `${window.scrollX + rect.left}px`;
  });
}

Somehow, I think that's a rather overengineered solution for something as simple as this.

Is there any way to add overlay in CSS only without modifying existing HTML and using overengineered Javascript ?

My goal is to achieve something like the Inspector Tool element selector. So, I should not change the layout/style. I just need to add an translucent overlay and border. I did this:

  .highlight-overlay {
        position: relative;
  }
  .highlight-overlay::after {
        content: "";
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: rgba(255, 166, 0, 0.2);
        border: 2px solid blue;
        pointer-events: none;
   }

The above works great. But the big downside is position: relative; . It sometimes break the existing HTML layout (if the container's original position was fixed or absolute or something else).

Another solution is to use position fixed and use Javascript to account for scrolling.

function addOverlay(targetElement) {
  const overlay = document.createElement('div');
  const rect = targetElement.getBoundingClientRect();

  overlay.style.position = 'absolute';
  overlay.style.top = `${window.scrollY + rect.top}px`;
  overlay.style.left = `${window.scrollX + rect.left}px`;
  overlay.style.width = `${rect.width}px`;
  overlay.style.height = `${rect.height}px`;
  overlay.style.backgroundColor = 'rgba(255, 166, 0, 0.2)';
  overlay.style.border = '2px solid blue';
  overlay.style.pointerEvents = 'none';
  overlay.style.zIndex = '9999';

  document.body.appendChild(overlay);

  // Update position on scroll
  window.addEventListener('scroll', () => {
    const rect = targetElement.getBoundingClientRect();
    overlay.style.top = `${window.scrollY + rect.top}px`;
    overlay.style.left = `${window.scrollX + rect.left}px`;
  });
}

Somehow, I think that's a rather overengineered solution for something as simple as this.

Is there any way to add overlay in CSS only without modifying existing HTML and using overengineered Javascript ?

Share Improve this question edited Feb 25 at 4:23 TSR asked Feb 22 at 23:56 TSRTSR 20.6k31 gold badges118 silver badges235 bronze badges 3
  • I haven't looked into anchor positioning but maybe that could help you? – Zach Jensz Commented Feb 23 at 2:27
  • What exactly is your question? – TylerH Commented Feb 24 at 18:53
  • Maybe you could use the :where selector in your CSS to try to set position relative. :where has lower specificity so likely won't break existing positioning. Alternatively, using JavaScript you can get the computed position using getComputedStyle and see if it already has a position or not. – Aayla Secura Commented Feb 25 at 8:25
Add a comment  | 

2 Answers 2

Reset to default 0

You just need to add one HTML tag dynamically using Javascript and add CSS to it. Sample code added below. Hope this will help.

const myDiv = document.createElement("div");
myDiv.classList = "overlay";
document.body.appendChild(myDiv);
.overlay {
width: 100%;
height: 100%;
position: fixed;
z-index: 10000;
top: 0;
background-color:rgba(255, 0, 0, 0.7); 
}
<div><p>Content goes here</p></div>

<dialog>

Avoid adding any additional markup by:

  • 1️⃣ Dynamically creating a <dialog>

  • 2️⃣ Adding a <dialog> to the DOM never affects layout.

  • 3️⃣ The inert attribute/property disables <dialog> focusability.

  • 4️⃣ showModal() and show() methods open <dialog>. The difference between them is how <dialog> behaves. If showModal() is used, <dialog> is a modal (interaction to the page is blocked). If show() method is used, then <dialog> is a normal popup (interaction with the page is possible). We'll be using showModal() so we can use the ::backdrop CSS pseudo-element which serves as a overlay.

    const modal = document.createElement("dialog"); // 1️⃣
    document.body.append(modal);                    // 2️⃣
    modal.inert = "true";                           // 3️⃣
    modal.showModal();                              // 4️⃣
    

::backdrop

This CSS pseudo-element is a perfect overlay, the following is the Chrome default styles:

dialog::backdrop {
  position: fixed;
  top: 0px;
  right: 0px;
  bottom: 0px;
  left: 0px;
  background: rgba(0, 0, 0, 0.1);
}

Example

const modal = document.createElement("dialog"); 
document.body.append(modal); 
modal.inert = "true"; 
modal.showModal(); 
:root {
  font: 2ch/1.5 "Segoe UI";
}

body {
  margin: 0;
  padding: 0;
  overflow-x: hidden;
  overflow-y: scroll;
}

main {
  min-height: 500vh;
}

textarea {
  display: block;
  width: 20rem;
  min-height: 120px;
  margin: 10% auto;
  padding: 10px;
  font: inherit;
}

/*
|| Hide the <dialog>
*/
dialog {
  opacity: 0;
}

/*
|| The overlay is given a faded tint. There are no
|| limitations when styling ::backdrop, and it can 
|| even be animated as well.
*/
dialog::backdrop {
  background-color: rgba(255, 166, 0, 0.4);
  border: 2px solid blue;
}
<main>
  <textarea>
Try editing the text in this textarea. 
Interaction between the user and this page is
blocked, but scrolling is still possible.
  </textarea>
</main>

本文标签: