2014-12-17 19 views
6

Mentre stavo tentando di creare una figura animata (transizioni su hover), ho scoperto che lo sfondo del mio <figure> si mostra vicino ai bordi quando applico il raggio del bordo: il 50% ad esso, anche se il mio l'immagine dovrebbe occupare tutto lo spazio disponibile."bordo" frastagliato visualizzato a causa del colore di sfondo sull'elemento wrapper con raggio del bordo: 50%;

Per una demo veloce che illustra il problema, si prega di guardare http://codepen.io/anon/pen/KwMMKz

HTML

<figure> 
    <img src="http://placehold.it/400x400" alt> 
    <figcaption>Demo</figcaption> 
</figure> 

CSS

figure { 
    background-color: red; 
    width: 400px; 
    height: 400px; 
    border-radius: 50%; 
    overflow: hidden; 
    position: relative; /* For caption */ 

} 

img { 
    border-radius: 50%; /* Forced on image for smooth transition */ 
    width: 100%; 
    transition: opacity 1s ease-out; 
} 

figcaption { 
    position: absolute; 
    top: 100%; 
    left: 0; 
    width: 100%; 
    color: hotpink; 
    text-align: center; 
    transition: top 1s ease-out; 
} 
figure:hover img { 
    opacity: 0; 
} 
figure:hover figcaption { 
    top: 50%; 
} 

Si prega di notare: io so che l'immissione il backgroun d-color on figure: hover è un work-around, ma sono più interessato al motivo per cui questo look "border frastagliato" appare.

La mia ipotesi è che ha a che fare con il rendering AA (o qualcosa di simile) del browser e che tratta l'elemento <figure> in modo diverso da un elemento multimediale come <img>, ma non riesco a trovare alcuna prova di questo online . È un bug, è una "funzionalità" o è qualcosa che posso effettivamente risolvere?

Infine, so anche che avrei potuto usare transform: translateY(); qui per l'animazione, ma non fa parte della mia domanda quindi per favore non fornire come risposta.

UPDATE 17/12 14:03

Sembra che questo problema non è esclusivo border-radius: 50%. Il problema può verificarsi quando un elemento wrapping utilizza border-radius in combinazione con overflow: hidden, quando il wrapper contiene contenuto uguale o superiore alle dimensioni del wrapper.

UPDATE 17/12 14:14

Né l'utilizzo di overflow: hidden sull'elemento involucro, né l'uso di border-radius sull'immagine contenuta (o qualsiasi altro elemento figlio) sembrano essere la causa di questa poiché possono essere scambiati e il bordo pixelato apparirà ancora.

Questo sembra indicare che questo problema è causato unicamente dal fatto che 2 elementi DOM si trovano esattamente nella stessa posizione, quando qualsiasi tipo di raggio di bordo viene applicato all'elemento wrapper e l'area visibile del bambino è limitata a quella di i genitori.

+0

questo sembra essere lo stesso problema di questo post: [Pixelated edge around a CSS Circle with overflow: hidden;] (http://stackoverflow.com/questions/19882283/pixelated-edge-around-a-css- cerchio-con-overflow-nascosto) –

+0

La tua domanda sul leggerissimo (1px bordo rosso) o su quello al passaggio del mouse l'area grigia è un quadrato (mentre si dissolve) invece di un cerchio? – MMachinegun

+1

@ web-tiki è probabilmente correlato allo stesso problema di base, ma non riesco a vedere nessuna risposta in quel post che spieghi perché sta accadendo e se si tratta di un bug o meno. Perché questo si verifica solo questo effetto pixel si verifica solo sul raggio di confine: 50% quando 2 elementi devono incontrarsi nella stessa posizione? Non riesco a pensare a nessuna buona ragione per cui questo avvenga. –

risposta

0

Sembra che sia effettivamente una "funzione" di come il browser gestisce border-radius per dare un bordo liscio agli angoli arrotondati di un contenitore. Lo sfondo dell'immagine è anti-aliasato allo stesso modo (ma poiché è trasparente non ha alcun effetto) come si può vedere impostando il colore di sfondo img.

Quando il bordo è anti-aliasing "sanguina" sullo sfondo per ammorbidire i bordi e così si vede che intorno all'immagine come un anello "jaggy" più o meno allo stesso modo in cui si vedrebbe una corona attorno alla luna durante un'eclissi solare completa.

il problema è sempre lì, sia che l'oggetto anti-alias sia coperto o meno, se si dovesse disegnare un cerchio quindi anti-alias, si vedrebbe che il cerchio è marginalmente più stretto rispetto alla versione anti-alias. La maggior parte degli algoritmi anti-aliasing aggregano lo che circonda lo pixel dell'oggetto anziché quelli contenuti al suo interno.

Per superarlo, è necessario rendere l'immagine abbastanza grande da coprire lo spazio occupato dal bordo anti-alias o ridurre il contenitore in modo che l'area anti-alias sia più piccola dell'immagine.

+2

L'OP afferma esplicitamente che ------> _ "So che posizionare il colore di sfondo su figura: hover è un work-around, ma sono più interessato al motivo per cui questo aspetto di" bordo frastagliato " sta comparendo "_, il che significa che l'OP sta cercando una ragione e non una soluzione. –

+0

Grazie, ma non vedo come l'aggiunta di un colore di sfondo allo stato di hover possa funzionare, sicuramente dovrebbe essere sull'immagine. Aggiornato comunque per spiegare cosa sta succedendo. – Mauro

+1

@ Mauro: non è vero. Se aggiungi la figura: hover {background-color: red; } invece di definirlo su figura {}, lavorerai attorno ai bordi frastagliati. Detto questo, questo non è rilevante per la mia domanda, come sto chiedendo perché sta accadendo, non per soluzioni alternative come posso pensare a me stesso. –

0

http://codepen.io/marczking/pen/KwMgaR

Così, dopo aver giocato in giro (usato background-image e pseudo-elementi, non cambia nulla ...) si nota che questo confine la luce è visibile solo se si applica angoli arrotondati. Quindi io parto dal presupposto qui si ha a che fare come il browser rende il CSS, niente di sbagliato con i CSS-regole ^^)

