Modify position after transition ends - html

I'm trying to force changing property position to change after certain part of time (after all animations will end). For this I've created sample codepen so you can see what I've already achieved (more-less):
transition: width 0.5s ease-in, height 0.5s, position 0s ease 0.6s;
https://codepen.io/anon/pen/xpQdZm
As you can see hovering on the green container triggers transition of inside container grow (from right to left). What I would like to do is to make the container decrease when we remove the hover effect but to keep the position set to absolute while transition still lasts but set position to static after all transitions ends.
The more illustrative example can be see here: https://codepen.io/anon/pen/VyVzed
Because of the changing of position from absolute to static when hover is missing, the images are flickering and it looks so ugly.
.container {
display: flex;
flex-direction: row;
width: 800px;
}
.container div {
position: relative;
flex: 1;
}
.container div img {
width: 200px;
transition: width 0.5s ease-out;
z-index: 100;
}
.container div img:hover {
height: 200%;
position: absolute;
width: 200%;
left: 0;
right: auto;
top: 0;
bottom: auto;
z-index: 200;
transition: width 0.5s ease-out;
}
.container:nth-of-type(even) div img:hover {
bottom: 0;
top: auto;
}
.container div:nth-of-type(even) img:hover {
left: auto;
right: 0;
}
<div class="container">
<div>
<img src="https://media.giphy.com/media/pqwPJPgR6qCB2/giphy.gif">
</div>
<div>
<img src="https://img00.deviantart.net/f0f4/i/2017/182/c/6/pvz_heroes_random_colored_doodle_of_nc_by_crystilialance-dbeqssx.png">
</div>
<div>
<img src="http://images4.fanpop.com/image/answers/177000/177769_1287459785835_400_300.jpg">
</div>
<div>
<img src="http://1.bp.blogspot.com/-6BwaeUjaDnM/TZSPiw4YeoI/AAAAAAAAAf4/YlxYyxxu6nE/s400/2.jpg">
</div>
</div>
<div class="container">
<div>
<img src="http://images4.fanpop.com/image/answers/177000/177769_1287459785835_400_300.jpg">
</div>
<div>
<img src="http://1.bp.blogspot.com/-6BwaeUjaDnM/TZSPiw4YeoI/AAAAAAAAAf4/YlxYyxxu6nE/s400/2.jpg">
</div>
<div>
<img src="https://media.giphy.com/media/pqwPJPgR6qCB2/giphy.gif">
</div>
<div>
<img src="https://img00.deviantart.net/f0f4/i/2017/182/c/6/pvz_heroes_random_colored_doodle_of_nc_by_crystilialance-dbeqssx.png">
</div>
</div>
I know I can set div to fixed height but the problem is I want images to be scaled by its width.

Instead of thinking about changing position why not changing how the animation works. You may try the use of scale and adjust transform-origin to decide how the image should move (and also optimize your markup)
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 400px;
}
.container img {
width: 100px;
height: 100px;
transition: 0.5s ease-out;
transform-origin: top left;
}
.container img:nth-child(even) {
transform-origin: top right;
}
.container img:nth-child(2n+5) {
transform-origin: bottom left;
}
.container img:nth-child(2n+6) {
transform-origin: bottom right;
}
.container img:hover {
position: relative;
z-index: 2;
transform: scale(2);
}
<div class="container">
<img src="https://lorempixel.com/100/100/">
<img src="https://lorempixel.com/150/150/">
<img src="https://lorempixel.com/200/200/">
<img src="https://lorempixel.com/300/300/">
<img src="http://1.bp.blogspot.com/-6BwaeUjaDnM/TZSPiw4YeoI/AAAAAAAAAf4/YlxYyxxu6nE/s400/2.jpg">
<img src="http://1.bp.blogspot.com/-6BwaeUjaDnM/TZSPiw4YeoI/AAAAAAAAAf4/YlxYyxxu6nE/s400/2.jpg">
<img src="https://media.giphy.com/media/pqwPJPgR6qCB2/giphy.gif">
<img src="https://img00.deviantart.net/f0f4/i/2017/182/c/6/pvz_heroes_random_colored_doodle_of_nc_by_crystilialance-dbeqssx.png">
</div>

