How to slide-transition two blocks with Vue.js? - vue.js

I'm trying to write a Vue.js transition that slides out an element and at the same time slides in another one. I almost have it working, but the elements bump each other when the animation starts.
Here is my CodePen and the code:
// pug/jade
#app
.elems
transition-group(name="elem")
li.elem(v-for="(elem, index) in elems"
v-if="index === currentElem"
#click="currentElem = currentElem === 0 ? 1 : 0" :key="index") {{ elem
// stylus
.elems
display: flex
align-items: center
justify-content: center
height: 100vh
position:relative
.elem
display: block
text-align: center
font-size: 30px
padding: 30px
border-radius: 20px
border: 2px solid black
user-select: none
cursor: pointer
&-enter-active, &-leave-active
transition: 1s
&-enter
transform: translateX(-100vw)
&-leave-to
transform: translateX(100vw)
// js
new Vue({
el: '#app',
data() {
return {
elems: ['hello there', 'hello yourself'],
currentElem: 0
}
}
})

You need absolute position of the .elem as i understand what you want.
otherwise they cant colide
try this css:
.elems
display: flex
align-items: center
justify-content: center
height: 100vh
width: 100vw
position: relative
overflow: hidden
.elem
display: block;
position: absolute
top: 50%;
left: 50;
margin-top: -30px;
margin-left: -150px
text-align: center
width: 300px
height: 60px
line-height: 60px
vertical-align: middle
font-size: 30px
border-radius: 20px
border: 2px solid black
user-select: none
cursor: pointer
&-enter-active, &-leave-active
transition: 1s
&-enter
transform: translateX(-100vw)
&-leave-to
transform: translateX(100vw)

Related

Safari linear gradient

I have a trouble using linear-gradient in Safari 15.2.
I wanna to create a block with fade effect at the end if children do not fit.
I have created an example: https://codepen.io/serejich/pen/xxXLvEG.
Code:
<div class="gradient-container">
<div class="elements">
<p>Element 1</p>
<p>Element 2</p>
<p>Element 3</p>
</div>
<div class="gradient"></div>
</div>
* {
margin: 0;
}
.gradient-container {
background-color: coral;
width: 200px;
height: 30px;
position: relative;
display: flex;
align-items: center;
}
.elements {
padding: 0 10px;
display: flex;
column-gap: 10px;
overflow-x: hidden;
}
.elements p {
color: #fff;
white-space: nowrap;
}
.gradient {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(to right, rgba(255, 255, 255, 0) calc(100% - 50px), coral);
}
If you will open this in Safari, there would be something like a white area at the right of block.
What causes this and are there any ways to fix it?
This is a bug in safari that has to do with the way browsers interpolate between gradients.
A common answer is to do what you did, using rgba(255, 255, 255, 0), however, Safari still interprets this as white and leads to that unwanted additional of white to the gradient. A fix is to use the same color you are transitioning from (coral in this case) and set it to transparent, which for coral would be rgba(255, 127, 80, 0). The example below uses the code from your pen with the fix applied for safari.
See this stack for more
* {
margin: 0;
}
.gradient-container {
background-color: coral;
width: 200px;
height: 30px;
position: relative;
display: flex;
align-items: center;
}
.elements {
padding: 0 10px;
display: flex;
column-gap: 10px;
overflow-x: hidden;
}
.elements p {
color: #fff;
white-space: nowrap;
}
.gradient {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
/*RGBA equivalent to coral html color with alpha set to 0 - fixes safari interpolation bug*/
background: linear-gradient(to right, rgba(255, 127, 80, 0) calc(100% - 50px), coral);
}
<div class="gradient-container">
<div class="elements">
<p>Element 1</p>
<p>Element 2</p>
<p>Element 3</p>
</div>
<div class="gradient"></div>
</div>

Vue js Vue-cli performing "npm run build", compiles css for image opacity to 1%

when I perform npm run serve everything work as intended.
when I perform npm run build there is "no error".
when I loot at the website the images can't be seen, then I inspect element I see the image opacity in my gallery section changes to 1%.
this is my template code:
<div class="gallery container">
<div
class="images"
v-for="(image, index) in images"
:key="index"
>
<img :src="image.small" #click="selectImage(index)" />
</div>
</div>
My scss code:
<style lang="scss" scoped>
.gallery-wrapper {
padding: 3rem 0;
.gallery {
display: grid;
grid-template-columns: repeat(4, 1fr);
align-items: center;
.images {
display: flex;
justify-content: center;
align-items: center;
img {
height: auto;
cursor: pointer;
width: 100%;
opacity: 85%;
border: 5px solid aliceblue;
&:hover {
opacity: 100%;
transition: 0.5s;
border: none;
margin: 5px 0;
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.62);
width: 90%;
}
}
}
}
}
</style>
other images are working fine. only the gallery images changes opacity when performing npm run build.
I look at the dist folder it generated a class with 1% opacity.
build result dist/css/app.ae40bac8.css:
.gallery-wrapper .gallery .images img[data-v-c5a51ec0] {
height: auto;
cursor: pointer;
width: 100%;
opacity: 1%;
border: 5px solid #f0f8ff;
}
.gallery-wrapper .gallery .images img[data-v-c5a51ec0]:hover {
opacity: 1%;
-webkit-transition: 0.5s;
transition: 0.5s;
border: none;
margin: 5px 0;
-webkit-box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.62);
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.62);
width: 90%;
}
it seems the webpack generated the wrong opacity.
Something that worked for me is using 0.85 instead of 85%

