Fa: prima di non lavorare su elementi img?


262

Sto cercando di utilizzare il :beforeselettore per posizionare un'immagine su un'altra immagine, ma sto scoprendo che semplicemente non funziona posizionare un'immagine prima di un imgelemento, solo qualche altro elemento. Nello specifico, i miei stili sono:

.container
{
   position: relative;
   display: block;
}

.overlay:before
{
    content: url(images/[someimage].png);
    position: absolute;
    left:-20px;
    top: -20px;
}

e trovo che funzioni bene:

<a href="[url]" class="container">
  <span class="overlay"/>
  <img width="200" src="[url]"/>
</a>

ma questo non:

<a href="[url]" class="container">
  <img width="200" src="[url]" class="overlay"/>
</a>

Posso usare un elemento divo pinvece di quello span, e il browser sovrappone correttamente la mia immagine sull'immagine imgnell'elemento, ma se applico la classe di sovrapposizione a imgse stessa, non funziona.

Mi piacerebbe farlo funzionare perché questo spanmi offende, ma soprattutto, ho circa 100 post sul blog che vorrei modificare, e posso farlo in una volta sola se potessi semplicemente modificare il foglio di stile, ma se devo tornare indietro e aggiungere un spanelemento in più tra gli elementi ae img, questo sarà molto più lavoro.


5
Questo è strano, soprattutto perché lo stesso standard CSS fornisce un esempio di utilizzo: prima con un elemento IMG ...


@chharvey: questa domanda è stata posta dopo questa.
Joshua Frank,

Risposte:


263

Sfortunatamente, la maggior parte dei browser non supporta l'utilizzo :aftero :beforesui tag img.

http://lildude.co.uk/after-css-property-for-img-tag

Tuttavia, è possibile per te realizzare ciò di cui hai bisogno con JavaScript / jQuery. Dai un'occhiata a questo violino:

http://jsfiddle.net/xixonia/ahnGT/

$(function() {

    $('.target').after('<img src="..." />');

});

Modifica :

Per il motivo per cui questo non è supportato, controlla la risposta di coreyward .


3
manca il violino. Questa è la bellezza dei collegamenti jsFiddle.
Roko C. Buljan,

Aggiustato. Mi dispiace per quello.
cwharris,

1
Questa risposta non spiega perché img non può avere prima o dopo. Inoltre, la soluzione javascript proposta non è un corretto sostituto.
Jasper Kennis,

3
La soluzione proposta non dovrebbe funzionare in tutti gli scenari. È semplicemente un esempio di come si potrebbe aggirare il problema. Se desideri proporre una soluzione più generale, sentiti libero di inviare una risposta.
cwharris,

141

Gli pseudo-selettori prima e dopo non inseriscono elementi HTML, ma inseriscono testo prima o dopo il contenuto esistente dell'elemento target. Poiché gli elementi di immagine non contengono testo o avere discendenti, né img:beforeo img:afterfarà nulla di buono. Questo vale anche per elementi simili <br>e <hr>per lo stesso motivo.


I tag img sono chiaramente elementi in sé e per sé, eppure ci è permesso inserirli prima o dopo altri elementi usando i selettori psuedo: prima e: dopo. Non è questo nelle specifiche CSS?
cwharris,

13
È un po 'diverso. È possibile inserire un'immagine, ma non utilizzare un tag immagine: è necessario utilizzare la content: url(/img/foo.jpg);sintassi. Vedi w3.org/TR/CSS21/generate.html per i dettagli.
coreyward

4
Piccola correzione: inseriscono psuedo-elementi, che sono più simili a elementi che a nodi di testo.
Chris Calo,

Il contenuto generato diventa parte del DOM Shadow. Quei nuovi elementi, attributi e nodi di testo sono molto reali. Puoi vederli ad es. Nell'Inspector di Chrome.
Marc Diethelm,

@coreyward Forse ti fiderai dell'MDN (elemento sostituito)
Marc Diethelm,

41

Ho trovato un modo per far funzionare questo in puro CSS:

Il Sono solo falso contenuti -Metodo

un metodo CSS puro per abilitare img: after.

Puoi dare un'occhiata a CodePen: sono solo un contenuto falso o vedere la fonte .

Sorgente e frammento

img {
    /* hide the default image */
    height:0;
    width:0;

    /* hide fake content */
    font-size:0;
    color:transparent;

    /* enable absolute position for pseudo elements */
    position:relative;

    /* and this is just fake content */
    content:"I'm just fake content";
}

/* initial absolute position */
img:before,
img:after {
    position:absolute;
    top:0;
    left:0;    
}

