[Vuejs]-Vue and CSS3: absolute position in a relative wrapper messes up height

1👍

Instead of position:absolute you can consider margin-top

ul {
  position: relative;
  border: solid 1px coral;
  padding-top:8px;
}

li {
  margin-top: -8px;
  border: solid 0.5px black;
  transition:0.5s all;
}
li:hover {
  margin-top:-12px;
  margin-bottom:4px;
}
<ul>
  <li>list item</li>
  <li>list item</li>
  <li>list item</li>
  <li>list item</li>
  <li>list item</li>

</ul>

<p>test that shoudl be after list</p>

UPDATE

You can also consider transform on hover:

ul {
  position: relative;
  border: solid 1px coral;
  padding-top:8px;
}

li {
  margin-top: -8px;
  border: solid 0.5px black;
  transition:0.5s all;
}
li:hover {
  transform:translateY(-5px);
}
<ul>
  <li>list item</li>
  <li>list item</li>
  <li>list item</li>
  <li>list item</li>
  <li>list item</li>

</ul>

<p>test that shoudl be after list</p>

2👍

If you want to keep position: absolute you can do the following:

Update your ListPerspective.vue:

  <ul class="mx-auto">
    <ListPerspectiveItem
      v-for="(alert, index) in alerts"
      :key="alert.id"
      :index="index"
      :alert="alert"
      :totalElements="alerts.length"
      :verticalShift="15"
      @close="remove(index)"
    />
    <div :style="notificationMsg"><slot></slot></div>
  </ul>

By adding a slotted list element at the end. Also add a computed style, i.e:

  data() {
    return { verticalShift: 15 }
  },
  computed: {
    notificationMsg() {
      return `position: absolute; top: ${(this.alerts.length + 1) * this.verticalShift}px; margin-top: 20px;`;
    }
  }

You calculate total distance from top of the component you need to display your message below notifications.

This unfortunately requires you to define verticalShift in your parent (ListPerspective) component and pass it as a prop to ListPerspectiveItem. If I were you I’d create a simple store with basic configs like these and instead of hardcoding 15 as a default value in your ListPerspectiveItem I’d fetch it from store, doing the same thing in ListPerspective component, i.e.:

data() { 
// generally you should bind store state properties as computed properties, 
// but since it's a default, constant variable you shouldn't have to watch for it's changes
  return { verticalShift: this.$store.state.defaults.css.verticalShift }
}


verticalShift: {
  type: Number, default: this.$store.state.defaults.css.verticalShift
}

Last thing left to do is to update your App.vue by adding your message to the slot:

  <ListPerspective>
      Click the &times; button to remove a message
  </ListPerspective>

Example

👤dziraf

Leave a comment