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


88

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

Проблема в тому, що я не можу знайти спосіб "скасувати" батьківський background-color(що також прозоро).

У фрагменті нижче hole- div, який повинен бути без жодного 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 .
вітер

2
Це лише пропозиція щодо lib: heelhook.github.io/chardin.js
онлайн Томас

Відповіді:


125

Ви можете зробити це лише з одним divі дати йому a box-shadow.

РЕДАГУВАТИ: як зазначив @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>


28
Не забудьте додати, pointer-events: noneякщо хочете, щоб область під нею була клікабельною.
Нік Швелидзе

4
1000 пікселів мені здається недостатньо - здається, було б занадто багато випадків, коли це не заповнювало б екран, інакше справді розумне рішення.
ESR

1
@EdmundReed ви можете налаштувати це під свої потреби :)
VilleKoo

8
box-shadow: 0 0 0 100vmax rgba(0,0,0,.3);буде гарантовано охоплювати весь екран
Принцхорн,

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, використовуючи CSSoutline властивість . Він має чудову підтримку браузера (і працює також у 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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.