Related

Can't quite get image to scale, and use overflow:hidden to work

Here is a link to a demo
I'm not sure what I'm missing, I've done this before a few times but It's been a day of fighting this particular CSS. I want the image to enlarge, but stay within the dimensions, so a zoom effect versus any enlargement. I've attempted to move the overflow:hidden into other parent or children, but it doesn't have an effect. I've played around with the display settings as well.
Any advice? The JSfiddle link is above, and the code below. Thanks for taking a look!
#purple-square {
width: 355px;
height: 255px;
background-image: url("../img/website_cards/purple_card.png");
border-radius: 10px;
}
#migraine-dentistry {
width: 355px;
height: 255px;
background-image: url("../img/website_cards/migraine_dentistry_card.png");
border-radius: 10px;
}
/* need position: relative in shell otherwisee the elements disappear */
#shell {
margin: auto;
width: 355px;
height: 255px;
position: relative;
transform-origin: center;
transition: 0.3s ease-in-out;
}
#shell:hover {
transform: scale(1.2);
}
#container {
width: 100%;
overflow: hidden;
display: inline-block;
transition: 0.3s;
margin: 0 auto;
}
#container div {
position: absolute;
left: 0;
transition: 0.3s ease-in-out;
}
#container:hover {
transition: ease-in-out 0.3s;
}
#container div.bottom:hover {
opacity: 0;
}
and here is the HTML setup:
<body>
<div id="shell">
<div id="container">
<div id='purple-square' class="top"></div>
<div id='migraine-dentistry' class="bottom"></div>
</div>
</div>
</body>
Full working code snipped below my steps
remove unnecessary elements Removed purple square, because it's never seen in wanted animation.
Removed the part the full #container div.bottom:hover part.
Removed every style that begins with #shell in the css and later trigger the animation on #container:hover.
main issue Add an #migraine-dentistry after the #container:hover animation, so if someone hovers the container it effects the #migraine-dentistry element. (#container:hover #mi.. {trans..})
In this (#container:hov..) element remove everything and
insert transform: scale(1.2);
because we just want to scale if user is hovering.
Remove whole #container div {..} style element, because we will directly add these styles to the #migraine-dentistry element.
In #container define px values for
> width: 355px; and height: 255px;
just because we not use the #shell element anymore. Also
> set position: relative; and z-index: 2;
that the #migrain.. element is inside his parent. And
> set border-radius: 15px;
for styling. Finally
>remove the display and transition values
because they are simply not needed.
last In #migraine-de.. styles
>set width: 100%; and height: 100%;
to fit div to parent.
> remove border-radius tag
because it's set by the #container
> add transition: 0.3s ease-in-out;
to transition like you wanted.
#container {
border-radius: 15px;
width: 355px;
height: 255px;
overflow: hidden;
z-index: 2;
position: relative;
}
#container:hover #migraine-dentistry {
transform: scale(1.2);
}
#migraine-dentistry {
width: 100%;
height: 100%;
transition: 0.3s ease-in-out;
background-image: url('https://images.unsplash.com/flagged/photo-1563248101-a975e9a18cc6?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80');
}
<body>
<div id="shell">
<div id="container">
<div id='migraine-dentistry' class="bottom"></div>
</div>
</div>
</body>
I know these long nights where you just can't get it done.

Div taking up full width of page

