Cómo hacer que las esquinas redondeadas CSS3 oculten el desbordamiento en Chrome / Opera


147

Necesito esquinas redondeadas en un div padre para enmascarar el contenido de su niño. overflow: hiddenfunciona en situaciones simples, pero se rompe en los navegadores basados ​​en webkit y Opera cuando el padre está posicionado de forma relativa o absoluta.

Esto funciona en Firefox e IE9:

CSS

#wrapper {
  width: 300px;
  height: 300px;
  border-radius: 100px;
  overflow: hidden;
  position: absolute;
}

#box {
  width: 300px;
  height: 300px;
  background-color: #cde;
}

HTML

<div id="wrapper">
  <div id="box"></div>
</div>

Ejemplo en JSFiddle

¡Gracias por la ayuda!

ACTUALIZACIÓN: El error que causa este problema se ha solucionado desde Chrome. Sin embargo, no he vuelto a probar Opera o Safari.

Respuestas:


183

Encontré otra solución para este problema. Esto parece otro error en WebKit (o probablemente Chrome), pero funciona. Todo lo que necesita hacer es agregar una máscara CSS de WebKit al elemento #wrapper. Puede usar una imagen png de un solo píxel e incluso incluirla en el CSS para guardar una solicitud HTTP.

#wrapper {
width: 300px; height: 300px;
border-radius: 100px;
overflow: hidden;
position: absolute; /* this breaks the overflow:hidden in Chrome/Opera */

/* this fixes the overflow:hidden in Chrome */
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
}

#box {
width: 300px; height: 300px;
background-color: #cde;
}​

JSFiddle Ejemplo


3
gracias por esta solucion ¡Lo probé en safari hoy (v6.0.2) y funcionó para mí allí!
billythetalented

66
Sin embargo, esto romperá cualquier sombra en el elemento.
Jack James

1
Esto también funciona en envoltorios con niños absolutamente posicionados, donde la otra solución aquí no lo hace. ¡Agradable!
Dan Tello

2
usando Chrome 42.0.2311.90 (64 bits), y esta solución aún es necesaria ... ¡gracias!
Simon

2
Sus soluciones eliminan las sombras del elemento padre.
ABDeveloper

106

Agregue un índice z a su elemento de radio de borde y enmascarará las cosas dentro de él.


@Sifu: simplemente estás equivocado. Por alguna razón, agregar un índice z como se sugirió resolvió este problema exacto para mí (en la versión actual de Chrome), y esta es una solución más simple y más general que la respuesta principal.
Nick F

77
@simon: recuerde que para que el índice z tenga efecto, se deben cumplir ciertas condiciones (por ejemplo, se debe establecer la posición). Ver aquí para más detalles.
Nick F

@NickF: fue un error en Chrome (-ium); -webkit-mask-image: -webkit-radial-gradient(circle, white, black);fue una solución efectiva, pero, afortunadamente, el error se solucionó en la actualización más reciente que recibí en Chrome.
Simon

z-index 1 al contenedor. z-index -1 al elemento absoluto lo resolvió para mí.
aZtraL-EnForceR

Este me funcionó. La solución de envoltura anterior no lo hace.
Ruwen

58

Sin importarles a todos, logré resolver el problema agregando un div adicional entre el contenedor y la caja.

CSS

#wrapper {
    position: absolute;
}

#middle {
    border-radius: 100px;
    overflow: hidden; 
}

#box {
    width: 300px; height: 300px;
    background-color: #cde;
}

HTML

<div id="wrapper">
    <div id="middle">
        <div id="box"></div>
    </div>
</div>

¡Gracias a todos los que ayudaron!

http://jsfiddle.net/5fwjp/


12
Esto funciona porque los elementos posicionados no recortan su contenido a su radio de borde en Webkit. Esta capa adicional simplemente hace que el div con radio de borde NO esté posicionado, y simplemente se sienta dentro de un elemento posicionado.
Daniel Beardsley

9
¿Sabrá por casualidad si se trata de un error / comportamiento previsto?
jmotes

44
+1 voto al error ... Cuando tiene una galería de imágenes que genera automáticamente los divs y establece la posición en absoluta, entonces esta "característica" realmente sux ...
inf3rno

@RunLoop Acabo de probar el jsfiddle en Safari 7.1 y funciona bien. ¿Puedes ser más específico sobre lo que no funciona?
jmotes

1
Nuestro colega el diseñador gráfico realmente "descubrió" esto 20 segundos antes de encontrar esta respuesta: D
Pere

