Рендеринг CSS3-вставки тени с изображением - PullRequest
9 голосов
/ 22 февраля 2011

Я хотел бы воспользоваться новой функцией CSS3 box-shadow для сайта, над которым я работаю.Проблема заключается в том, что Chrome 9.0.5 и Opera 10 неправильно отображают границу вставки, если внутри находится изображение (границы скрыты вокруг области изображения).

Я понимаю, что box-shadow все еще работает впрогресс, но я ожидаю, что браузеры полностью его поддержат или полностью его игнорируют.

<!doctype html>
<html>
  <head>
    <style>
        div {
            border: 1px solid black;
            width: 300px;
            height: 200px;
            overflow: hidden;

            // CSS3 inset shade
            -moz-box-shadow: inset 0 0 20px red;
            -webkit-box-shadow: inset 0 0 20px red;
            box-shadow: inset 0 0 20px red;
        }
    </style>
  </head>
  <body>
        <div>
            <img src="http://www.google.com/images/logos/ps_logo2.png" width="364" height="126" alt="" />
        </div>
  </body>
</html>

Известен ли какой-нибудь обходной путь для правильной визуализации красного оттенка?

Спасибо!

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

Ответы [ 5 ]

19 голосов
/ 22 февраля 2011

Box-shadow находится чуть выше фона в порядке наложения при использовании вставки. Поэтому любое изображение, которое вы имеете внутри div, будет закрывать тень.

В соответствии с W3C-характеристиками

С точки зрения стековых контекстов и порядок покраски, внешние тени элемент рисуется сразу ниже фон этого элемента, и внутренние тени элемента нарисовано сразу над фоном этого элемента (ниже границ и изображение границы, если есть).

Другими словами, Chrome и Opera делают это правильно (FTR, FF 3.6.13 делает то же самое, что и Opera).

Если вы хотите, чтобы тень перекрывала изображение, у вас есть несколько вариантов в зависимости от ваших потребностей:

  1. Установите для изображения background свойство div.
  2. Абсолютно поместите div над изображением с изображением, сделайте его того же размера и поместите туда тень (не очень рекомендуется, так как она сложная и добавляет несемантическую разметку).
  3. Убедитесь, что фоны изображений прозрачны (это позволит тени просвечивать, но непрозрачные пиксели все равно будут покрывать тень).
  4. Вместо этого рассмотрите использование border-image и градиента (Этот также немного запутанный, но помещает градиент в саму границу, и вы можете перейти к прозрачному, используя RGBA.)
11 голосов
/ 20 марта 2012

Есть лучшее решение - просто установите этот CSS на свой img.

img {
  z-index: -1;
  position: relative
}

Пример: http://trentwalton.com/2010/11/22/css-box-shadowinset/

3 голосов
/ 18 августа 2014

Используйте псевдоэлемент, чтобы наложить тень на изображение. Это позволяет избежать добавления дополнительного, несемантического брата в вашу разметку, работает независимо от фона других элементов (в отличие от настройки z-index: -1) и не требует JavaScript.

Простой живой пример: http://jsfiddle.net/4qvzqajq/

Пример OP: http://jsfiddle.net/AWaVC/138/

Предполагая эту разметку:

<div class="container">
    <img src="http://stackoverflow.com/content/stackoverflow/img/apple-touch-icon.png" />
</div>

Этот CSS-код будет применять вставную тень к содержимому div (включая изображение):

.container {
    position: relative;
}
.container:after {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    content: '';
    -moz-box-shadow:    inset 0 0 5px #000000;
    -webkit-box-shadow: inset 0 0 5px #000000;
    box-shadow:         inset 0 0 5px #000000;
}
1 голос
/ 03 марта 2014

Проблема с отрицательным решением z-index состоит в том, что если позади изображения есть элемент с фоном, изображение перекрывается. Так что это решение работает только на белых сайтах. Мое решение состоит в том, чтобы поставить тень на div, который является родным братом img. Это div получает position: absolute; и располагается точно над изображением:

http://jsfiddle.net/E3hFM/

HTML:

<div class="teaserimage">
  <img src="http://placehold.it/300x200">
  <div class="shadow"></div>
</div>

SCSS:

.teaserimage {
    position: relative;
    float: left;
    img {
        vertical-align: middle; // to remove standard margin-bottom: 3px; of the image
    }
    .shadow {
        -webkit-box-shadow: inset 10px 10px 10px 0px rgba(0, 0, 0, 0.5);
        -moz-box-shadow: inset 10px 10px 10px 0px rgba(0, 0, 0, 0.5);
        box-shadow: inset 10px 10px 10px 0px rgba(0, 0, 0, 0.5);
        position: absolute;
        top: 0px;
        width: 100%;
        height: 100%;
    }
}
1 голос
/ 29 апреля 2012

Вчера у меня есть решение с одним свойством DIV и background-image.Если мы говорим о динамическом сайте с неизвестными или не совсем понятными размерами изображения, мы можем использовать класс JavaScript Image.На самом деле это не «разводной гаечный ключ» и не ракетостроение о правильной настройке ширины и высоты.

Посмотрите на это с загруженным JQuery:

<style type="text/css">
  #ribbon div {
    display: inline-block; /* no hacks about left-floating images */
    border: none;
    border-radius: 8px; /* just for test inset shadow with rounded borders */
    -webkit-border-radius: 8px;
    -moz-border-radius: 8px;

    // CSS3 inset shade
    -moz-box-shadow: inset 0 0 20px red;
    -webkit-box-shadow: inset 0 0 20px red;
    box-shadow: inset 0 0 20px red;
  }
</style>

<script type="text/javascript">
  $(function(){

    // Here's our images. We can load a list with AJAX.
    var sources = ['1.jpg','2.jpg','3.jpg'];
    var imgs = [];

    var ribbon = $('#ribbon'); // Image list container

    // Add images to the ribbon
    for (var i=0, len=sources.length; src=sources[i], i<len; i++) {

      var div = $('<div>'); // Create an empty DIV
      div.attr('id','thumbimg'+i); // Name our DIV for async access
      div.css('display','none'); // Make it hidden while loading the image
      div.appendTo(ribbon); // Add to container

      imgs[i] = new Image(); // Empty Image object
      imgs[i].id = 'img'+i; // Name it for DIV match

      // We can get the dimensions only after the image is loaded
      imgs[i].onload = function() {
        var myDiv = $('#thumb'+this.id); // Matching 'thumbimgX'
        myDiv.css({
          'display': '', // Clear display property = show hidden DIV
          'width': this.width + 'px', // Set DIV.width = Image.width
          'height': this.height + 'px', // Same for height
          'background-image': 'url('+this.src+')', // draw our image in background
          // Note the image already loaded and the div is inserted before
          // so picture just appears without lags
        });
      }

      // Load image
      imgs[i].src = src;
    }

  }
</script>

<body>
   ...
  <div id="ribbon"></div>
   ...
</body>

Таким образом, мы можем отобразить список изображений с различными встроенными теневыми эффектами: виньетирование (

inset 0 0 60px rgba(0,0,0,0.8)

), buttonize /магнит на холодильник (

inset -4px -4px 8px rgba(0,0,0,0.2), inset 4px 4px 8px rgba(255,255,255,0.8)

) и все, что вы хотите.Нет тега IMG, поэтому при щелчке правой кнопкой мыши не отображаются параметры «сохранить изображение» или «скопировать адрес изображения».

ps упс, фиксированная загрузка изображения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...