I've implemented a hover state that overlays text when a div is hovered.
Here is the code -
.desktop-image {
position: relative;
}
.img_description {
position: absolute;
top: -13%;
bottom: 0;
left: 0;
right: 0;
color: #000;
visibility: hidden;
opacity: 0;
transition: opacity .7s, visibility .7s;
}
.desktop-image:hover .img_description {
visibility: visible;
opacity: 1;
}
<div id="images" class="misma">
<div class="desktop-image">
<img src="http://via.placeholder.com/200x200">
<p class="img_description">This image looks super neat.</p>
</div>
<div class="mobile-image-misma">
<img src="http://via.placeholder.com/100x100">
</div>
</div>
The problem
When I inspect the page I notice that the div .desktop-image is taking up the full width of the screen (see pic).
Question
How can I make this div wrap to the size of the actual image, so that the hover state is ONLY implemented when that image is hovered, as opposed to when anywhere within the blue section is hovered.
Thanks
By default div's are defined with display: block, meaning that they will take the entire available width.
You can specify that .desktop-image will be display: inline-block; and you will get the wanted result.
My suggestion to you is to use semantic HTML, there are 2 element that are dedicated to what you trying to achieve figure & figcaption.
Added an example with them.
.desktop-image {
position: relative;
display: inline-block;
}
.desktop-image img {
vertical-align: middle;
}
.img_description {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
color: #000;
visibility: hidden;
opacity: 0;
transition: opacity .7s, visibility .7s;
}
.desktop-image:hover .img_description {
visibility: visible;
opacity: 1;
}
<div id="images" class="misma">
<div class="desktop-image">
<img src="http://via.placeholder.com/200x200">
<p class="img_description">This image looks super neat.</p>
</div>
<div class="mobile-image-misma">
<img src="http://via.placeholder.com/100x100">
</div>
<figure class="desktop-image">
<img src="http://via.placeholder.com/200x200">
<figcaption class="img_description">This image looks super neat.</figcaption>
</figure>
</div>
Please see this.
.desktop-image {
position: relative;
display: inline-block;
}
.img_description {
position: absolute;
top: -13%;
bottom: 0;
left: 0;
color: #000;
visibility: hidden;
opacity: 0;
transition: opacity .7s, visibility .7s;
right:0;
}
.desktop-image:hover .img_description {
visibility: visible;
opacity: 1;
}
<div id="images" class="misma">
<div class="desktop-image">
<img src="http://via.placeholder.com/200x200">
<p class="img_description">This image looks super neat.</p>
</div>
<div class="mobile-image-misma">
<img src="http://via.placeholder.com/100x100">
</div>
</div>
By default div tag has a default display property display: block
In your code
<div class="desktop-image"> div appear full width of the display
set a width: and a min-height: property to solve the problem
.desktop-image {
position: relative;
width: 200px; /*new*/
height: 200px; /*new*/
}
Add CSS property clear: both to the div with the class desktop-image.
Specify the width of the .desktop-image class in percentage like .desktop-image{width:70%;} or whatever percentage suit the page design.
By doing that image will remain in this .desktop-image div.

Slideshow not centering?