18

opacidad: 0.99; en el contenedor resuelve el error del webkit


2
transform: translateY(0);es una alternativa que logra el mismo resultado sin interferir con la representación visual del objeto (a menos que esté utilizando la perspectiva).
kontur

15

Parece que este funciona:

.wrap {
    -webkit-transform: translateZ(0);
    -webkit-mask-image: -webkit-radial-gradient(circle, white 100%, black 100%);
}

http://jsfiddle.net/qWdf6/82/


44
transform: translateZ(0)es suficiente para mi
kalvn

Tenga en cuenta que esto (en particular translateZ) habilitará implícitamente la aceleración de hardware para sus elementos, lo que abre una nueva lata de gusanos en algunos casos, lamentablemente.
doldt

transform: translateZ(0)También funcionó para mí. En mi caso, no es una mala idea que este artículo sea acelerado por hardware.
Sebastien Lorber

9

Compatible con el último Chrome, Opera y Safari, puedes hacer esto:

-webkit-clip-path: inset(0 0 0 0 round 100px);
clip-path: inset(0 0 0 0 round 100px);

¡Definitivamente deberías consultar la herramienta http://bennettfeely.com/clippy/ !


Creo que puede acortar esta ruta de clip aún más : inserción (0%); ... solo tener un camino de clip parece ser el truco :-)
Jakob E

Guau. Es la respuesta perfecta.
Shashank Bhatt




2

basado en la excelente respuesta de graycrow ...

Aquí hay un ejemplo más real del mundo que tiene dos divs ciculares con algún contenido de relleno. Reemplacé el fondo png codificado con solo un valor hexadecimal, es decir

-=-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);

se reemplaza con

-webkit-mask-image:#fff;

Ver este JSFiddle ... http://jsfiddle.net/hqLkA/


1

Aquí mira cómo lo hice; Jsfiddle

Con el Código que puse, logré que funcionara en Webkit (Chrome / Safari) y Firefox. No sé si funciona con la última versión de Opera. Sí, funciona con la última versión de Opera.

#wrapper {
  width: 300px; height: 300px;
  border-radius: 100px;
  overflow: hidden;
  position: absolute; /* this breaks the overflow:hidden in Chrome/Opera */
}

#box {
  width: 300px; height: 300px;
  background-color: #cde;
  border-radius: 100px;
  -webkit-border-radius: 100px;
  -moz-border-radius: 100px;
  -o-border-radius: 100px;
}

Por qué molestarse en poner el border-radiusenvoltorio en esa situación, obtienes el mismo resultado con solo encenderlo #box. Además, si el #boxradio del borde es solo para arreglar WebKit, podría incluir la -webkit-propiedad allí.
robertc

Laberinto, esto podría funcionar en algunas situaciones, pero en mi caso estoy buscando una solución que no transforme la forma de la caja (y el envoltorio todavía funciona como una máscara). Mi ejemplo fue muy simplificado, pero estoy tratando de usar el contenedor para ocultar la sombra de la caja (usando relleno en el contenedor para hacer visibles solo los bordes de las sombras que quiero).
jmotes

1
Gracias por la ayuda, aunque Maze! Su solución me ayudó a pensar sobre el problema de manera más crítica. Por cierto, puedes ignorar la edición que hice en tu publicación. Tenía la intención de hacerlo por mi cuenta. Lo siento :)
jmotes

@ user480837 No hay problema amigo, me alegro de haber sido de ayuda. :)
Laberinto

1
@Maze Eso no funcionará si se aplica un borde de cualquier tipo: jsfiddle.net/ptW85/228
antitóxico

1

Intenté cada respuesta pero sin éxito. Después de algunas horas de investigación, encontré una solución para este problema. El uso de estas propiedades en su clase no permitirá que los elementos div desborden el contenedor.

.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
}

0

Si está buscando crear una máscara para una imagen y colocar la imagen dentro del contenedor, no establezca el atributo 'position: absolute'. Todo lo que tiene que hacer es cambiar el margen izquierdo y el margen derecho. Chrome / Opera se adherirá al desbordamiento: reglas ocultas y de radio de borde.

// Breaks in Chrome/Opera.
    .container {
        overflow: hidden;
        border-radius: 50%;
        img {
            position: absolute;
            left: 20px;
            right: 20px;
        }
    }

// Works in Chrome/Opera.
    .container {
        overflow: hidden;
        border-radius: 50%;
        img {
            margin-left: 20px;
            margin-right: 20px;
        }
    }
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.