Est-ce que: avant de ne pas travailler sur les éléments img?

262

J'essaie d'utiliser le :beforesélecteur pour placer une image sur une autre image, mais je trouve que cela ne fonctionne tout simplement pas de placer une image avant un imgélément, seulement un autre élément. Plus précisément, mes styles sont:

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

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

et je trouve que cela fonctionne bien:

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

mais cela ne signifie pas:

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

Je peux utiliser un élément divou à la pplace de cela span, et le navigateur superpose correctement mon image sur l'image de l' imgélément, mais si j'applique la classe de superposition à imglui - même, cela ne fonctionne pas.

J'aimerais que cela fonctionne parce que cela spanme choque, mais plus important encore, j'ai environ 100 articles de blog que je voudrais modifier, et je peux le faire en une seule fois si je pouvais simplement modifier la feuille de style, mais si je dois revenir en arrière et ajouter un spanélément supplémentaire entre les éléments aet img, ce sera beaucoup plus de travail.

Joshua Frank
la source
5
C'est étrange, d'autant plus que la norme CSS elle-même donne un exemple d'utilisation: avant avec un élément IMG…
@chharvey: Cette question a été posée après celle-ci.
Joshua Frank

Réponses:

263

Malheureusement, la plupart des navigateurs ne prennent pas en charge l'utilisation :afterou :beforeles balises img.

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

Cependant, il vous est possible d'accomplir ce dont vous avez besoin avec JavaScript / jQuery. Découvrez ce violon:

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

$(function() {

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

});

Modifier :

Pour la raison pour laquelle cela n'est pas pris en charge, consultez la réponse de coreyward .

cwharris
la source
3
votre violon manque. C'est la beauté des liens jsFiddle.
Roko C. Buljan
A corrigé. Désolé pour ça.
cwharris
1
Cette réponse n'explique pas pourquoi img ne peut pas avoir avant ou après. De plus, la solution javascript proposée ne la remplace pas correctement.
Jasper Kennis
3
La solution proposée ne devrait pas fonctionner dans tous les scénarios. C'est simplement un exemple de la façon dont on pourrait contourner le problème. Si vous souhaitez proposer une solution plus générale, n'hésitez pas à poster une réponse.
cwharris
141

Les pseudo-sélecteurs avant et après n'insèrent pas d'éléments HTML - ils insèrent du texte avant ou après le contenu existant de l'élément ciblé. Parce que les éléments d'image ne contiennent pas de texte ou n'ont pas de descendants, ni l'un img:beforeni img:afterl'autre ne vous seront utiles. C'est également le cas pour des éléments comme <br>et <hr>pour la même raison.

coreyward
la source
Les balises Img sont clairement des éléments en soi, et pourtant nous sommes autorisés à les insérer avant ou après d'autres éléments en utilisant les sélecteurs de pseudo: avant et: après. N'est-ce pas dans la spécification CSS?
cwharris
13
C'est un peu différent. Vous pouvez insérer une image, mais sans utiliser de balise d'image - vous devez utiliser la content: url(/img/foo.jpg);syntaxe. Voir w3.org/TR/CSS21/generate.html pour les détails.
coreyward
4
Petite correction: ils insèrent des éléments pseudo, qui ressemblent plus à des éléments qu'à des nœuds de texte.
Chris Calo
Le contenu généré devient une partie du DOM fantôme. Ces nouveaux éléments, attributs et nœuds de texte sont bien réels. Vous pouvez les voir par exemple dans l'inspecteur de Chrome.
Marc Diethelm
@coreyward Vous ferez peut-être confiance à MDN (élément remplacé)
Marc Diethelm
41

J'ai trouvé un moyen de faire ce travail en css pur:

La méthode I'm just fake content

une méthode CSS pure pour activer img: after.

Vous pouvez consulter le CodePen: je suis juste un faux contenu ou voir la source .

Source et extrait

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"  
/>

Prise en charge du navigateur

✓ Chrome 10+

✓ Firefox 11+

✓ Opera 9.8+

✓ Safari

Pas de support

⊗ Internet Explorer 8/9

Veuillez tester dans d'autres navigateurs

