designing user icons that overlap

I'm looking to design a component that stacks user icons on top of each other, similar to the example shown in the image. This feature is commonly seen on Google. How can I achieve this effect with a list of user icons?

Here's an example of what I'm aiming for: https://i.sstatic.net/BLZOj.png.

<template>
    <div>
    <ul>
      <li v-for="user in userList" :key="user.key">
        <user-icon-component :name="user.name" :image="user.picture"></user-icon-component>
      </li>
    </ul>
    </div>
</template>


<script>
export default {
  name: "UserList",
  props: {
    userList: {
      type: Object,
      default: null,
    },
  },
};
</script>

<style>

</style>

Answer №1

The user icon component is represented by an <img> HTML tag that accepts a user prop:

Vue.component('user-icon-component', {
  props: ['user'],
  template: `
  <img :src="user.picture" width="32" height="32" />
  `
})

To position the <li>s, use position: absolute, and for the <ul>, use position: relative to remove them from the normal flow of the document. Apply the left position to each <li> based on the loop's index:

<ul class="icon-container">
  <li v-for="(user, key, i) in userList" :key="user.key"
      class="icon" :style="{ left: `${i * 20}px` }">
    <user-icon-component :user="user"></user-icon-component>
  </li>
</ul>

Below is a demo of this functionality:

Vue.component('user-icon-component', {
    props: ['user'],
  template: `
  <img :src="user.picture" width="32" height="32" />
  `
})

/***** APP *****/
new Vue({
  el: "#app",
  data() {
    return {
        userList: {
        'Bob': { name: 'Bob', key: 1, picture: 'https://www.flaticon.com/svg/static/icons/svg/3084/3084430.svg' },
        'Mary': { name: 'Mary', key: 2, picture: 'https://www.flaticon.com/svg/static/icons/svg/3084/3084431.svg' },
        'Paul': { name: 'Paul', key: 3, picture: 'https://www.flaticon.com/svg/static/icons/svg/3084/3084452.svg' },
      }
    }
  },
});
.icon-container {
  position: relative;
}
.icon {
  position: absolute;
}
ul {
  list-style-type: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <ul class="icon-container">
    <li v-for="(user, key, i) in userList" :key="user.key"
        class="icon" :style="{ left: `${i * 20}px` }">
      <user-icon-component :user="user"></user-icon-component>
    </li>
  </ul>
</div>

Answer №2

Your question sparked an idea that intrigued me, so I decided to challenge myself and see what I could come up with. After some experimentation, I created a unique solution:

Check out this vue overlapping avatars component I developed

The technique I used involved utilizing the component's props as styles in style binding. While there are some scoped styles present, I believe they could also be incorporated into the style binding for a cleaner code structure.

The user prop consists of an array of objects with the property: img: 'imageURL'. By employing a v-for loop on a div element with:

:style="{ backgroundImage: `url(${user.img})`}"

We were able to display the images accordingly.

To achieve the overlapping effect, the div elements were styled with position: relative, and by using the index of the v-for loop, the style binding was adjusted as follows:

:style="{backgroundImage: `url(${user.img})`, left: `-${i*15}px`}"

This arrangement shifted each element 15px to the left, with the exception of the first one.

If you're curious to see the final outcome, here is an image showcasing the result:

https://i.sstatic.net/7KTYU.png

I thoroughly enjoyed tackling your question - it was quite enjoyable! :)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Incorporate a globally imported class inside a Vue 3 component by utilizing the provide function

