Чи: раніше не працювати над елементами 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або pелемент span, і браузер правильно накладає моє зображення на зображення в imgелементі, але якщо застосувати клас накладання до imgсебе, він не працює.

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


5
Це дивно, тим більше, що сам стандарт CSS наводить приклад використання: раніше з елементом IMG…


@chharvey: Це питання було задано після цього.
Джошуа Франк

Відповіді:


262

На жаль, більшість браузерів не підтримує використання тегів img :afterабо :beforeна них.

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

Однак ви можете виконати те, що вам потрібно, за допомогою JavaScript / jQuery. Ознайомтеся з цією загадкою:

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

$(function() {

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

});

Редагувати :

З причини, чому це не підтримується, ознайомтеся з відповіддю Coreyward .


3
ваша загадка відсутня. Ось така краса посилань jsFiddle.
Roko C. Buljan

Виправлено це. Вибач за це.
cwharris

1
Ця відповідь не пояснює, чому img не може бути до або після. Також запропоноване рішення JavaScript не є належною його заміною.
Джаспер Кенніс

3
Запропоноване рішення не передбачається працювати у кожному сценарії. Це просто приклад того, як можна обійти проблему. Якщо ви хочете запропонувати більш загальне рішення, не соромтеся опублікувати відповідь.
cwharris

141

До і після псевдоселекторів не вставляються елементи HTML - вони вставляють текст до або після наявного вмісту цільового елемента. Оскільки елементи зображення не містять текст або мати нащадків, ні img:beforeчи img:afterбуде робити вам ніякої користі. Це також стосується таких елементів, як <br>і <hr>з тієї ж причини.


Теги img - це явно самі по собі елементи, і все ж нам дозволено вставляти їх до або після інших елементів, використовуючи: до і: після псеедоселекторів. Це не в специфікації css?
cwharris

13
Це трохи інакше. Ви можете вставити зображення, але не використовуючи тег зображення - ви повинні використовувати content: url(/img/foo.jpg);синтаксис. Деталі див. У w3.org/TR/CSS21/generate.html .
coreyward

4
Невелика корекція: вони вставляють елементи psuedo, які більше схожі на елементи, ніж вони схожі на текстові вузли.
Кріс Кало

Створений контент стає частиною Shadow DOM. Ці нові елементи, атрибути та текстові вузли дуже реальні. Ви можете бачити їх, наприклад, у Інспекторі Chrome.
Марк Дітхельм

@coreyward Можливо, ви будете довіряти MDN (Замінений елемент)
Marc Diethelm

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+

✓ Opera 9.8+

✓ Сафарі

Немає підтримки

⊗ Internet Explorer 8/9

Перевірте інші веб-переглядачі


1
Таким чином, ви просто додаєте вміст: "" до стилю тегу img та: до та: після початку роботи. Приємна знахідка, мені цікаво, як це крос-браузер.
w00t

2
Я встановив тест на іконки jsbin.com/esewow/edit#html,live, і можу підтвердити, що він не працює на IE8, але на Chrome і Safari він працює чудово.
w00t

14
Приклад CodePen працює лише у Firefox, якщо src тегу img недійсний - це призводить до того, що атрибут alt буде наданий як елемент, який фактично дозволяє: до і після. Якщо 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>


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

Щоб побачити це в дії, перегляньте створену нами загадку . Просто ви знаєте, що це зручно для веб-переглядачів, і не потрібно хитрість коду "підробляти вміст".


Це корисно звернутися display: inline-blockдо #img_container. Це зробить ширину контейнера рівним зображенню для всіх розмірів екрана. Отже, у вас не з’являється :afterвміст, що плаває поза зображенням.
Анонім

1

Я думаю, що найкращий спосіб зрозуміти, чому це не працює, це: до і: після вставлення їх вмісту до або після вмісту в тег, до якого ви їх застосовуєте. Таким чином, це працює з divs або spans (або більшістю інших тегів), оскільки ви можете розміщувати вміст всередині них.

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

Однак img - це самодостатній тег, що самозакривається, і оскільки він не має окремого тегу закриття, ви нічого не можете помістити всередину нього. (Це повинно виглядати так <img>Content</img>, але, звичайно, це не працює.)

Я знаю, що це стара тема, але вона спочатку з’являється в Google, тому, сподіваємось, це допоможе іншим дізнатися.


1

Цей для мене працює:

html

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

CSS

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


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
}

-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');
}

Спробуй це.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.