Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

css

vue.js

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)

like image 716
WoJ Avatar asked Apr 23 '18 18:04

WoJ


3 Answers

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" ... >
like image 96
Max Avatar answered Nov 17 '22 00:11

Max


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>
like image 32
Richard Matsen Avatar answered Nov 16 '22 23:11

Richard Matsen


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>
like image 5
Sphinx Avatar answered Nov 16 '22 23:11

Sphinx