TimPietrusky
la source
1
Donc, fondamentalement, vous ajoutez simplement du contenu: "" au style de la balise img et: avant et: après avoir commencé à travailler. Belle trouvaille, je me demande à quel point c'est cross-browser.
w00t
2
J'ai mis en place un test d'icône jsbin.com/esewow/edit#html,live et je peux confirmer que cela ne fonctionne pas sur IE8 mais sur Chrome et Safari cela fonctionne très bien.
w00t
14
L'exemple CodePen ne fonctionne dans Firefox que si le src de la balise img n'est pas valide - ce qui provoque le rendu de l'attribut alt comme un élément qui permet en fait: avant et: après. Si l'img src existe, il cesse de fonctionner: codepen.io/anon/pen/EjtDu
thenickdude
2
Arrêtez-moi si je me trompe, mais il semble que cela ne fonctionne plus avec Chrome 46
Gyum Fox
5
img: avant et img: après ne fonctionnent pas du tout dans Safari . Pas même ça, ce qui m'a d'abord excité. Bon essai cependant.
Wray Bowling
9

En raison de la nature d' <img>un élément remplacé , le style du document ne l'a pas affecté.

Pour le référencer de toute façon, <picture>fournit un wrapper natif idéal qui peut être attaché à des pseudo-éléments, comme ceci:

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>

dakab
la source
3

Voici une autre solution utilisant un conteneur div pour img lors de l'utilisation :hover::afterpour obtenir l'effet.

Le HTML comme suit:

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

Le CSS comme suit:

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

Pour le voir en action, consultez le violon que j'ai créé. Juste pour que vous sachiez que cela est compatible avec tous les navigateurs et qu'il n'est pas nécessaire de tromper le code avec un «faux contenu».

truleighsyd
la source
Il est utile d'appliquer display: inline-blockà #img_container. Cela rendra la largeur du conteneur égale à l'image à toutes les tailles d'écran. Ainsi, vous ne finissez pas par avoir du :aftercontenu flottant en dehors de l'image.
Anonyme
1

Je pense que la meilleure façon de comprendre pourquoi cela ne fonctionne pas est que: avant et: après avoir inséré leur contenu avant ou après le contenu de la balise à laquelle vous les appliquez. Cela fonctionne donc avec des divs ou des étendues (ou la plupart des autres balises) car vous pouvez y mettre du contenu.

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

Cependant, un img est une balise à fermeture automatique, et comme il n'a pas de balise de fermeture séparée, vous ne pouvez rien y mettre. (Cela devrait ressembler <img>Content</img>, mais bien sûr, cela ne fonctionne pas.)

Je sais que c'est un vieux sujet, mais il apparaît d'abord sur Google, donc j'espère que cela aidera les autres à apprendre.

BevansDesign
la source
1

Celui-ci fonctionne pour moi:

html

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

CSS

ul li::before {
    content: url(../images/check.png);
}
Épée I
la source
1

Les pseudo-éléments générés par :: avant et :: après sont contenus dans la boîte de mise en forme de l'élément, et ne s'appliquent donc pas aux éléments remplacés tels que img ou aux éléments br.

https://developer.mozilla.org/en-US/docs/Web/CSS/::after

Goda A
la source
1

::after peut être utilisé pour afficher l'image de secours d'une image


Voir l'exemple ci-dessous, les 2 premières imgbalises pointent vers les URL cassées. Mais le second affiche l'image de secours au lieu du logo cassé par défaut du navigateur. Cependant, je ne suis pas sûr que ce soit pratique, je trouve ça un peu difficile à faire fonctionner correctement.

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">

Loi Nguyen Huynh
la source
0

Essayez ce code

.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
}
subindas pm
la source
-1

J'ai essayé et trouvé une méthode plus simple pour le faire. Voici le HTML:

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

J'ai placé une <p>balise vide après ma balise d'image. Maintenant, je vais utiliser p :: before pour afficher l'image et la positionner en fonction de mes besoins. Voici le 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');
}

Essayez-le.

Tajveer Singh Nijjar
la source
-1

Essayez :: after sur l'élément précédent.

Dmytro Yurchenko
la source
Pourriez-vous élaborer votre message?
zmag