Reloading page is flashing content on slot in vue component - vue.js

Is there any way to avoid this flicker on page refresh, it's a modal component which takes HTML as slot, but when I refresh the page it flashes. My app is not using a router so it's not complete SPA.
see the gif.
Here is the code.
.body {
padding: 2em;
text-align: center;
display: table-cell;
vertical-align: middle;
}
.modal-mask {
position: absolute;
z-index: 9998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, .5);
display: table;
transition: opacity .3s ease;
}
.modal-wrapper {
display: table-cell;
vertical-align: middle;
}
.modal-container {
width: 70%;
margin: 1em auto;
padding: 20px 30px;
background-color: #fff;
border-radius: 2px;
box-shadow: 0 2px 8px rgba(0, 0, 0, .33);
transition: all .3s ease;
font-family: Helvetica, Arial, sans-serif;
}
.modal-header h3 {
margin-top: 0;
color: #42b983;
}
.modal-body {
margin: 20px 0;
}
.modal-default-button {
float: right;
}
/*
* The following styles are auto-applied to elements with
* transition="modal" when their visibility is toggled
* by Vue.js.
*
* You can easily play with the modal transition by editing
* these styles.
*/
.modal-enter {
opacity: 0;
}
.modal-leave-active {
opacity: 0;
}
.modal-enter .modal-container,
.modal-leave-active .modal-container {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
<!-- template for the modal component -->
<script type="text/x-template" id="modal-template">
<transition name="modal">
<div class="modal-mask">
<div class="modal-wrapper">
<div class="modal-container">
<div class="modal-header">
<slot name="header">
default header
</slot>
<button class="modal-default-button" #click="$emit('close')">Close</button>
</div>
<div class="modal-body">
<slot name="body">
default body
</slot>
</div>
<div class="modal-footer">
<slot name="footer">
default footer
<button class="modal-default-button" #click="$emit('close')">
OK
</button>
</slot>
</div>
</div>
</div>
</div>
</transition>
</script>
<!-- app -->
<div id="app">
<button id="show-modal" #click="showModal = true">Show Modal</button>
<!-- use the modal component, pass in the prop -->
<modal v-if="showModal" #close="showModal = false">
<!--
you can use custom content here to overwrite
default content
-->
<div slot="body">
<div class="modal-body">
<h4>Text in a modal</h4>
<p>Duis mollis, est non commodo luctus, nisi erat porttitor ligula.</p>
<h4>Popover in a modal</h4>
<p>This button should trigger a popover on click.</p>
<h4>Tooltips in a modal</h4>
<p>This link and that link should have tooltips on hover.</p>
<hr>
<h4>Overflowing text to show scroll behavior</h4>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
</div>
</div>
<h3 slot="header">custom header</h3>
</modal>
</div>
<script src="https://unpkg.com/vue#latest/dist/vue.js"></script>
<script>
// register modal component
Vue.component('modal', {
template: '#modal-template'
})
// start app
new Vue({
el: '#app',
data: {
showModal: false
}
})
</script>

Most usually this is due to the fact that your vue.js requires to load until it is able to do what you want.
You basically load html content which is by default visible.
After the html you load vue and vue will hide your content due to your v-if or v-show statements. The most simple way to ensure something like this is not happening is to use the v-cloak directive plus a little bit of css.
Place it at a very high level as given in this example
<div id="app"><!-- vue mounted at this div -->
<div v-cloak>
<!-- your actual code / content -->
</div>
</div>
And the css
[v-cloak] { display: none; }
The v-cloak property will be removed as soon as vue is done with loading. Therefore everything is hidden until vue is done with loading. This should ensure your content is not flashing.

Related

What is overriding a media query?

I am practicing with css-grid and media queries. When I add the media query for max-width 768px nothing happens when I shrink the screen to that size and I still see the 4 columns instead of the 2 I am trying to apply.
I am using Visual Studio Code and the live server. I already tried opening the html directly in Finder (I am using mac os), i have refreshed the page and still have the same issue.
Something is overriding that media query when I have a screen size under 768px and when I inspect the file I see these messages below. How can I solve this or what am I doing wrong here?
Very thankful for any help!
body {
background: green;
}
.grid {
display: grid;
grid-template-columns: repeat(4, auto);
grid-gap: 1rem;
}
#media (max-width: 768px) {
.grid {
display: grid;
grid-template-columns: repeat (2, auto);
}
}
<body>
<div class="grid">
<div class="item">
<h3>Heading 1</h3>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Quidem debitis nesciunt eum accusamus corrupti voluptates officiis. Molestiae deleniti pariatur ipsum rerum facilis dicta fugiat quibusdam, nulla quo suscipit, consectetur ratione.</p>
</div>
<div class="item">
<h3>Heading 2</h3>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Quidem debitis nesciunt eum accusamus corrupti voluptates officiis. Molestiae deleniti pariatur ipsum rerum facilis dicta fugiat quibusdam, nulla quo suscipit, consectetur ratione.</p>
</div>
<div class="item">
<h3>Heading 3</h3>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Quidem debitis nesciunt eum accusamus corrupti voluptates officiis. Molestiae deleniti pariatur ipsum rerum facilis dicta fugiat quibusdam, nulla quo suscipit, consectetur ratione.</p>
</div>
<div class="item">
<h3>Heading X</h3>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Quidem debitis nesciunt eum accusamus corrupti voluptates officiis. Molestiae deleniti pariatur ipsum rerum facilis dicta fugiat quibusdam, nulla quo suscipit, consectetur ratione.</p>
</div>
</div>
</body>
There is a space between the word repeat and the opening bracket. Remove that and all should be OK.
The yellow warning triangle shows that something was wrong with that line.