I have a slideshow that I wanted to center, but I can't center it properly, the left part of the image stands exacly in the middle, so the image is not centered, anyone has an idea why?
Here's the following code and images:
CSS
.slider {
width: 100%;
margin: auto;
height:400px;
background-color: rgba(0,0,0,0.1);
}
.slider-wrapper{
width: 100%;
height: 400px;
}
.slide {
position: absolute;
max-width: 100%;
max-height: 400px;
margin:auto;
opacity: 0;
transition: opacity 500ms linear;
}
.slider contains: .slider-wrapper and .slide, .slide is the class I use for each image.
HTML
<div class="slider" id="main-slider">
<div class="slider-wrapper">
<img src="images/eventos/image1.png" class="slide" />
<img src="images/eventos/image2.png" class="slide" />
<img src="images/eventos/image3.png" class="slide" />
<img src="images/eventos/image4.png" class="slide" />
</div>
</div>
This image contains text-align:center and margin: 0 auto
And this one doens't
My code contains jquery so the slideshow works, if needed, please ask so I put it in too.
UPDATE
I discovered the problem, the problem is the position: absolute in those images, I deleted every css and any div I had and left the the .slide and just the images, in .slide I just left position: absolute and it still didn't work, so what can I do?
You can't apply text-align:center alignment on a absolute positioned element. Remove the absolute position and the images should center when using text-align in your wrapper:
.slider {
width: 100%;
margin: auto;
height:400px;
background-color: rgba(0,0,0,0.1);
}
.slider-wrapper{
text-align:center;
width: 100%;
height: 400px;
}
.slide {
width: 100%;
height: 400px;
opacity: 1;
transition: opacity 500ms linear;
border:1px solid black;
}
However, It is unclear from your code whether the absolute position is required. If so, you may need to resort to js calculations.
UPDATE
From OP comment, position absolute is required. Therefore, it is necessary to set the left attribute on slides. If the slide width is known, you could calculate by subtracting half of the viewport width from half of the slide width. For instance, on a 200px wide slide:
left:calc(50vw - 100px);
Assuming slides have variable width, resort to js:
var myElement = document.getElementById('foo');
var width = myElement.offsetWidth;
myElement.style.left = 'calc(50vw - ' + width / 2 + 'px)';
In lieu of finding elements by id, requiring individual ids for each slide, you may want to store all slides in an object array using getElementsByClassName('slide') and retrieving the width according to the slide currently displayed.
If you want to center an element that is set to position: absolute, you need to set the left and right properties to 0. I.e. right: 0 and left: 0. Check out the code below:
.slide {
position: absolute;
max-width: 100%;
max-height: 400px;
width: 200px;
height: 200px;
margin: 0 auto;
left: 0;
right: 0;
/* opacity: 0; */
transition: opacity 500ms linear;
border: 1px solid #000;
}
.slider {
width: 100%;
margin: auto;
height:400px;
background-color: rgba(0,0,0,0.1);
}
.slider-wrapper{
width: 100%;
height: 400px;
}
.slide {
position: absolute;
max-width: 100%;
max-height: 400px;
width: 200px;
height: 200px;
margin: 0 auto;
left: 0;
right: 0;
/* opacity: 0; */
transition: opacity 500ms linear;
border: 1px solid #000;
}
<div class="slider" id="main-slider">
<div class="slider-wrapper">
<img src="images/eventos/image1.png" class="slide" />
<img src="images/eventos/image2.png" class="slide" />
<img src="images/eventos/image3.png" class="slide" />
<img src="images/eventos/image4.png" class="slide" />
</div>
</div>
Maybe try position: fixed; and then top: 50%; left: 50%;
The answer for me was controlling the width of the of the direct children of the class uk-slider-items through uk-child-width-1-3#m as follows:
<div class="uk-container">
<h1 class="uk-heading-line uk-text-center uk-padding-large"><span>Similar Products</span></h1>
<div uk-slider="center: true">
<div class="uk-position-relative uk-visible-toggle uk-light">
<ul class="uk-slider-items uk-child-width-1-2 uk-child-width-1-3#s uk-child-width-1-3#m uk-grid uk-grid-match" >
<li v-for="(pro,index) in category" :key="index">
<div class="uk-card uk-card-default">
<div class="uk-card-media-top">
<img src="/product.jpg" alt="">
</div>
<div class="uk-card-body">
<h3 class="uk-card-title">{{pro.name}}</h3>
<p>{{pro.details}}</p>
</div>
</div>
</li>
</ul>
<a class="uk-position-center-left uk-position-small uk-background-secondary" href="#" uk-slidenav-previous uk-slider-item="previous"></a>
<a class="uk-position-center-right uk-position-small uk-background-secondary" href="#" uk-slidenav-next uk-slider-item="next"></a>
</div>
<ul class="uk-slider-nav uk-dotnav uk-flex-center uk-margin"></ul>
</div>

Transition centered text to left / right edges without overflowing

