Oscurare l'intero schermo tranne un'area fissa?


88

Voglio creare un tutorial che guidi l'utente esattamente dove fare clic. Sto cercando di coprire l'intero schermo con una <div>che dim tutti gli elementi ad eccezione di una specifica regione , che si trova in un fisso width, height, tope left.

Il problema è che non riesco a trovare un modo per "cancellare" il genitore background-color(che è anche trasparente).

Nello snipped di seguito, holeè il div che dovrebbe essere senza background-color, compreso il suo genitore.

Può essere realizzato? Qualche idea?

#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>

Ecco un'immagine di mockup di ciò che sto cercando di ottenere:

inserisci qui la descrizione dell'immagine


13
Se stai creando un tour / tutorial delle funzionalità, potresti essere interessato a una delle librerie js per farlo. Hanno alcune funzionalità interessanti e ti risparmieranno la fatica di scrivere un sacco di effetti CSS unici. Visita introjs.com o linkedin.github.io/hopscotch .
ottobre

2
Questo è solo un suggerimento per un lib: heelhook.github.io/chardin.js
online Thomas

Risposte:


125

Potresti farlo con uno solo dive dargli un box-shadow.

EDIT: come ha sottolineato @Nick Shvelidze, dovresti considerare di aggiungerepointer-events: none

vmaxValore aggiunto per box-shadowcome suggerito da @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
Assicurati di aggiungere pointer-events: nonese desideri che l'area sottostante sia selezionabile.
Nick Shvelidze

4
1,000px non mi sembra abbastanza - sembra che ci sarebbero troppi casi in cui questo non riempie lo schermo, altrimenti una soluzione davvero intelligente.
ESR

1
@EdmundReed puoi adattarlo alle tue esigenze :)
VilleKoo

8
box-shadow: 0 0 0 100vmax rgba(0,0,0,.3);sarà garantito per coprire l'intero schermo
Prinzhorn

2
@VilleKoo puoi aggiungerlo dietro la linea dei 1000 px e mantenerlo come
alternativa

19

Puoi creare un SVG riempito con un percorso che ha il buco dove ne hai bisogno. Ma immagino che tu abbia bisogno di trovare un modo per gestire i clic, poiché tutti saranno indirizzati allo svg sovrapposto. Cosa document.getElementFromPointposso aiutarti qui. mdn


Penso che il modulo di feedback di Google utilizzi svg per oscurare l'area di sosta.
Durga

3

Questo può anche essere fatto in modo simile alla risposta di @ VilleKoo, ma con un bordo.

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

Puoi ottenere lo stesso risultato della risposta di VilleKoo usando la outlineproprietà CSS . Ha un eccellente supporto per il browser (e funziona anche in IE8 +). I contorni hanno la stessa sintassi dei bordi, ma a differenza del bordo non occupano spazio, vengono disegnati sopra il contenuto.

Anche per IE9 + puoi sostituire 99999pxcon calc(100 * (1vh + 1vw - 1vmin)).

Lo svantaggio di questo approccio è che outlinenon è influenzato da border-radius.

Demo:

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

Ecco un semplice codice jQuery usando @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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.