Есть ли: раньше не работал на img элементов?

262

Я пытаюсь использовать :beforeселектор, чтобы поместить изображение поверх другого изображения, но я обнаружил, что просто не получается поместить изображение перед imgэлементом, а только каким-то другим элементом. В частности, мои стили:

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

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

и я считаю, что это работает нормально:

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

но это не

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

Вместо этого я могу использовать элемент divили , и браузер корректно накладывает мое изображение поверх изображения в элементе, но если я применяю класс оверлея к самому себе, он не работает.pspanimgimg

Я хотел бы, чтобы это работало, потому что это spanменя оскорбляет, но что более важно, у меня есть около 100 сообщений в блоге, которые я хотел бы изменить, и я могу сделать это за один раз, если бы я мог просто изменить таблицу стилей, но если я должен вернуться назад и добавить дополнительный spanэлемент между aи imgэлементами, это будет намного больше работы.

Джошуа Фрэнк
источник
5
Это странно, особенно потому, что сам стандарт CSS дает пример использования: before с элементом IMG…
@chharvey: этот вопрос был задан после этого.
Джошуа Франк

Ответы:

263

К сожалению, большинство браузеров не поддерживают использование :afterили использование :beforeтегов img.

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

Тем не менее, вы можете выполнить то, что вам нужно, с помощью JavaScript / jQuery. Проверьте эту скрипку:

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

$(function() {

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

});

Редактировать :

По той причине, что это не поддерживается, проверьте ответ coreyward .

cwharris
источник
3
ваша скрипка отсутствует. В этом вся прелесть ссылок jsFiddle.
Roko C. Buljan
Починил это. Извини за это.
cwharris
1
Этот ответ не объясняет, почему img не может иметь до или после. Кроме того, предлагаемое решение javascript не является его правильной заменой.
Джаспер Кеннис
3
Предполагается, что предлагаемое решение не будет работать в каждом сценарии. Это просто пример того, как можно обойти проблему. Если вы хотите предложить более общее решение, не стесняйтесь опубликовать ответ.
cwharris
141

Псевдоселекторы до и после не вставляют элементы HTML - они вставляют текст до или после существующего содержимого целевого элемента. Поскольку элементы изображения не содержат текст или иметь потомков, ни img:beforeили img:afterбудет делать вам никакой пользы. Это также относится к таким элементам, как <br>и <hr>по той же причине.

coreyward
источник
Теги img, безусловно, являются элементами сами по себе, но нам разрешено вставлять их до или после других элементов с помощью псевдо-селекторов: before и: after. Разве это не в спецификации CSS?
cwharris
13
Это немного по-другому. Вы можете вставить изображение, но не используя тег изображения - вы должны использовать content: url(/img/foo.jpg);синтаксис. См. W3.org/TR/CSS21/generate.html для деталей.
coreyward
4
Небольшое исправление: они вставляют псевдоэлементы, которые больше похожи на элементы, чем на текстовые узлы.
Крис Кало
Созданный контент становится частью Shadow DOM. Эти новые элементы, атрибуты и текстовые узлы очень реальны. Вы можете увидеть их, например, в Chrome's Inspector.
Марк Дитхельм
@coreyward Может быть, вы будете доверять MDN (Замененный элемент)
Марк Дитхельм
41

Я нашел способ сделать эту работу в чистом CSS:

Я просто поддельные содержание -метод

чистый метод CSS для включения img: after.

Вы можете проверить CodePen: я просто фальшивый контент или посмотреть источник .

Источник и фрагмент

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

Поддержка браузера

✓ Chrome 10+

✓ Firefox 11+

✓ Опера 9.8+

✓ Сафари

Нет поддержки

⊗ Internet Explorer 8/9

Пожалуйста, проверьте в других браузерах

TimPietrusky
источник
1
Таким образом, вы просто добавляете контент: "" в стиль тега img и: before и: after для начала работы. Хорошая находка, интересно, как это кросс-браузер.
w00t
2
Я установил значок теста jsbin.com/esewow/edit#html,live и могу подтвердить, что он не работает в IE8, но в Chrome и Safari работает нормально.
w00t
14
Пример CodePen работает в Firefox только в том случае, если src тега img недопустим - это вызывает отображение атрибута alt как элемента, который фактически позволяет: before и: after. Если img src существует, он перестает работать: codepen.io/anon/pen/EjtDu
thenickdude
2
Остановите меня, если я ошибаюсь, но кажется, что он больше не работает с Chrome 46
Gyum Fox
5
img: before и img: after вообще не работают в Safari . Даже не это, что изначально меня взволновало. Хорошая попытка, хотя
Wray Bowling
9

Из-за того, <img>что элемент заменяется , стиль документа на него не влияет.

Чтобы сослаться на него в любом случае, <picture>предоставляется идеальная нативная оболочка, к которой могут быть прикреплены псевдоэлементы, например:

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
источник
3

Вот еще одно решение, использующее контейнер div для img при использовании :hover::afterдля достижения эффекта.

HTML выглядит следующим образом:

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

CSS следующим образом:

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

Чтобы увидеть это в действии, посмотрите созданную мной скрипку . Просто, чтобы вы знали, что это кросс-браузер дружественный и нет необходимости обманывать код с «поддельным контентом».

truleighsyd
источник
Полезно применять display: inline-blockк #img_container. Это сделает ширину контейнера равной изображению при всех размерах экрана. Таким образом, вы не получите :afterконтент, плавающий за пределами изображения.
Аноним
1

Я думаю, что лучший способ понять, почему это не работает, - это до и после вставки их содержимого до или после содержимого в теге, к которому вы их применяете. Таким образом, он работает с элементами div или span (или большинством других тегов), потому что вы можете помещать содержимое в них.

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

Тем не менее, img является самодостаточным, самозакрывающимся тегом, и поскольку у него нет отдельного закрывающего тега, вы ничего не можете поместить в него. (Это должно было бы выглядеть <img>Content</img>, но, конечно, это не работает.)

Я знаю, что это старая тема, но она сначала появляется в Google, так что, надеюсь, это поможет другим учиться.

BevansDesign
источник
1

Этот работает для меня:

HTML

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

CSS

ul li::before {
    content: url(../images/check.png);
}
Меч I
источник
1

Псевдоэлементы, созданные с помощью :: before и :: after, содержатся в блоке форматирования элемента и, следовательно, не применяются к заменяемым элементам, таким как img, или к элементам br.

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

Года А
источник
1

::after может использоваться для отображения запасного изображения


Смотрите пример ниже, первые 2 imgтега указывают на неработающие URL. Но второй отображает запасное изображение вместо сломанного логотипа по умолчанию из браузера. Тем не менее, я не уверен, что это практично, я считаю довольно сложно заставить его работать правильно.

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

Попробуйте этот код

.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 вечера
источник
-1

Я попытался и нашел более простой способ сделать это. Вот HTML-код:

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

То, что я сделал, это поместил пустой <p>тег после моего тега изображения. Теперь я буду использовать p :: before, чтобы показать изображение и расположить его в соответствии с моими потребностями. Вот 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');
}

Попытайся.

Тайвеер Сингх Ниджар
источник
-1

Попробуйте :: после предыдущего элемента.

Дмитрий Юрченко
источник
Не могли бы вы разработать свой пост?
ZMag