Come fare in modo che gli angoli arrotondati CSS3 nascondano l'overflow in Chrome / Opera


147

Ho bisogno di angoli arrotondati su un div genitore per mascherare il contenuto dai suoi figli. overflow: hiddenfunziona in situazioni semplici, ma interrompe i browser basati su webkit e Opera quando il genitore è posizionato in modo relativo o assoluto.

Funziona con 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>

Esempio su JSFiddle

Grazie per l'aiuto!

AGGIORNAMENTO: il bug che causa questo problema è stato risolto da Chrome. Non ho ancora testato nuovamente Opera o Safari.

Risposte:


183

Ho trovato un'altra soluzione per questo problema. Sembra un altro bug in WebKit (o probabilmente Chrome), ma funziona. Tutto quello che devi fare - è aggiungere una maschera CSS WebKit all'elemento #wrapper. Puoi usare un'immagine png a singolo pixel e persino includerla nel CSS per salvare una richiesta 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;
}​

Esempio JSFiddle


3
grazie per questa correzione. provato oggi in Safari (v6.0.2) e ha funzionato per me lì!
Billythetalented

6
questo romperà comunque eventuali ombre sull'elemento.
Jack James,

1
Funziona anche con wrapper con bambini posizionati in modo assoluto, dove l'altra soluzione qui no. Bello!
Dan Tello,

2
utilizzando Chrome 42.0.2311.90 (64 bit) e questa correzione è ancora necessaria ... grazie!
simon,

2
le tue soluzioni rimuovono le ombre dell'elemento genitore.
ABDeveloper

107

Aggiungi un indice z al tuo oggetto con raggio di confine e maschererà le cose al suo interno.


@Sifu: ti sbagli semplicemente. Per qualsiasi motivo, l'aggiunta di un indice z come suggerito ha risolto questo esatto problema per me (nella versione corrente di Chrome), e questa è una soluzione più semplice e più generale della risposta migliore.
Nick F,

7
@simon: ricorda che affinché z-index abbia effetto, devono essere soddisfatte determinate condizioni (es. posizione deve essere impostata). Vedi qui per i dettagli.
Nick F,

@NickF - era un bug in Chrome (-ium); -webkit-mask-image: -webkit-radial-gradient(circle, white, black);è stata una soluzione efficace, ma, per fortuna, il bug è stato corretto nell'ultimo aggiornamento che ho ricevuto su Chrome.
simon

z-index 1 al contenitore. z-index -1 all'elemento assoluto lo ha risolto per me.
aZtraL-EnForceR

Questo ha funzionato per me. La soluzione wrapper sopra non funziona.
Ruwen,

58

Non importa a tutti, sono riuscito a risolvere il problema aggiungendo un ulteriore div tra il wrapper e la scatola.

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>

Grazie a tutti coloro che hanno aiutato!

http://jsfiddle.net/5fwjp/


12
Questo funziona perché gli elementi posizionati non agganciano i loro contenuti al loro raggio di confine in Webkit. Questo strato aggiuntivo lo rende semplicemente in modo tale che il div con raggio del bordo NON sia posizionato e si trovi semplicemente all'interno di un elemento posizionato.
Daniel Beardsley,

9
Sapresti per caso se si tratta di un bug / comportamento previsto?
jmotes,

4
+1 voto per bug ... Quando hai una galleria di immagini che genera automaticamente i div e imposta la posizione su assoluta, allora questa "caratteristica" è davvero sux ...
inf3rno

@RunLoop Ho appena testato jsfiddle in Safari 7.1 e funziona benissimo. Puoi essere più specifico su ciò che non funziona?
jmotes

1
Il nostro collega il graphic designer in realtà "scoperto" 20 secondi prima di trovare questa risposta: D
Pere

18

opacità: 0,99; sul wrapper risolve il bug del webkit


2
transform: translateY(0);è un'alternativa che ottiene lo stesso risultato senza interferire con la rappresentazione visiva dell'oggetto (a meno che non si stia utilizzando la prospettiva).
kontur

15

Sembra che questo funzioni:

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

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


4
transform: translateZ(0)è abbastanza per me.
Kalvn,

Nota che questo (in particolare translateZ) abiliterà implicitamente l'accelerazione hardware dei tuoi elementi, che in alcuni casi apre una nuovissima lattina di worm, purtroppo.
Doldt,

transform: translateZ(0)ha funzionato anche per me. Nel mio caso non è una cattiva idea che questo articolo sia accelerato dall'hardware.
Sebastien Lorber,

9

Supportato negli ultimi Chrome, Opera e Safari, puoi farlo:

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

Dovresti assolutamente dare un'occhiata allo strumento http://bennettfeely.com/clippy/ !


Penso che puoi abbreviare ancora di più questo percorso di clip: inset (0%); ... solo avere un percorso di clip sembra fare il trucco :-)
Jakob E

Wow. È la risposta perfetta
Shashank Bhatt,




2

basato sull'ottima risposta di Graycrow ...

Ecco un esempio più reale del mondo che ha due div cicolari con alcuni contenuti di riempimento. Ho sostituito lo sfondo PNG hard-coded con solo un valore esadecimale, vale a dire

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

è sostituito da

-webkit-mask-image:#fff;

Vedi questo JSFiddle ... http://jsfiddle.net/hqLkA/


1

Qui guarda come l'ho fatto; Jsfiddle

Con il codice che ho inserito, sono riuscito a farlo funzionare su Webkit (Chrome / Safari) e Firefox. Non so se funziona con l'ultima versione di Opera. Sì, funziona con l'ultima versione di 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;
}

Perché preoccuparti di mettere il border-radiuswrapper on in quella situazione, ottieni lo stesso risultato semplicemente impostandolo #box. Inoltre, se il #boxraggio del bordo serve solo a correggere WebKit, puoi semplicemente includere la -webkit-proprietà lì.
robertc,

Labirinto, questo potrebbe funzionare in alcune situazioni, ma nel mio caso sto cercando una soluzione che non trasformi la forma della scatola (e l'involucro funziona ancora come una maschera). Il mio esempio è stato molto semplificato, ma sto cercando di usare il wrapper per nascondere il dropshadow dalla scatola (usando l'imbottitura sul wrapper per rendere visibili solo i bordi dell'ombra).
jmotes,

1
Grazie per l'aiuto però Maze! La tua soluzione mi ha aiutato a pensare al problema in modo più critico. A proposito, puoi ignorare la modifica che ho apportato al tuo post. Volevo farcela da solo. Mi dispiace :)
jmotes

@ user480837 Nessun problema amico, felice di essere stato di aiuto. :)
Maze,

1
@Maze Che non funzionerà se viene applicato un bordo di qualsiasi tipo: jsfiddle.net/ptW85/228
antitossico

1

Ho provato tutte le risposte ma senza successo. Dopo alcune ore di investigazione ho trovato la soluzione a questo problema. L'uso di queste proprietà nella classe non consentirà agli elementi div di traboccare il contenitore.

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

0

Se stai cercando di creare una maschera per un'immagine e posizionare l'immagine all'interno del contenitore, non impostare l'attributo 'position: absolute'. Tutto quello che devi fare è cambiare il margine sinistro e il margine destro. Chrome / Opera aderirà all'overflow: regole nascoste e border-radius.

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