Затемнить весь экран, кроме фиксированной области?

89

Я хочу создать учебное пособие, которое приведет пользователя именно к тому, куда нужно щелкнуть. Я стараюсь , чтобы покрыть весь экран с <div>которой тускнеет все элементы , кроме в конкретной области , которая находится в фиксированном width, height, topи left.

Проблема в том, что я не могу найти способ «отменить» родительский элемент background-color(который также прозрачен).

В фрагменте ниже показан holediv, который должен быть без него background-color, включая его родительский.

Можно ли это вообще сделать? Любые идеи?

#bg{
   background-color:gray;
   opacity:0.6;
   width:100%;
   height:100vh;
}
#hole{
   position:fixed;
   top:100px;
   left:100px;
   width:100px;
   height:100px;
}
<div id="bg">
    <div id="hole"></div>
</div>

Вот макет того, чего я пытаюсь достичь:

введите описание изображения здесь

Коби Дуэк
источник
13
Если вы создаете обзор / руководство по функциям, вам может быть интересна одна из библиотек js для этого. У них есть отличные функции, которые избавят вас от необходимости писать кучу разовых CSS-эффектов. Посетите introjs.com или linkedin.github.io/hopscotch .
octern
2
Это всего лишь предложение для библиотеки
онлайн Томас

Ответы:

126

Вы можете сделать это с помощью всего одного divи дать ему оценку box-shadow.

EDIT: как указал @Nick Shvelidze, вам следует подумать о добавленииpointer-events: none

Добавленная vmaxстоимость, box-shadowкак предложил @Prinzhorn

div {
  position: fixed;
  width: 200px;
  height: 200px;
  top: 50px;
  left: 50px;
  /* for IE */
  box-shadow: 0 0 0 1000px rgba(0,0,0,.3);
  /* for real browsers */
  box-shadow: 0 0 0 100vmax rgba(0,0,0,.3);
  pointer-events: none;
}
<div></div>

VilleKoo
источник
29
Не забудьте добавить, pointer-events: noneесли хотите, чтобы область под ним была интерактивной.
Ник
4
1000 пикселей мне кажется недостаточно - похоже, что будет слишком много случаев, когда это не заполняет экран, в противном случае действительно умное решение.
ESR
1
@EdmundReed, вы можете настроить это под свои нужды :)
VilleKoo
8
box-shadow: 0 0 0 100vmax rgba(0,0,0,.3);будет гарантировано , чтобы покрыть весь экран
Prinzhorn
2
@VilleKoo вы можете добавить его за 1000px линию и держать это как падение назад
Prinzhorn
19

Вы можете создать SVG-файл, заполненный траекторией с отверстием там, где оно вам нужно. Но я предполагаю, что вам нужно найти способ обрабатывать клики, поскольку все они будут нацелены на наложенный svg. Я document.getElementFromPointмогу помочь тебе здесь. mdn

Филипп
источник
Я думаю, что форма обратной связи Google использует svg для затемнения зоны отдыха.
Дурга
3

Это также можно сделать аналогично ответу @VilleKoo, но с рамкой.

div {
    border-style: solid;
    border-color: rgba(0,0,0,.3);
    pointer-events: none;
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
    border-width: 40px 300px 50px 60px;
}
<div></div>

Дэн
источник
2

Вы можете добиться того же, что и в ответе VilleKoo, используя outlineсвойство CSS . Он имеет отличную поддержку браузера (а также работает в IE8 +). Контуры имеют тот же синтаксис, что и границы, но в отличие от границы они не занимают места, они рисуются над содержимым.

Также для IE9 + вы можете заменить 99999pxна calc(100 * (1vh + 1vw - 1vmin)).

Недостатком такого подхода является то, что на outlineнего не влияет border-radius.

Демо:

div {
  position: fixed;
  width: 200px;
  height: 200px;
  top: 50px;
  left: 50px;
  /* IE8 */
  outline: 99999px solid rgba(0,0,0,.3);
  /* IE9+ */
  outline: calc(100 * (1vw + 1vh - 1vmin)) solid rgba(0,0,0,.3);
  /* for other browsers */
  outline: 100vmax solid rgba(0,0,0,.3);
  pointer-events: none;
}
<div></div>

Вадим Овчинников
источник
0

Вот простой код jQuery с использованием @VilleKoo css

var Dimmer = (function(){
  var el = $(".dimmer");
  
  return {
    showAt: function(x, y) {
      el
        .css({
          left: x,
          top: y,
        })
        .removeClass("hidden");
    },
    
    hide: function() {
      el.addClass("hidden");
    }
  }
}());


$(".btn-hide").click(function(){ Dimmer.hide(); });
$(".btn-show").click(function(){ Dimmer.showAt(50, 50); });
.dimmer {
  position: fixed;
  width: 200px;
  height: 200px;
  top: 50px;
  left: 50px;
  box-shadow: 0 0 0 1000px rgba(0,0,0,.3); /* for IE */
  box-shadow: 0 0 0 100vmax rgba(0,0,0,.3); /* for real browsers */
  pointer-events: none;
}

.hidden { display: none; }
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>

  <div>
    <input type="text">
    <select name="" id=""></select>
    <input type="checkbox">
  </div>
  <div>
    <input type="text">
    <select name="" id=""></select>
    <input type="checkbox">
  </div>
  <div>
    <input type="text">
    <select name="" id=""></select>
    <input type="checkbox">
  </div>
  <div>
    <input type="submit" disabled>
  </div>
  
  <input type="button" value="Hide" class="btn-hide">
  <input type="button" value="Show" class="btn-show">
  <div class="dimmer hidden"></div>
  <script src="https://code.jquery.com/jquery-2.2.4.js"></script>
</body>
</html>

Буксы
источник
0
#bg {
   background-color: gray;
   opacity: 0.6;
   position: absolute;
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
   z-index: 99998;
}
#hole {
   position: fixed;
   top: 100px;
   left: 100px;
   width: 100px;
   height: 100px;
   z-index: 99999;
}
Зерднелемо
источник