I was able to transition text-align from center to left. With this code, if you run it, then hover over, you'll see the top one goes to the left. However the bottom overflows on the right; how can I figure out how to make the transition to right not overflow?
Note: This is a demo of my real application, which has strings/elements of unknown/variable width, from 1 to anything to fill a single line (no wrapping).
.header {
position: fixed;
width: 70%;
background-color: springgreen;
}
.title {
text-align: center;
}
.menu {
text-align: center;
}
.trans-left {
transition: margin-right 1s;
}
.trans-right {
transition: margin-left 1s;
}
.header:hover .trans-left {
margin-right: 100%;
}
.header:hover .trans-right {
margin-left: 100%;
}
<body>
<div class='header'>
<div class='title'>
<span class='trans-left'>This one goes left</span>
</div>
<div class='menu'>
<span class='trans-right'>This one goes right</span>
</div>
</div>
</body>
You're aligning the text elements like this:
margin-left: 100%;
margin-right: 100%;
This positions each element – from the starting point of the box – to the left and right edges.
Hence, the left edge of the left-moving box will align with the left edge of the container.
And the left edge of the right-moving box will align with the right edge of the container. This causes the rest of this box to overflow.
Try this instead:
margin-right: 90%; /* adjust as needed */
Edit based on revised question
Here is an alternative solution that works regardless of content width.
.header {
position: fixed;
width: 70%;
background-color: springgreen;
}
.title, .menu {
text-align: center;
position: relative;
width: 100%;
height: 50px;
}
.trans-left {
position: absolute;
left: 50%;
transform: translateX(-50%);
transition: 1s;
}
.trans-right {
position: absolute;
right: 50%;
transform: translateX(50%);
transition: 1s;
}
.header:hover .trans-left {
left: 0;
transform: translateX(0);
transition: 1s;
}
.header:hover .trans-right {
right: 0;
transform: translateX(0);
transition: 1s;
}
<div class="header">
<div class="title">
<span class="trans-left">This one goes left</span>
</div>
<div class="menu">
<span class="trans-right">This one goes right</span>
</div>
</div>
More details: Element will not stay centered, especially when re-sizing screen

rotated text that is aligned to the top left corner outside of the image?

I was wondering what would be the most efficient way to place a rotated text directly outside the image's top left corner? Please keep in mind that I would like it if the height of the text box aligns with the height of the image, and the image scale will vary (tall images, short image, wide images, etc.)
Here is a visual of what I would like to achieve:
How might I do this? Thank you in advance!
Whoops, forgot to add the jsfiddle. You can view it here!
.image.information {
display:block;
position:absolute;
margin:0;
top:45%;
left:100%;
height:100%;
-webkit-transition:all 250ms linear;
-o-transition:all 250ms linear;
transition:all 250ms linear;
transform:rotate(-90deg);
-webkit-transform:rotate(-90deg);
-moz-transform:rotate(-90deg);
-ms-transform:rotate(-90deg);
-o-transform:rotate(-90deg);
filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
}
.image-wrap {
height: 100%;
width: 100%;
display: block;
}
.image-inner img {
width: 500px;
height: auto;
display: block;
}
<div class="image-wrap">
<img class="image-inner" src="http://i.stack.imgur.com/YyMHW.jpg" alt="" />
<div class="image information">
information<br/>
informa<br/>
info
</div>
</div>
This is possible using CSS3 transforms, but requires an extra element in your DOM:
<div class="image-wrap">
<img class="image-inner" src="http://media.creativebloq.futurecdn.net/sites/creativebloq.com/files/images/2013/08/korea5b.jpg" alt="" />
<div class="image information">
<div class="info-inner">
information
<br/>informa
<br/>info
</div>
</div>
</div>
Now with some absolute-positioning magic:
.image.information {
position:absolute;
left: 0;
top: 0;
bottom: 0;
width: 75px;
background: #ccc;
}
.info-inner {
text-align: center;
position: absolute;
top: 50%;
left: 50%;
margin-top:-75px;
margin-left: -75px;
height:55px;
width: 150px;
vertical-align: bottom;
transform: rotate(90deg);
}
.image-wrap {
height: 100%;
width: 100%;
position: relative;
}
img.image-inner {
width: 300px;
margin-left: 75px;
}
Note that there's no simple way to have vertically-centered text without specifying an explicit text height. In this case I have chosen 55px. It will stretch to match the height of any image you specify.
JSFiddle: http://jsfiddle.net/zephod/ckqcLsbv/2/