HTML - Gap between Main content and Footer

I'm using this footer as reference to my Website but I've detected a situation when the main content is short, which creates a gap between both elements (See image below).
Anyone can give me a hand in this? :) I'll post the necessary code!
#inherits LayoutComponentBase
<div class="sidebar">
<NavMenu />
</div>
<div class="main">
<div class="top-row px-4 auth">
<LoginDisplay />
</div>
#Body
<!-- footer -->
https://codepen.io/scanfcode/pen/MEZPNd (HTML and CSS of Footer is here)
</div>
main CSS:
You may need to update your HTML structure in right panel.
follow
<div class="content">
<h1>Sticky Footer with Negative Margin 1</h1>
<div class="push">
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.
</p>
</div>
</div>
<footer class="footer">
Footer
</footer>
<style>
html, body {
height: 100%;
margin: 0;
}
.content {
padding: 20px;
min-height: 100%;
margin: 0 auto -50px;
}
.footer,
.push {
height: 50px;
}
* {
box-sizing: border-box;
}
body {
font: 16px Sans-Serif;
}
h1 {
margin: 0 0 20px 0;
}
p {
margin: 20px 0 0 0;
}
footer {
background: #42A5F5;
color: white;
line-height: 50px;
padding: 0 20px;
}
</style>

Smooth transition of v-if/else height in Vue.js

I have a component that loads data and then displays it. The user can modify the module which triggers new data to load. While data is loading a loading state is shown. I would like to smoothly transition between these states using animate.css. I have it roughly working, but there is still some jumpiness to it. How can you get the height of the element to smoothly scale on changing state?
JS:
new Vue({
el: '#demo',
data: {
show: true
},
methods: {
loadData() {
this.show = !this.show
setTimeout(() => {
this.show = !this.show
}, 1000);
}
}
})
HTML:
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.2/animate.min.css">
<div id="demo" style="border:1px solid #ddd">
<button v-on:click="loadData()">
Toggle
</button>
<transition
appear-active-class="animated fadeIn"
enter-active-class="animated fadeIn"
leave-active-class="animated fadeOutDown faster"
mode="out-in"
>
<p v-if="!show" key="loading" style="border:1px solid #ddd">Loading</p>
<p v-if="show" key="data" style="border:1px solid #ddd">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In urna metus, pulvinar a dapibus nec, mattis eu nunc. Sed sed lorem id quam tincidunt accumsan. Nam pharetra, nunc facilisis malesuada tincidunt, nulla mi molestie neque, quis dictum dolor dolor a mi. Suspendisse sed est mollis risus vehicula viverra ac in nunc. Duis cursus mauris vitae sapien tincidunt, sit amet sodales dui mattis. Aliquam dui magna, sagittis at tristique et, consequat at sapien. Quisque ac bibendum urna, et aliquet orci. Ut vitae ipsum id odio consectetur eleifend a nec dui. Suspendisse nulla quam, suscipit in pretium id, dignissim sit amet tortor. Aliquam aliquam, leo et tincidunt venenatis, neque purus cursus elit, ac commodo quam leo at ligula.
</p>
</transition>
</div>
https://jsfiddle.net/2ud5s1ne/11/
Shameless plug, I created vue-smooth-reflow for this exact use case.
Here's a demo: https://jsfiddle.net/guanzo/snyvoxec/1/
new Vue({
el: '#demo',
mixins: [SmoothReflow],
data: {
show: true
},
mounted(){
this.$smoothReflow()
},
methods: {
loadData() {
this.show = !this.show
setTimeout(() => {
this.show = !this.show
}, 1000);
}
}
})