Overlay on hover in vue.js

Im trying to implement displaying text when hovering over an image in vue.js but I am a bit stuck. Im trying to implement this example on an array with multiple images:
https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_image_overlay_fade
I got a pretty big vue file but here is the essential:
template:
</template>
[...]
<div v-for="item in filteredPeople" v-bind:key="item.id" class="list-complete-item">
<router-link #mouseover.native="hovertext" :to="'/'+item.link">
<img class="list-complete-img" :src="'http://placehold.it/400x300?text='+item.id" alt>
</router-link>
</div>
[...]
</template>
script
<script>
export default {
data() {
return {
info: [
{
id: 1,
title: "Title one",
link: "project1",
hovertext: "project1 hover text lorem lorem lorem",
category_data: {
"1": "Category 1"
}
},
[...]
methods: {
hovertext() {
console.log("");
},
I had some idea to try to use a method to put the text in a div under the image but then I cannot get the text to get above the image on hover. And I cannot get the method right ... Not really sure this is a good way doing it,
I also found this codepen example:
https://codepen.io/oliviaisarobot/pen/xzPGvY
This is pretty close to what I want to do but I cannot get the text to display here either.
I am a bit lost. Any help how to do this in vue?
---------- UPDATE ----------
I want the image boxes to stretch so they always fits the window but I seems to get a gap between my flexbox rows which I cannot seem to get rid of. You can see the white space. I attach my stylesheet.
.list-complete {
display: flex;
height: auto;
flex-direction: row;
flex-flow: row wrap;
}
.list-complete-item {
flex: 0 1 50%;
display: inline-block;
}
.list-complete-item a {
display: inline-block;
position: relative;
width: 100%;
height: auto;
outline: 1px solid #fff;
}
.list-complete-img {
width: 100%;
}
.text {
color: rgb(186, 74, 74);
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
text-align: center;
}
.list-complete-item a:hover .overlay {
opacity: 1;
}
.overlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow: hidden;
height: 60%;
width: 100%;
opacity: 0;
transition: 0.5s ease;
background-color: #008cba;
}
You don't need to use js(vue) events. Do it with plain css, like in example you linked to.
Go with this template:
<div v-for="item in filteredPeople" v-bind:key="item.id" class="list-complete-item">
<router-link :to="'/'+item.link">
<img class="list-complete-img" :src="'http://placehold.it/400x300?text='+item.id" alt>
<div class="overlay">
<div class="text">{{ item.hovertext }}</div>
</div>
</router-link>
</div>
And style it up:
.list-complete-item {
width: 400px;
height: 300px;
display: inline-block;
}
.list-complete-item a {
display: inline-block;
position: relative;
width: 400px;
height: 300px;
}
.list-complete-item a .image {
display: block;
width: 100%;
height: auto;
}
.list-complete-item a .overlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
width: 100%;
opacity: 0;
transition: .5s ease;
background-color: #008CBA;
}
.list-complete-item a:hover .overlay {
opacity: 1;
}
.list-complete-item a .text {
color: white;
font-size: 20px;
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
text-align: center;
}
And the final result:

How to disable v-tooltip when user click outside

I use v-tooltip to show tooltip on every cell of table
<td v-tooltip="{content: 'some content', trigger: 'click'}"></td>
But I want when user click another cell, current tooltip will disapear, I have tried "autoHide" property, but it not working.
Thanks
v-tooltip repository:
https://github.com/Akryum/v-tooltip
It's a late answer but maybe it can help someone else:
you can add the tooltip component as a ref and call the hide method:
this.$refs.popover.hide()
I think you will have to use the more customizable v-popover component. The v-tooltip directive doesn't seem to handle manual triggering, and you need manual triggering.
console.clear();
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!',
selectedCell: null
}
})
body {
font-family: sans-serif;
margin: 42px;
}
.tooltip {
display: block !important;
z-index: 10000;
}
.tooltip .tooltip-inner {
background: black;
color: white;
border-radius: 16px;
padding: 5px 10px 4px;
}
.tooltip .tooltip-arrow {
width: 0;
height: 0;
border-style: solid;
position: absolute;
margin: 5px;
border-color: black;
}
.tooltip[x-placement^="top"] {
margin-bottom: 5px;
}
.tooltip[x-placement^="top"] .tooltip-arrow {
border-width: 5px 5px 0 5px;
border-left-color: transparent !important;
border-right-color: transparent !important;
border-bottom-color: transparent !important;
bottom: -5px;
left: calc(50% - 5px);
margin-top: 0;
margin-bottom: 0;
}
.tooltip[x-placement^="bottom"] {
margin-top: 5px;
}
.tooltip[x-placement^="bottom"] .tooltip-arrow {
border-width: 0 5px 5px 5px;
border-left-color: transparent !important;
border-right-color: transparent !important;
border-top-color: transparent !important;
top: -5px;
left: calc(50% - 5px);
margin-top: 0;
margin-bottom: 0;
}
.tooltip[x-placement^="right"] {
margin-left: 5px;
}
.tooltip[x-placement^="right"] .tooltip-arrow {
border-width: 5px 5px 5px 0;
border-left-color: transparent !important;
border-top-color: transparent !important;
border-bottom-color: transparent !important;
left: -5px;
top: calc(50% - 5px);
margin-left: 0;
margin-right: 0;
}
.tooltip[x-placement^="left"] {
margin-right: 5px;
}
.tooltip[x-placement^="left"] .tooltip-arrow {
border-width: 5px 0 5px 5px;
border-top-color: transparent !important;
border-right-color: transparent !important;
border-bottom-color: transparent !important;
right: -5px;
top: calc(50% - 5px);
margin-left: 0;
margin-right: 0;
}
.tooltip[aria-hidden='true'] {
visibility: hidden;
opacity: 0;
transition: opacity .15s, visibility .15s;
}
.tooltip[aria-hidden='false'] {
visibility: visible;
opacity: 1;
transition: opacity .15s;
}
<script src="//unpkg.com/popper.js"></script>
<script src="//unpkg.com/vue/dist/vue.js"></script>
<script src="//unpkg.com/v-tooltip"></script>
<div id="app">
<table border="1">
<tr v-for="i in 3">
<td #click="selectedCell = i">
<p><span>This is cell {{ i }}</span></p>
<v-popover trigger="manual" :open="selectedCell === i">
<template slot="popover">
<p>
{{ message }}
</p>
</template>
</v-popover>
</td>
</tr>
</table>
</div>

