Поместите значок в угол изображения автоматически - PullRequest
17 голосов
/ 22 мая 2011

У меня есть макет, где изображения «плавают» в определенной области. Макет выглядит так:

Layout Example

Источник как этот:

<div class="free_tile">
  <a class="img_container canonical" href="/photos/10">
    <img class="canonical" src="http://s3.amazonaws.com/t4e-development/photos/1/10/andrew_burleson_10_tile.jpg?1303238025" alt="Andrew_burleson_10_tile">
    <!-- EDIT: I am aware that I can put the badge here. See the edit notes and image below. -->
  </a>
  <div class="location">Houston</div>
  <div class="taxonomy"> T6 | Conduit | Infrastructure </div>
</div>

CSS выглядит так (в SCSS):

div.free_tile { width: 176px; height: 206px; float: left; margin: 0 20px 20px 0; position: relative;
  &.last { margin: 0 0 20px 0; }
  a.img_container { display: block; width: 176px; height: 158px; text-align: center; line-height: 156px; margin-bottom: 10px; }
  img { margin: 0; border: 1px solid $dark3; display: inline-block; vertical-align: middle; @include boxShadow;
    &.canonical { border: 1px solid $transect; }
  }
  .location, .taxonomy { width: 176px; }
  .location { font-weight: 700; }
  .taxonomy { line-height: 10px; font-size: 10px; text-transform: uppercase; height: 20px; overflow: hidden; }
}
div.transect_badge { height: 20px; width: 20px; background: url('/images/transect-badge.png'); }

Итак, в основном изображения располагаются вертикально выровненными по центру и по центру текста и имеют максимальную ширину 176 и максимальную высоту 158, но они обрезаются, чтобы сохранить исходное соотношение сторон, чтобы фактический верхний угол каждого изображения падает по-разному в зависимости от того, какое изображение это.

У меня есть значок, который я хотел бы поместить в верхний угол некоторых изображений (когда изображение «каноническое»). Вы видите стиль для этого выше (div.transect_badge).

Проблема, конечно, в том, что я не знаю, где будет верхний угол изображения, поэтому я не могу жестко закодировать позицию с помощью CSS.

Я предполагаю, что мне нужно будет сделать это через jQuery или что-то в этом роде. Итак, я начал с метода jQuery для автоматического добавления значка div к любым каноническим изображениям. Это прекрасно работает, но я не могу понять, как расположить его в верхнем левом углу.

Как это можно сделать? (в идеале использовать только HTML и CSS, но реально использовать JS / jQuery)

- EDIT-- Вот проблема: изображение плавает в контейнере, поэтому угол изображения может попадать куда угодно за пределы контейнера. Вот пример того, что произойдет, если я попытаюсь использовать position:absolute; top:0; left:0 внутри того же контейнера, с которым связано изображение: The problem

Ответы [ 4 ]

16 голосов
/ 22 мая 2011

Потребовалось несколько попыток, но вот оно: позиционер значка, не зависящий от размера .

HTML:

<div class="tile">
    <span class="photo">
        <a href=""><img src="/photos/10.jpg" alt="10" /><ins></ins></a>
    </span>
    <p class="location">Houston</p>
    <p class="taxonomy">T6 | Conduit | Infrastructure</p>        
</div>

CSS:

.tile {
    float: left;
    width: 176px;
    height: 206px;
    margin: 0 20px 20px 0;
 }
.photo {
    display: block;
    width: 176px;
    height: 158px;
    text-align: center;
    line-height: 158px;
    margin-bottom: 10px;
}
a {
    display: inline-block;
    position: relative;
    line-height: 0;
}
img {
    border: none;
    vertical-align: middle;
}
ins {
    background: url('/images/badge.png') no-repeat 0 0;
    position: absolute;
    left: 0;
    top: 0;
    width: 20px;
    height: 20px;
}

Пример:

В предыдущих, менее успешных попытках (см. Историю редактирования), проблема заключалась в том, чтобы получить изображение вертикально по центру и получить родительский элемент того же размера (вчтобы разместить значок в верхнем левом углу этого родителя).Что касается встроенного элемента, то родительский элемент не заботится о высоте своего содержимого и поэтому остается небольшим, но как блочный элемент он растягивается до размера родительского элемента и, таким образом, достигает высокого значения, см. демонстрационная скрипка .Хитрость заключается в том, чтобы дать этому родителю очень маленькую высоту строки (например, 0) и отобразить его как встроенный блок.Таким образом родитель будет расти в соответствии со своими потомками.