how to vertically centre align ion-slides in ion-content?

I have an ion-slides page:
<ion-content padding>
<ion-slides pager="true">
<ion-slide class="step-one">
<h1>Welcome</h1>
<p>Lorem ipsum dolor sit amet, massa nam ante. Vel lacus viverra volutpat tortor ligula ornare, varius ut mauris ipsum mus torquent, scelerisque suspendisse penatibus, purus et arcu ipsum vehicula quam luctus. Consectetuer sed urna accumsan. Nec viverra felis varius pretium, volutpat in et cras, odio consectetuer lacinia risus feugiat sit etiam, commodo pulvinar, dolor non et inventore.</p>
<p> </p> <!-- TODO: figure out how to add spacing properly -->
</ion-slide>
<ion-slide class="step-two">
<h1>Heading</h1>
<p>blah, blah</p>
</ion-slide>
<ion-slide class="step-three">
<h1>Heading</h1>
<p>blah, blah</p>
<ion-button (click)='finish()'>FINISH!</ion-button>
</ion-slide>
</ion-slides>
</ion-content>
How can I vertically centre the ion-slide? Currently it sits at the top of the page.
The solution for me was to add this css:
.slides {
display: flex !important;
justify-content: center !important;
align-items: center !important;
height: 100%;
}

In Vue.js how to make a nav fade in on scroll down event and fade out where scroll pageYOffset = 0

I am working on a Vue.js project and i am stuck on a small animation for the header navbar.
I want to listen to the users scroll event and fade in and out the nav-bar, if user scrolls down, fade in and if user scrolls back to top: 0 fade out, and show a full screen intro without navigation bar. the nav is fixed/sticky at the top.
How can i do this using Vue.js?
for a better visualization :
this is the screenshot of my page
I adapted this solution to your case by adding showNavbar property to your data object that change the navbar state and using transition element with name='fade' that wraps navbar element, in your CSS you have to add the following rules :
.fade-enter-active
{
transition: all 1s;
}
.fade-leave-active {
transition: all 2s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
finally you should add an event listener to scrolling event like :
window.addEventListener('scroll', this.handleScroll);
and checking the value of window.pageYOffset as follow :
window.pageYOffset>0?this.showNavbar=true:this.showNavbar=false;
the following code works fine :
new Vue({
el: '#app',
data() {
return {
showNavbar:false
}
},
methods:{
handleScroll (event) {
window.pageYOffset>0?this.showNavbar=true:this.showNavbar=false;
}
},
created () {
window.addEventListener('scroll', this.handleScroll);
},
destroyed () {
window.removeEventListener('scroll', this.handleScroll);
}
})
body {
margin: 0;
font-size: 28px;
font-family: Arial, Helvetica, sans-serif;
}
.header {
background-color: #f1f1f1;
padding: 30px;
text-align: center;
}
#navbar {
overflow: hidden;
background-color: #333;
}
#navbar a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
}
#navbar a:hover {
background-color: #ddd;
color: black;
}
#navbar a.active {
background-color: #4CAF50;
color: white;
}
.content {
padding: 16px;
}
.sticky {
position: fixed;
top: 0;
width: 100%;
}
.sticky + .content {
padding-top: 60px;
}
.fade-enter-active
{
transition: all 1s;
}
.fade-leave-active {
transition: all 2s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" >
</head>
<body>
<div id="app">
<div class="header">
<h2>Scroll Down</h2>
<p>Scroll down to see the sticky effect.</p>
</div>
<transition name="fade">
<div id="navbar" class="sticky" v-if="showNavbar">
<a class="active" href="javascript:void(0)">Home</a>
News
Contact
</div>
</transition >
<div class="content">
<h3>Sticky Navigation Example</h3>
<p>The navbar will stick to the top when you reach its scroll position.</p>
<p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
<p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
<p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
<p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
<p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
<p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
<p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
</div>
</div>
</body>
</html>