In the process of developing an application using Vue 3, I have created an api class specifically for handling API calls: import axios from 'axios' export default class { /** * Send GET Request * @param {string} url * @retur ...

The hyperlinks are not functioning correctly on my template

I'm using a template with the following preview link: The template includes an image of a laptop on the left side, with clickable points representing links. My goal is to make these points clickable so that they open specific pages like mbank.pl or ...

The proper method for utilizing the clipped prop on the <v-navigation-bar/> component within Vuetify is as follows

Looking for the correct way to apply the clipped prop to <v-navigation-draw/> in a Vuetify application in order to ensure that the navigation drawer sits below the app-bar. Here is what I have tried so far. Started with a new project: $ vue create ...

Ways to disable mousewheel function in jQuery

I am trying to deactivate the mouse scroll in jQuery and successfully did so, however, I encountered this error message jquery.min.js:2 [Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See Thi ...

The CSS formatting isn't functioning properly

I've been attempting to implement CSS within my HTML document, but for some reason, it's not working. I even tried using an external style sheet, but that didn't work either. The goal is to create a green box that is 960px wide and 200px hig ...

Enhance your CSS horizontal submenu by incorporating a submenu list

My menu includes submenus like this: This is the HTML code: <div class="nav"> <div class="table"> <ul class="select"><li><a href="#nogo"><b>Home</b> </a></li></ul> <ul class="select">& ...

Having trouble connecting the HTML file with the JavaScript file

This is my unique HTML file <!DOCTYPE html> <html> <head> <script src="ll.js"></script> </head> <body> <link rel="stylesheet" href="home.css"> ...

axios Error: Unable to assign value to 'username' property because it is undefined

My experience testing the backend API with POSTMAN was successful as everything went smoothly and the response data appeared as follows: {"username":"123","email":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e4d5d6d7a4838985 ...

What is the most effective strategy for managing dependencies for npm packages?

I am currently working on extracting a few Vue.js components from the main application and converting them into an npm package stored in a repository. This package will be imported and utilized across two different websites. To bundle everything, I am util ...

Aligning rotated text in a bootstrap 4 table header

In my Bootstrap 4 project, I'm having difficulties with positioning rotated text within a table header. My goal is to align all the rotated text at the bottom of the cell and centered horizontally. Despite trying different transform-origins, it seems ...

Repeating percentages displayed in a progress bar

I created a responsive progress bar, but the progress values are repeating. I only want the central value to be displayed. Any suggestions on how to fix this issue? DEMO <div id="tab1"> <dx-data-grid class="tableTask" [dataSource]="datas" ...

Shade your elements with the magic of CSS3

Can someone help me create an object with a drop shadow using CSS3? Here is my current code: <!DOCTYPE html> <html> <head> <style type="text/css"> div { width:300px; height:100px; background-color:yellow; } </style> </ ...

Styling background images with jQuery

Issue with Implementing jQuery Background Image Swapper and CSS Styling html { background: url(images/image_1.jpg) no-repeat center center fixed; -webkit-background-size: cover; -moz-background-size: cover; -o-background-size: cover; b ...

The location of the footer is not aligned correctly

Recently, I encountered an issue that has left me puzzled. The problem is that the footer on my webpage is appearing between the calendar button and the calendar itself. Here is a snippet from my calendar.html file: {% extends 'base.html' %} {% ...

Overflowing issue with jQuery Show DIV disrupting footer of other DIVs

I have utilized jQuery to create a simple show/hide functionality. Currently, I am facing two issues: 1) The hidden DIV is displaying over the footer instead of causing the footer to drop down automatically. How can I achieve this? 2) Is there a way to h ...

Leveraging pre-rendered HTML in Vue.js components for both parent and child elements

Currently, I am rendering all the HTML server-side and attempting to use Vue to set this HTML as the $el for two components. According to the lifecycle diagram, this should be possible. There is a parent Vue instance (which binds to #main) that contains a ...

What is the method to retrieve the value from a specific div after an event has been triggered in Laravel?

Exploring the world of laravel and vue.js, I'm diving into fetching data from an API using resources. The concept involves incorporating 2 divs called GOAL and VALUE. The Value needs to be automatically updated whenever there's a change in the s ...

Assigning a value to a Vuex module variable using getters from another module in Nuxt.js

The Nuxt.js application I am working on involves initializing a variable in a Vuex module that uses Axios in its actions. store/program.js let program_url = 'programs/'; export const actions = { async programList({commit}) { await this.$ ...

The navbar is perfectly aligning all elements to the center

I've been struggling with this navbar for a while now. The latest issue I'm facing is proving to be quite challenging. The problem at hand is getting the navbar centered without affecting the positioning of other elements around it. If you check ...

Alter the dimensions and material displayed on Vue

In my Vue.js project, I have a topbar with two divs whose size and content need to be adjusted based on whether the user is logged in. If they are not logged in, it should look like this: <div id='search' width="400px"></div><div ...