Comment puis-je faire fonctionner un effet de verre / flou CSS pour une superposition?

105

J'ai du mal à appliquer un effet de flou sur une div superposition semi-transparente. J'aimerais que tout ce qui se trouve derrière la div soit flou, comme ceci:

Image SFW

Voici un jsfiddle qui ne fonctionne pas: http://jsfiddle.net/u2y2091z/

Des idées pour faire fonctionner cela? J'aimerais que cela soit aussi simple que possible et que ce soit multi-navigateur. Voici le CSS que j'utilise:

#overlay {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;

    background:black;
    background:rgba(0,0,0,0.8);

    filter:blur(4px);
    -o-filter:blur(4px);
    -ms-filter:blur(4px);
    -moz-filter:blur(4px);
    -webkit-filter:blur(4px);
}
Chad Johnson
la source
1
FYI - CSS filtern'est pas pris en charge sur Firefox, vous ne devriez pas l'utiliser.
Weafs.py
2
Peut-être rendre le div opaque mais utiliser un pseudo élément avec l'image comme arrière-plan qui peut être flou indépendamment.
bjb568
1
@ chipChocolate.py Les filtres CSS sont pris en charge par défaut dans FF35 +. Mais je suis d'accord avec vous, nous, les développeurs, ne devrions pas nous y fier car ce n'est pas une fonctionnalité multi-navigateurs.
Hashem Qolami

Réponses:

73

Pour une réponse plus simple et à jour:

backdrop-filter: blur(6px);

Notez que la prise en charge du navigateur n'est pas parfaite, mais dans la plupart des cas, un flou ne serait pas essentiel.

Jon Catmull
la source
1
C'est de loin la meilleure réponse.
tanner burton le
71

Voici un exemple qui utilise le svgfiltre.

L'idée est d'utiliser un svgélément avec le heightmême que le #overlayet d'y appliquer le feGaussianblurfiltre. Ce filtre est appliqué sur un svg imageélément. Pour lui donner un effet extrudé, vous pouvez utiliser un box-shadowen bas de la superposition.

Support du navigateur pour les svgfiltres .

Demo on Codepen

body {
  background: #222222;
}
#container {
  position: relative;
  width: 450px;
  margin: 0 auto;
}
img {
  height: 300px;
}
#overlay {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  z-index: 1;
  color: rgba(130, 130, 130, 0.5);
  font-size: 50px;
  text-align: center;
  line-height: 100px;
  box-shadow: 0 3px 5px rgba(0, 0, 0, 0.3);
}
<div id="container">
  <img src="http://lorempixel.com/450/300/sports" />
  <div id="overlay">WET</div>
  <svg width="450" height="100" viewBox="0 0 450 100" style="position: absolute; top: 0;">
    <defs>
      <filter id="blur">
        <feGaussianBlur in="SourceGraphic" stdDeviation="3" />
      </filter>
    </defs>
    <image filter="url(#blur)" xlink:href="http://lorempixel.com/450/300/sports" x="0" y="0" height="300px" width="450px" />
  </svg>
</div>

Weafs.py
la source
51

J'ai pu rassembler des informations de tout le monde ici et plus loin sur Google, et j'ai trouvé ce qui suit qui fonctionne dans Chrome et Firefox: http://jsfiddle.net/xtbmpcsu/ . Je travaille toujours sur ce travail pour IE et Opera.

La clé consiste à placer le contenu à l' intérieur du div auquel le filtre est appliqué:

<div id="mask">
    <p>Lorem ipsum ...</p>
    <img src="http://www.byui.edu/images/agriculture-life-sciences/flower.jpg" />
</div>

Et puis le CSS:

body {
    background: #300000;
    background: linear-gradient(45deg, #300000, #000000, #300000, #000000);
    color: white;
}
#mask {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    background-color: black;
    opacity: 0.5;
}
img {
    filter: blur(10px);
    -webkit-filter: blur(10px);
    -moz-filter: blur(10px);
    -o-filter: blur(10px);
    -ms-filter: blur(10px);
    position: absolute;
    left: 100px;
    top: 100px;
    height: 300px;
    width: auto;
}

Donc, le masque a les filtres appliqués. Notez également l'utilisation de url () pour un filtre avec une <svg>balise pour la valeur - cette idée est venue de http://codepen.io/AmeliaBR/pen/xGuBr . Si vous réduisez votre CSS, vous devrez peut-être remplacer les espaces du balisage du filtre SVG par "% 20".

Alors maintenant, tout à l'intérieur du masque div est flou.

