自动将徽章放在图像角上

时间:2011-05-21 20:34:04

标签: javascript jquery html css position

我有一个布局,图像在某个区域内“浮动”。布局如下所示:

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 个答案:

答案 0 :(得分:16)

需要一些试用,但现在是:the size independent image badge positioner

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

示例:

在以前不太成功的尝试中(请参阅编辑历史记录),问题是让图像垂直居中,以使其父级具有相同的大小(以便将徽章定位在该父级的左上角)。作为内联元素,父母不关心其内容的高度,因此保持小,但作为块元素,它延伸到h的父母的大小,因此达到高,见demonstration fiddle。诀窍似乎是给父母一个非常小的行高(例如0)并将其显示为内联块。这样父母就会根据孩子的成长而增长。

使用所有DTD在Opera 11,Chrome 11,IE8,IE9,FF4和Safari 5中进行测试。 IE7失败了,但是照片的中心对齐与徽章在正确的位置并没有那么糟糕。现在也适用于IE7,因为我删除了{{内的标记中的空格1}}标签。哈哈,多奇怪啊!

答案 1 :(得分:2)

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" />');

从技术上讲,您可以在不使用jQuery插入HTML的情况下向HTML添加类似内容。

答案 2 :(得分:0)

使用<div>以外的元素,例如<span>并将其放在<a>元素之后的<img>元素中。然后,提供<a>元素position:relative;<span>获取position:absolute; top:0px; left:0px;。也就是说,如果你不介意徽章也是同一链接的一部分 - 但这是最​​简单的方法。此外,使用<span>的原因是为了保持HTML4有效,<div>仍然是HTML5有效的。

答案 3 :(得分:0)

我确实找到了一个使用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的情况下找到其中一个可行的方法。