/* img:before - chrome & others */
img:before {
    content:url(http://placekitten.com/g/250/250);
}

/* img:before - firefox */
body:not(:-moz-handler-blocked) img:before {
    padding:125px;
    background:url(http://placekitten.com/g/250/250) no-repeat;
}

/* img:after */
img:after {
    /* width of img:before */
    left:250px;

    content:url(http://lorempixel.com/350/200/city/1);
}
<img
    alt="You are watching the ~ I'm just fake content ~ method"  
/>

Supporto per il browser

✓ Chrome 10+

✓ Firefox 11+

✓ Opera 9.8+

✓ Safari

Senza supporto

⊗ Internet Explorer 8/9

Si prega di testare in altri browser


1
Quindi in pratica aggiungi semplicemente il contenuto: "" allo stile del tag img e: prima e: dopo inizia a lavorare. Bella scoperta, mi chiedo quanto sia cross-browser.
wt

2
Ho impostato un test delle icone jsbin.com/esewow/edit#html,live e posso confermare che non funziona su IE8 ma su Chrome e Safari funziona bene.
wt

14
L'esempio CodePen funziona in Firefox solo se l'src del tag img non è valido, il che rende il rendering dell'attributo alt come elemento che in realtà consente: prima e: dopo. Se esiste img src, smette di funzionare: codepen.io/anon/pen/EjtDu
thenickdude

2
Fermami se sbaglio, ma sembra che non funzioni più con Chrome 46
Gyum Fox,

5
img: before e img: after non funzionano affatto in Safari . Nemmeno questo, che inizialmente mi ha emozionato. Buona prova però.
Wray Bowling,

9

A causa della natura di <img>essere un elemento sostituito , lo stile del documento non lo influenza.

Per fare riferimento comunque, <picture>fornisce un wrapper nativo ideale a cui possono essere associati pseudo-elementi, in questo modo:

img:after, picture:after{
    content:"\1F63B";
    font-size:larger;
    margin:-1em;
}
<img src="//placekitten.com/110/80">

<picture>
    <img src="//placekitten.com/110/80">
</picture>


3

Ecco un'altra soluzione che utilizza un contenitore div per img durante l'utilizzo :hover::afterper ottenere l'effetto.

L'HTML come segue:

<div id=img_container><img src='' style='height:300px; width:300px;'></img></div>

Il CSS come segue:

#img_container { 
    margin:0; 
    position:relative; 
} 

#img_container:hover::after { 
    content:''; 
    display:block; 
    position:absolute; 
    width:300px; 
    height:300px; 
    background:url(''); 
    z-index:1; 
    top:0;
} 

Per vederlo in azione, dai un'occhiata al violino che ho creato. Solo per sapere che è compatibile con più browser e non è necessario ingannare il codice con "contenuti falsi".


È utile fare domanda display: inline-blockper #img_container. Ciò renderà la larghezza del contenitore uguale all'immagine a tutte le dimensioni dello schermo. Quindi, non finisci per avere :aftercontenuti fluttuanti al di fuori dell'immagine.
Anonimo il

1

Penso che il modo migliore per capire perché questo non funziona sia: prima e: dopo aver inserito il contenuto prima o dopo il contenuto all'interno del tag a cui lo stai applicando. Funziona quindi con div o span (o con la maggior parte degli altri tag) perché puoi inserire contenuti al loro interno.

<div>
:before
Content
:after
</div>

Tuttavia, un img è un tag autonomo e autochiudente, e poiché non ha un tag di chiusura separato, non è possibile inserire nulla al suo interno. (Dovrebbe apparire <img>Content</img>, ma ovviamente non funziona.)

So che questo è un vecchio argomento, ma si apre prima su Google, quindi spero che questo possa aiutare gli altri a imparare.


1

Questo funziona per me:

html

<ul>
    <li> name here </li>
</ul>

CSS

ul li::before {
    content: url(../images/check.png);
}


1

::after può essere utilizzato per visualizzare l'immagine di fallback di un'immagine


Vedi l'esempio di seguito, i primi 2 imgtag indicano gli URL rotti. Ma il secondo visualizza l'immagine di fallback invece del logo rotto predefinito dal browser. Tuttavia, non sono sicuro che sia pratico, trovo che sia un po 'complicato farlo funzionare correttamente.

img {
  position: relative;
  display: inline-block;
  width: 300px;
  height: 200px;
  vertical-align: top;
}
img:not(:first-child)::after {
  position: absolute;
  left: 0; top: 0; right: 0; bottom: 0;
  content: "<" attr(alt) "> NOT FOUND";
  border: 1px dashed #999;
  background: url(https://cdn.dribbble.com/users/1012566/screenshots/4187820/topic-2.jpg) center/100%;
}
<img src="https://source.unsplash.com/random/100/75" alt="logo">
<img src="https://source.unsplash.com/random/100/75" alt="logo">
<img src="https://source.unsplash.com/random/100x75" alt="logo">


0

Prova questo codice

.button:after {
    content: ""
    position: absolute
    width: 70px
    background-image: url('../../images/frontapp/mid-icon.svg')
    display: inline-block
    background-size: contain
    background-repeat: no-repeat
    right: 0
    bottom: 0
}

-1

Ho provato e trovato un metodo più semplice per farlo. Ecco l'HTML:

    <img id="message_icon" src="messages2.png">
    <p id="empty_para"></p>

Quello che ho fatto è stato posizionare un <p>tag vuoto dopo il mio tag immagine. Ora userò p :: prima per mostrare l'immagine e posizionarla in base alle mie esigenze. Ecco il CSS:

#empty_para
{
    display:inline;
    font-size:40;
    background:orange;
    border:2px solid red;
    position:relative;
    top:-400px;
    left:100px;
}
#empty_para::before
{
    content: url('messages.png');
}

Provalo.


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.