Chad Johnson
la source
c'est tellement intelligent
Gangsar Swapurba
3
Chrome n'aime pas la finale filter: url(.... Supprimez cela et Chrome utilise avec succès filter: blur(10px);.
Doug S
2
Ai-je mal compris? Ce n'est pas ce que veut l'OP. Les textes ne doivent pas être flous.
Eric
2
@Eric, vous vous méprenez clairement, puisque le répondeur est l'OP.
tao
10

Si vous recherchez aujourd'hui une approche multi-navigateurs fiable , vous n'en trouverez pas une excellente. La meilleure option que vous avez est de créer deux images (cela peut être automatisé dans certains environnements) et de les organiser de telle sorte que l'une se superpose à l'autre. J'ai créé un exemple simple ci-dessous:

<figure class="js">
    <img src="http://i.imgur.com/3oenmve.png" />
    <img src="http://i.imgur.com/3oenmve.png?1" class="blur" />
</figure>
figure.js {
    position: relative;
    width: 250px; height: 250px;
}

figure.js .blur {
    top: 0; left: 0;
    position: absolute;
    clip: rect( 0, 250px, 125px, 0 );
}

Bien qu'efficace, même cette approche n'est pas nécessairement idéale. Cela étant dit, cela donne le résultat souhaité .

entrez la description de l'image ici

Sampson
la source
8

Voici une solution possible.

HTML

<img id="source" src="http://www.byui.edu/images/agriculture-life-sciences/flower.jpg" />

<div id="crop">
    <img id="overlay" src="http://www.byui.edu/images/agriculture-life-sciences/flower.jpg" />
</div>

CSS

#crop {
    overflow: hidden;

    position: absolute;
    left: 100px;
    top: 100px;

    width: 450px;
    height: 150px;
}

#overlay {
    -webkit-filter:blur(4px);
    filter:blur(4px);

    width: 450px;
}

#source {
    height: 300px;
    width: auto;
    position: absolute;
    left: 100px;
    top: 100px;
}

Je sais que le CSS peut être simplifié et que vous devriez probablement vous débarrasser des identifiants. L'idée ici est d'utiliser un div comme conteneur de recadrage, puis d'appliquer un flou sur la duplication de l'image. Violon

Pour que cela fonctionne dans Firefox, vous devrez utiliser le piratage SVG .

Juho Vepsäläinen
la source
@ chipChocolate.py Je suppose que vous devez utiliser le piratage SVG dans ce cas, demosthenes.info/blog/534/Crossbrowser-Image-Blur .
Juho Vepsäläinen
Notez que pour le filtre CSS, vous pouvez omettre les préfixes de fournisseur autrement que -webkit-car il n'est pas implémenté dans ces navigateurs. Il est préférable de mettre la déclaration standard à la fin - après toutes les versions préfixées.
Hashem Qolami
@HashemQolami Terminé. Merci.
Juho Vepsäläinen
FF est OK, maintenant (54.0.1 (32 bits)). Juste parfait! Tx!
Pedro Ferreira
7
background: rgba(255,255,255,0.5);
backdrop-filter: blur(5px);

Au lieu d'ajouter un autre arrière-plan flou à votre contenu, vous pouvez utiliser le filtre de fond . FYI IE 11 et Firefox peuvent ne pas le prendre en charge. Vérifiez caniuse .

Démo:

header {
  position: fixed;
  width: 100%;
  padding: 10px;
  background: rgba(255,255,255,0.5);
  backdrop-filter: blur(5px);
}
body {
  margin: 0;
}
<header>
  Header
</header>
<div>
  <img src="https://dummyimage.com/600x400/000/fff" />
  <img src="https://dummyimage.com/600x400/000/fff" />
  <img src="https://dummyimage.com/600x400/000/fff" />
</div>

Allen Wong
la source
La même solution a déjà été proposée: stackoverflow.com/a/58083568/3702797
Kaiido du
4

#bg, #search-bg {
  background-image: url('https://images.pexels.com/photos/719609/pexels-photo-719609.jpeg?w=940&h=650&auto=compress&cs=tinysrgb');
  background-repeat: no-repeat;
  background-size: 1080px auto;
}

#bg {
  background-position: center top;
  padding: 70px 90px 120px 90px;
}

#search-container {
  position: relative;
}

#search-bg {
  /* Absolutely position it, but stretch it to all four corners, then put it just behind #search's z-index */
  position: absolute;
  top: 0px;
  right: 0px;
  bottom: 0px;
  left: 0px;
  z-index: 99;

  /* Pull the background 70px higher to the same place as #bg's */
  background-position: center -70px;

  -webkit-filter: blur(10px);
  filter: url('/media/blur.svg#blur');
  filter: blur(10px);
}

