How to conditionally show an element, keeping its occupied space?

10,665

Solution 1

See MDN - CSS visibility,

The visibility CSS property can show or hide an element without affecting the layout of a document (i.e., space is created for elements regardless of whether they are visible or not)

So, use Vue's dynamic style to bind your expression to CSS visibility.

new Vue({
  el: "#app",
  data: {
    visible: true
  },
  mounted() {
    setInterval(() => this.visible = !this.visible, 1000)
  }
})
#app {
  display: grid;
  grid-template-columns: auto auto auto;
}

#app div {
  border-style: solid;
  border-width: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
  <div>one</div>
  <div :style="{visibility: visible ? 'visible' : 'hidden'}">two</div>
  <div>three</div>
  {{visible}}
</div>

Solution 2

Look at this: https://forum.vuejs.org/t/vue-style-visibility-hidden-on-v-show-how/58293

You can achieve it, using a custom directive:

Vue.directive('visible', function(el, binding) {
    el.style.visibility = !!binding.value ? 'visible' : 'hidden';
});

And then use

<div v-visible="your_condition" ... >

Solution 3

bind style with opacity = 0 or 1.

new Vue({
  el: "#app",
  data: {
    visible: true
  },
  mounted() {
    setInterval(() => this.visible = !this.visible, 1000)
  }
})
.layout {
  display: grid;
  grid-template-columns: auto auto auto;
}

.your-column {
  border-style: solid;
  border-width: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
  <div class="layout">
    <div class="your-column">one</div>
    <div class="your-column" :style="{'opacity':visible?1:0}">two</div>
    <div class="your-column">three</div>
  </div>
</div>
Share:
10,665

Related videos on Youtube

WoJ
Author by

WoJ

Updated on September 15, 2022

Comments

  • WoJ
    WoJ over 1 year

    Vue.js has two conditional keywords: v-if and v-show which allow for an element to be visible or not based on a condition. The difference is

    The difference is that an element with v-show will always be rendered and remain in the DOM; v-show only toggles the display CSS property of the element.

    I thought that it would have an impact on the space taken by an invisible element but in any of these cases, the space occupied by an element is none when the condition is false.

    This means that in, say, a span of three elements taking 100% of the width of the screen, the place of the invisible is taken by the next one, as in this example with CSS Grid:

    new Vue({
      el: "#app",
      data: {
        visible: true
      },
      mounted() {
        setInterval(() => this.visible = !this.visible, 1000)
      }
    })
    #app {
      display: grid;
      grid-template-columns: auto auto auto;
    }
    
    #app div {
      border-style: solid;
      border-width: 1;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
    <div id="app">
      <div>one</div>
      <div v-if="visible">two</div>
      <div>three</div>
    </div>

    Is there a simple way to hide the contents of the element (making it invisible), but keep its space? (to have, in the example above, the central element appearing and disappearing - but with the two other ones not moving)

  • Geo...
    Geo... about 2 years
    I was going to bind a style, then I saw this. I didn't even know about this. Very nice, elegant solution.