¿Cómo puedo hacer que un efecto de cristal / desenfoque CSS funcione para una superposición?


102

Tengo problemas para aplicar un efecto de desenfoque en un div de superposición semitransparente. Me gustaría que todo lo que hay detrás del div sea borroso, así:

Imagen SFW

Aquí hay un jsfiddle que no funciona: http://jsfiddle.net/u2y2091z/

¿Alguna idea de cómo hacer que esto funcione? Me gustaría que esto sea lo más sencillo posible y que sea entre navegadores. Aquí está el CSS que estoy usando:

#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);
}

1
FYI: CSS filterno es compatible con Firefox, no debería usarlo.
Weafs.py

2
Tal vez haga que el div sea opaco, pero use un pseudo elemento con la imagen como fondo que se puede difuminar de forma independiente.
bjb568

1
Los filtros CSS @ chipChocolate.py son compatibles con FF35 + de forma predeterminada. Pero estoy de acuerdo con usted, nosotros, como desarrolladores, no deberíamos confiar en él, ya que no es una función de varios navegadores.
Hashem Qolami

Respuestas:


71

Aquí hay un ejemplo que usa svgfilter.

La idea es usar un svgelemento con lo heightmismo que #overlayy aplicarle el feGaussianblurfiltro. Este filtro se aplica a un svg imageelemento. Para darle un efecto extruido, puede usar un box-shadowen la parte inferior de la superposición.

Soporte de navegador para svgfiltros .

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>



51

Pude reunir información de todos aquí y buscar más en Google, y se me ocurrió lo siguiente que funciona en Chrome y Firefox: http://jsfiddle.net/xtbmpcsu/ . Todavía estoy trabajando para que esto funcione para IE y Opera.

La clave es poner el contenido dentro del div al que se aplica el filtro:

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

Y luego el 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;
}

Entonces la máscara tiene los filtros aplicados. Además, tenga en cuenta el uso de url () para un filtro con una <svg>etiqueta para el valor; esa idea vino de http://codepen.io/AmeliaBR/pen/xGuBr . Si minimiza su CSS, es posible que deba reemplazar cualquier espacio en el marcado del filtro SVG con "% 20".

Entonces, todo dentro de la máscara div está borroso.


es tan inteligente
Gangsar Swapurba

3
A Chrome no le gusta la final filter: url(.... Elimina eso y Chrome lo usa con éxito filter: blur(10px);.
Doug S

2
¿Lo entendí mal? No es lo que quiere el OP. Los textos no deben estar borrosos.
Eric

2
@Eric, claramente lo malinterpretas, ya que el que responde es el OP.
tao

10

Si está buscando un enfoque confiable entre navegadores hoy en día , no encontrará uno excelente. La mejor opción que tiene es crear dos imágenes (esto podría automatizarse en algunos entornos) y organizarlas de manera que una se superponga a la otra. He creado un ejemplo simple a continuación:

<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 );
}

Aunque es efectivo, incluso este enfoque no es necesariamente ideal. Dicho esto, produce el resultado deseado .

ingrese la descripción de la imagen aquí


8

He aquí una posible solución.

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;
}

Sé que el CSS se puede simplificar y probablemente debería deshacerse de los identificadores. La idea aquí es usar un div como contenedor de recorte y luego aplicar desenfoque en un duplicado de la imagen. Violín

Para que esto funcione en Firefox, tendrías que usar el hack de SVG .


@ chipChocolate.py Supongo que necesitas usar el truco SVG en ese caso, entonces, demosthenes.info/blog/534/Crossbrowser-Image-Blur .
Juho Vepsäläinen

Tenga en cuenta que para el filtro CSS, puede omitir los prefijos de proveedor que no sean -webkit-porque no está implementado en esos navegadores. Es mejor poner la declaración estándar al final, después de todas las versiones con prefijo.
Hashem Qolami

@HashemQolami Hecho. Gracias.
Juho Vepsäläinen

FF está bien, ahora (54.0.1 (32 bits)). ¡Simplemente perfecto! Tx!
Pedro Ferreira

6
background: rgba(255,255,255,0.5);
backdrop-filter: blur(5px);

En lugar de agregar otro fondo borroso a su contenido, puede usar el filtro de fondo . FYI IE 11 y Firefox pueden no admitirlo. Compruebe caniuse .

Manifestación:

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>


Ya se ha propuesto la misma solución: stackoverflow.com/a/58083568/3702797
Kaiido

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>


1

Se me ocurrió esta solución.

Haga clic para ver la imagen del efecto borroso

Es una especie de truco que usa un elemento secundario absolutamente posicionado div, establece su imagen de fondo igual que la principal divy luego usa la background-attachment:fixedpropiedad CSS junto con las mismas backgroundpropiedades establecidas en el elemento principal.

Luego aplica filter:blur(10px)(o cualquier valor) en el div hijo.

*{
    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>

ver en codepen


0

Aquí hay una solución que funciona con fondos fijos, si tiene un fondo fijo y tiene algunos elementos superpuestos y necesita fondos borrosos para ellos, esta solución funciona:

Imagen tenemos este sencillo HTML:

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

Un fondo fijo para <body>o el elemento contenedor:

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

Y aquí, por ejemplo, tenemos un elemento superpuesto con un fondo blanco transparente:

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

Ahora necesitamos usar exactamente la misma imagen de fondo de nuestro contenedor para nuestros elementos de superposición también, la uso como una :beforeclase 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;
}

Dado que el fondo fijo funciona de la misma manera tanto en el envoltorio como en los elementos superpuestos, tenemos el fondo exactamente en la misma posición de desplazamiento del elemento superpuesto y simplemente podemos desenfocarlo. Aquí hay un violín que funciona, probado en Firefox, Chrome, Opera y Edge: https://jsfiddle.net/0vL2rc4d/

NOTA: En Firefox hay un error que hace que la pantalla parpadee al desplazarse y hay fondos borrosos fijos. si hay alguna solución, avísame


0

Esto hará la superposición de desenfoque sobre el contenido:

.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);
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.