#search {
  /* Put this on top of the blurred layer */
  position: relative;
  z-index: 100;
  padding: 20px;
  background: rgb(34,34,34); /* for IE */
  background: rgba(34,34,34,0.75);
}

@media (max-width: 600px ) {
  #bg { padding: 10px; }
  #search-bg { background-position: center -10px; }
}

#search h2, #search h5, #search h5 a { text-align: center; color: #fefefe; font-weight: normal; }
#search h2 { margin-bottom: 50px }
#search h5 { margin-top: 70px }
<div id="bg">
  <div id="search-container">
    <div id="search-bg"></div>
    <div id="search">
      <h2>Awesome</h2>
      <h5><a href="#">How it works »</a></h5>
    </div>
  </div>
</div>

prajeesh loremine
la source
1

J'ai trouvé cette solution.

Cliquez pour voir l'image de l'effet flou

C'est une sorte d'astuce qui utilise un enfant positionné de manière absolue div, définit son image d'arrière-plan de la même manière que le parent divet utilise ensuite la background-attachment:fixedpropriété CSS avec les mêmes backgroundpropriétés définies sur l'élément parent.

Ensuite, vous appliquez filter:blur(10px)(ou toute valeur) sur le div enfant.

*{
    margin:0;
    padding:0;
    box-sizing: border-box;
}
.background{
    position: relative;
    width:100%;
    height:100vh;
    background-image:url('https://images.unsplash.com/photo-1547937414-009abc449011?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80');
    background-size:cover;
    background-position: center;
    background-repeat:no-repeat;
}

.blur{
    position: absolute;
    top:0;
    left:0;
    width:50%;
    height:100%;
    background-image:url('https://images.unsplash.com/photo-1547937414-009abc449011?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80');
    background-position: center;
    background-repeat: no-repeat;
    background-attachment: fixed;
    background-size:cover;
    filter:blur(10px);
    transition:filter .5s ease;
    backface-visibility: hidden;
}

.background:hover .blur{
    filter:blur(0);
}
.text{
    display: inline-block;
    font-family: sans-serif;
    color:white;
    font-weight: 600;
    text-align: center;
    position: relative;
    left:25%;
    top:50%;
    transform:translate(-50%,-50%);
}
<head>
    <title>Blurry Effect</title>
</head>
<body>
    <div class="background">
        <div class="blur"></div>
        <h1 class="text">This is the <br>blurry side</h1>
    </div>
</body>
</html>

vue sur codepen

CptGeo
la source
0

Voici une solution qui fonctionne avec des arrière-plans fixes, si vous avez un arrière-plan fixe et que vous avez des éléments superposés et que vous avez besoin d'arrière-plans estompés pour eux, cette solution fonctionne:

Image, nous avons ce HTML simple:

<body> <!-- or any wrapper -->
   <div class="content">Some Texts</div>
</body>

Un arrière-plan fixe pour <body>ou l'élément wrapper:

body {
  background-image: url(http://placeimg.com/640/360/any);
  background-size: cover;
  background-repeat: no-repeat;
  background-attachment: fixed;
}

Et ici par exemple, nous avons un élément superposé avec un fond transparent blanc:

.content {
  background-color: rgba(255, 255, 255, 0.3);
  position: relative;
}

Maintenant, nous devons utiliser exactement la même image d'arrière-plan de notre wrapper pour nos éléments de superposition, je l'utilise comme une :beforeclasse psuedo:

.content:before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  filter: blur(5px);
  background-image: url(http://placeimg.com/640/360/any);
  background-size: cover;
  background-repeat: no-repeat;
  background-attachment: fixed;
}

Étant donné que l'arrière-plan fixe fonctionne de la même manière dans les éléments wrapper et superposés, nous avons l'arrière-plan exactement dans la même position de défilement que l'élément superposé et nous pouvons simplement le rendre flou. Voici un violon fonctionnel, testé dans Firefox, Chrome, Opera et Edge: https://jsfiddle.net/0vL2rc4d/

REMARQUE: dans Firefox, il existe un bogue qui fait scintiller l'écran lors du défilement et des arrière-plans flous sont fixes. s'il y a une solution, faites le moi savoir

Amin
la source
0

Cela fera la superposition de flou sur le contenu:

.blur{
 display:block;
 bottom: 0;
 left: 0;
 position: fixed;
 right: 0;
 top: 0;
 -webkit-backdrop-filter: blur(15px);
 backdrop-filter: blur(15px);
 background-color: rgba(0, 0, 0, .5);
}
Magnettoo
la source