Чи: раніше не працювати над елементами 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.