Протестировано в Opera 11, Chrome 11, IE8, IE9, FF4 и Safari 5 со всеми DTD. IE7 не работает, но выравнивание по центру фотографии с значком в правильном положении совсем не так уж и плохо. Теперь работает и для IE7, потому что я удалил пробелы в разметке в aтег.Ха-ха, как странно!

2 голосов
/ 22 мая 2011

EDIT3: это решение очень похоже на мое оригинальное решение.Я на самом деле не особо изучал ваш код, поэтому должен был заметить это раньше.Ваш тег a уже оборачивает каждое изображение, так что вы можете просто добавить туда значок и расположить его абсолютно.Тег a не нуждается в ширине / высоте.Также вы должны добавить изображение значка в начале тега a.

Демо: http://jsfiddle.net/wdm954/czxj2/1/

div.free_tile {
    width: 176px;
    height: 206px;
    float: left;
}

a.img_container {
    display: block;
    margin-bottom: 10px;
}

span.transect_badge {
    display:block;
    position: absolute;
    height: 20px;
    width: 20px;
    background-image: url('/images/transect-badge.png');
}

HTML ...

<a class="img_container canonical" href="/photos/10">
    <span class="transect_badge"></span>
    <img class="canonical" src="path/to/img" />
</a>

Другие решения ...

В моем коде я использую теги SPAN, поэтому имитирую изображения, но это та же идея.Изображение значка при расположении absolute создаст требуемый эффект.

Демо: http://jsfiddle.net/wdm954/62faE/

РЕДАКТИРОВАТЬ: В случае, если вам нужно jQuery для позиционирования.Это должно работать (где .box - ваш контейнер, а .corner - изображение значка) ...

$('.box').each(function() {
    $(this).find('.corner')
        .css('margin-top', ( $(this).width() - $(this).find('.img').width() ) / 2);
    $(this).find('.corner')
        .css('margin-left', ( $(this).height() - $(this).find('.img').height() ) / 2);
});

EDIT2: еще одно решение - обернуть каждое изображение новым контейнером.Вам нужно переместить код, который вы используете для центрирования каждого изображения, в класс нового контейнера для упаковки.

Демонстрация: http://jsfiddle.net/wdm954/62faE/1/

$('.img').wrap('<span class="imgwrap" />');
$('.imgwrap').prepend('<span class="badge" />');

Технически вы можете просто добавить что-то вродеэто к вашему HTML, хотя без использования jQuery для вставки.

0 голосов
/ 22 мая 2011

Я нашел одно решение, используя jQuery. Я не предпочитаю это, потому что это заметно влияет на загрузку страницы, но допустимо, если больше ничего не будет работать. Меня больше интересует идея NGLN, которая кажется многообещающей, но я еще не совсем понял. Однако, поскольку эта тема привлекла много трафика, я подумал, что опубликую одно решение, которое придумал для будущих читателей:

Учитывая эту разметку:

<div class="free_tile">
  <a class="img_container canonical" href="/photos/10">
    <img class="canonical" src="http://s3.amazonaws.com/t4e-development/photos/1/10/andrew_burleson_10_tile.jpg?1303238025" alt="Andrew_burleson_10_tile">
    <span class="transect-badge"></span>
  </a>
  <div class="location">Houston</div>
  <div class="taxonomy"> T6 | Conduit | Infrastructure </div>
</div>

Тот же CSS, что и в вопросе, за исключением:

span.transect-badge { display: block; height: 20px; width: 20px; position: absolute; background: url('/images/transect-badge.png'); }

Тогда этот jQuery решает проблему:

$(function() {
  $('img.canonical').load( function() {
    var position = $(this).position();
    $(this).next().css({ 'top': position.top+1, 'left': position.left+1 });
  });
});

Однако, как я уже сказал, это приводит к заметному времени выполнения на стороне клиента, поэтому я бы предпочел использовать решение не JS, если смогу. Я буду продолжать оставлять этот вопрос открытым, пока буду тестировать и давать отзывы о других предлагаемых решениях, в надежде найти одно из них работоспособным без JS.

0 голосов
/ 22 мая 2011

Используйте элемент, отличный от <div>, например, <span> и поместите его внутри элемента <a> после элемента <img>. Затем дайте элемент <a> position:relative; и <span> получит position:absolute; top:0px; left:0px;. То есть, если вы не возражаете, значок также является частью той же ссылки - но это самый простой способ. Кроме того, причина использования <span> состоит в том, чтобы сохранить ваш HTML4 действительным, однако <div> все равно будет HTML5 действительным.

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