IE 10 vertically stretching images?

heres the code. it seems to be working on this editor on stackoverflow...but when rendered on ie10 it take the palceholder image and stretches it (almost as if it were 200% in height and 100% in width
<style>
section`enter code here` {
padding: 1em;
text-align: center;
}
.content {
margin: 0 auto;
max-width: 1000px;
}
.content > h2 {
clear: both;
margin: 0;
padding: 4em 1% 0;
color: #484B54;
font-weight: 800;
font-size: 1.5em;
}
.content > h2:first-child {
padding-top: 0em;
}
.grid {
position: relative;
margin: 0 auto;
padding: 1em 0 4em;
max-width: 1100px;
list-style: none;
text-align: center;
}
/* Common style */
.grid figure {
position: relative;
float: left;
overflow: hidden;
margin: 10px 1%;
min-width: 310px;
max-width: 310px;
max-height: 310px;
width: 48%;
background: #d30c55;
text-align: center;
}
.grid figure img {
position: relative;
display: block;
height: 100%;
width:auto;
max-height: 100%;
max-width: 100%;
opacity: 1;
}
.grid figure figcaption {
padding: 0em 2em 2em 2em;
color: #ffffff;
text-transform: uppercase;
font-size: 1.25em;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.grid figure figcaption::before,
.grid figure figcaption::after {
pointer-events: none;
}
.grid figure figcaption,
.grid figure figcaption > a {
position:absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
/* Anchor will cover the whole item by default */
/* For some effects it will show as a button */
.grid figure figcaption > a {
z-index: 1000;
text-indent: 200%;
white-space: nowrap;
font-size: 0;
opacity: 0;
}
.grid figure h2 {
word-spacing: -0.15em;
font-weight: 200;
}
.grid figure h2 span {
font-weight: 400;
}
.grid figure h2,
.grid figure p {
margin: 0;
}
.grid figure p {
letter-spacing: 1px;
font-size: 68.5%;
}
/*---------------*/
/***** transition *****/
/*---------------*/
figure.effect-transition {
background-color: #a39d99;
}
figure.effect-transition img {
/* opacity: 0.7; */
-webkit-transition: opacity 0.35s, -webkit-transform 0.35s;
transition: opacity 0.35s, transform 0.35s;
-webkit-transform: scale(1);
transform: scale(1);
}
figure.effect-transition:hover img {
opacity: 0.1;
-webkit-transform: scale(1);
transform: scale(1);
}
figure.effect-transition h2 {
margin-top: 80%;
-webkit-transition: -webkit-transform 0.35s;
transition: transform 0.35s;
-webkit-transform: translate3d(0,20px,0);
transform: translate3d(0,20px,0);
}
figure.effect-transition p {
margin: 1em 0 0;
padding: 0.6em;
border: 1px solid #fff;
opacity: 0;
-webkit-transition: opacity 0.35s, -webkit-transform 0.35s;
transition: opacity 0.35s, transform 0.35s;
-webkit-transform: translate3d(0,20px,0) scale(1.1);
transform: translate3d(0,20px,0) scale(1.1);
}
figure.effect-transition:hover h2 {
-webkit-transform: translate3d(0,0,0);
transform: translate3d(0,-170px,0);
}
figure.effect-transition:hover p {
opacity: 1;
-webkit-transform: translate3d(0,0,0) scale(1);
transform: translate3d(0,-30px,0) scale(1);
}
#media screen and (max-width: 50em) {
.content {
padding: 0 10px;
text-align: center;
}
.grid figure {
display: inline-block;
float: none;
margin: 10px auto;
width: 100%;
}
}
</style>
<div class="container">
<div class="content">
<div class="grid">
<figure class="effect-transition" style="background-color: #d40e8c;"><img alt="blabla" src="https://placeholdit.imgix.net/~text?txtsize=33&txt=310%C3%97310&w=310&h=310" /> <figcaption>
<h2>Go back <span>home</span></h2>
<p>Some random text here</p>
View more</figcaption></figure>
</div>
</div>
</div>
(I do not have the code on me at this exact moment to show).
I've built something with HTML5 and CSS3. Everything works wonderfully except on some peoples computers (everyone has IE10), the image files are being stretched vertically ?
This is being built for my company (internal)...Is there a reason why this would happen on only some peoples version of IE10?
Thank you,
Nick
Please Check with the css as shown below,
img.someClass{
max-width:100%;
width:auto
}
What did the trick for me was setting a max-width at something like
max-width: 110px;
and afterwards a width:100%;
images were nog not stretched anymore
UPDATE: nvm, this caused the img to have a width of 0 on Firefox