Overlapping/overlaying multiple inline images
I have a list of images I'm trying to overlap so that they look similar to this:
My code:
.avatar img {
border-radius: 50%;
position: relative;
left: -5px;
z-index: 1;
}
<div class="avatars">
<span class="avatar">
<img src="https://picsum.photos/70" width="25" height="25"/>
</span>
<span class="avatar">
<img src="https://picsum.photos/50" width="25" height="25"/>
</span>
<span class="avatar">
<img src="https://picsum.photos/20" width="25" height="25"/>
</span>
<span class="avatar">
<img src="https://picsum.photos/100" width="25" height="25"/>
</span>
<!-- Variable amount more avatars -->
</div>
<p>4 People</p>
But obviously, I need an incrementing left
value, and a decrementing z-index
for the number of avatar imgs. Sure, I could do this with the @for
directive, but the thing is, there's a variable amount of avatar imgs. I was looking at the length()
function, but it doesn't work the way I was going to use it.
Another idea, is to have a set width div, and fit the images inside that, but that comes with its own issues (what if there are 5 images, or 20, how do control the width). I could also combine the images how I want them, elsewhere and not use any CSS.
You can use flex and reverse order then no need z-index:
.avatars {
display: inline-flex;
flex-direction: row-reverse;
}
.avatar {
position: relative;
border: 4px solid #fff;
border-radius: 50%;
overflow: hidden;
width: 100px;
}
.avatar:not(:last-child) {
margin-left: -60px;
}
.avatar img {
width: 100%;
display: block;
}
<div class="avatars">
<span class="avatar">
<img src="https://picsum.photos/70">
</span>
<span class="avatar">
<img src="https://picsum.photos/80">
</span>
<span class="avatar">
<img src="https://picsum.photos/90">
</span>
<span class="avatar">
<img src="https://picsum.photos/100">
</span>
</div>
Here is another idea with scale:
.avatars {
display: inline-block;
transform: scale(-1, 1);
}
.avatar {
position: relative;
display: inline-block;
border: 4px solid #fff;
border-radius: 50%;
overflow: hidden;
width: 100px;
}
.avatar:not(:first-child) {
margin-left: -60px;
}
.avatar img {
width: 100%;
display: block;
transform: scale(-1, 1);
}
<div class="avatars">
<span class="avatar">
<img src="https://picsum.photos/70">
</span>
<span class="avatar">
<img src="https://picsum.photos/80">
</span>
<span class="avatar">
<img src="https://picsum.photos/90">
</span>
<span class="avatar">
<img src="https://picsum.photos/100">
</span>
</div>
Another idea using mask in case you want to keep the order of your images. This will also give you transparency between the images:
.avatar {
display: inline-block;
border-radius: 50%;
overflow: hidden;
width: 100px;
}
.avatar:not(:first-child) {
margin-left: -60px;
-webkit-mask:radial-gradient(circle 55px at 5px 50%,transparent 99%,#fff 100%);
mask:radial-gradient(circle 55px at 5px 50%,transparent 99%,#fff 100%);
}
.avatar img {
width: 100%;
display: block;
}
body {
background:pink
}
<div class="avatars">
<span class="avatar">
<img src="https://picsum.photos/70">
</span>
<span class="avatar">
<img src="https://picsum.photos/80">
</span>
<span class="avatar">
<img src="https://picsum.photos/90">
</span>
<span class="avatar">
<img src="https://picsum.photos/100">
</span>
</div>
Another idea using a 3D tranformation trick (without transparency)
.avatars {
transform-style:preserve-3d; /* here */
}
.avatar {
display: inline-block;
border-radius: 50%;
overflow: hidden;
width: 100px;
}
.avatar:not(:first-child) {
margin-left: -60px;
transform:rotateY(-1deg); /* and here */
}
.avatar img {
width: 100%;
display: block;
}
<div class="avatars">
<span class="avatar">
<img src="https://picsum.photos/70">
</span>
<span class="avatar">
<img src="https://picsum.photos/80">
</span>
<span class="avatar">
<img src="https://picsum.photos/90">
</span>
<span class="avatar">
<img src="https://picsum.photos/100">
</span>
</div>
I like Temani's better, but if you can't use flex because you have to support IE 9 or earlier, I'll leave this here.
Note that the text direction is now right to left, so you'll need to reverse the order of your avatars.
.avatar img {
border-radius: 50%;
position: relative;
left: -5px;
margin-left: -25px;
z-index: 1;
}
.avatars {
direction: rtl; /* This is to get the stack with left on top */
text-align: left; /* Now need to explitly align left */
padding-left: 25px; /* Same value as the negative margin */
}
<div class="avatars">
<span class="avatar">
<img src="https://www.fillmurray.com/50/50" width="50" height="50"/>
</span>
<span class="avatar">
<img src="https://www.fillmurray.com/100/100" width="50" height="50"/>
</span>
<span class="avatar">
<img src="https://www.fillmurray.com/200/200" width="50" height="50"/>
</span>
<span class="avatar">
<img src="https://www.fillmurray.com/150/150" width="50" height="50"/>
</span>
<span class="avatar">
<img src="https://www.fillmurray.com/50/50" width="50" height="50"/>
</span>
<!-- Variable amount more avatars -->
</div>