<figure> 
    <figcaption>Demo</figcaption> 
</figure> 

figure { 
    background-color: red; 
    width: 400px; 
    height: 400px; 
    border-radius: 100px; 
    position: relative; /* For caption */ 

} 
figure::before { 
    content: ""; 
    position: absolute; 
    left: 0; 
    top: 0; 
    right: 0; 
    bottom: 0; 
    background: url("http://placehold.it/400x400") no-repeat; 
    border-radius: 100px; /* Forced on image for smooth transition */ 
    transition: opacity 1s ease-out; 
} 

figcaption { 
    position: absolute; 
    top: 100%; 
    left: 0; 
    width: 100%; 
    color: hotpink; 
    text-align: center; 
    transition: top 1s ease-out; 
} 
figure:hover::before { 
    opacity: 0; 
} 
figure:hover figcaption { 
    top: 50%; 
} 
+0

marczking: Sono consapevole che si verifica solo quando si utilizza il 50% per il raggio di confine e che probabilmente è correlato al rendering del browser. Ho provato questo in tutti i browser rilevanti e tutti mostrano lo stesso risultato. È solo un sospetto che tutti i browser farebbero lo stesso "errore", quindi sarebbe bello se qualcuno potesse almeno confermare che è effettivamente correlato al rendering del browser. –

+1

bene nella mia penna sopra si verifica anche quando si utilizza 100px e non il 50%, la dimensione del bordo-raggio non sembra importare – MMachinegun

+0

marczking: sembra che tu abbia ragione su questo. Quindi, in pratica, si verifica quando un elemento wrapping utilizza un raggio di bordo in combinazione con un overflow: nascosto ... È solo qualcosa che i browser non supportano correttamente? –

0

si potrebbe aggiungere una nuova variabile con un'opacità di 0 allora ho quel dissolvenza con l'immagine si dissolve.

figure { 
 
    width: 400px; 
 
    height: 400px; 
 
    border-radius: 50%; 
 
    overflow: hidden; 
 
    position: relative; /* For caption */ 
 
} 
 

 
background { 
 
    background-color: red; 
 
    width: 400px; 
 
    height: 400px; 
 
    border-radius: 50%; 
 
    overflow: hidden; 
 
    opacity: 0; 
 
    position: fixed; 
 
    z-index: 5; 
 
    transition: opacity 1s ease-out; 
 
} 
 

 
img { 
 
    border-radius: 50%; /* Forced on image for smooth transition */ 
 
    width: 100%; 
 
    transition: opacity 1s ease-out; 
 
    position: relative; 
 
    z-index: 100; 
 
} 
 

 
figcaption { 
 
    position: absolute; 
 
    top: 100%; 
 
    left: 0; 
 
    width: 100%; 
 
    color: hotpink; 
 
    text-align: center; 
 
    transition: top 1s ease-out; 
 
    z-index: 10000; 
 
} 
 
figure:hover img { 
 
    opacity: 0; 
 
} 
 
figure:hover background { 
 
    opacity: 1; 
 
} 
 
figure:hover figcaption { 
 
    top: 50%; 
 
}
<figure> 
 
    <background></background> 
 
    <img src="http://placehold.it/400x400" alt> 
 
    <figcaption>Demo</figcaption> 
 
</figure>

Avviso ho aggiunto il tag background e rimosso dal background-colorfigure

0

Ho avuto lo stesso problema e si è conclusa con pseudo elemento al posto di sfondo, un po 'come quella :

figure::before { 
    content: ''; 
    display: block; 
    background-color: red; 
    width: 400px; 
    height: 400px; 
    transform: scale(0.997); 
    border-radius: 50%; 
} 

Questo mi ha permesso di creare "pseudo background" che ho poi ridotto leggermente con transform: scale (0.997); quindi avrà le stesse dimensioni ma un po 'sotto il bordo visibile. Naturalmente nel tuo caso dovresti anche posizionare l'immagine in modo assoluto in modo che non venga spinto di seguito da questo :: prima.

Problemi correlati