Css left transition dont work with height and left - html

I'm trying to make somekind of toolbox, I need make toolbox apearing from left on opening, so I make transition from left=-1500px to left=0; and that works fine.
when I try make some kind of minimalization adding transition to height=0;width=0; after I added: transition: width, height 1s linear; transition left stop working.
Here is example: https://jsfiddle.net/wsghc65c/7/
my css:
.modal {
visibility: visible;
position: fixed;
z-index: 1;
left: 10%;
top: 10%;
width: 80%;
height: 80%;
margin: auto;
opacity: 1;
padding: 10px;
padding-top: 25px;
border-radius: 15px;
background-color: #aaa;
border-width: thin;
border-style: solid;
transition: visibility 0.1s linear;
transition: left 1s linear;
transition: width, height 1s linear;
}
.modal-content {
overflow: -moz-scrollbars-vertical;
overflow-x: hidden;
overflow-y: scroll;
max-height: 80vh;
mac-width: 86vh;
}
.modal-left-hide {
visibility: hidden;
left: -1500px;
}
.modal.minimized {
width: 0%;
height: 0%;
left: 10vh;
padding: 0;
margin: 0;
}

https://jsfiddle.net/wsghc65c/16/
Add the height width transition to the minimized class. You might want to set overflow hidden too.
.modal.minimized {
width: 0%;
height: 0%;
left: 10vh;
padding: 0;
margin: 0;
transition: width 1s linear, height 1s linear;
}

Related

Draw ideal symmetric css border with border-radius

I'm trying to draw a border with border-radius: 8px;. It perfectly draws symmetrical border without border-radius but messed up with it. What am I doing wrong here?
setTimeout(function(){
document.getElementsByClassName('border')[0].classList.add('animate-border');
},100)
body {
background: white;
}
.main-container {
position:absolute;
top:50%;
left:50%;
transform: translate(-50%, -50%);
width: 300px;
height: 460px;
background: ;
}
.border:before {
border:2px solid black;
border-radius: 8px;
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 0;
border-top: 0;
border-left: 0;
pointer-events: none;
overflow: hidden;
opacity: 0;
transform: rotateZ(0) rotate(0);
}
.border.animate-border:before {
opacity: 1;
height: 100%;
width: 100%;
transition: opacity 0s ease,width 0.5s ease, height 0.5s 0.5s ease;
overflow: hidden;
transform: rotateZ(0) rotate(0);
}
.border:after {
border: 2px solid black;
border-radius: 8px;
content: '';
position: absolute;
top: 0;
right: 0;
width: 0;
height: 0;
border-bottom: 0;
border-right: 0;
opacity: 0;
overflow: hidden;
transform: rotateZ(0) rotate(0);
}
.border.animate-border:after {
opacity: 1;
height: 100%;
width: 100%;
overflow: hidden;
transition: opacity 0s 1s ease,width 0.5s 1s ease, height 0.5s 1.5s ease;
transform: rotateZ(0) rotate(0);
}
<div class='main-container border'></div>
CSS:
body {
background: white;
}
.main-container {
position:absolute;
top:50%;
left:50%;
transform: translate(-50%, -50%);
width: 300px;
height: 460px;
background: ;
}
.border:before {
border:2px solid black;
border-radius: 8px;
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 0;
border-top: 0;
border-left: 0;
pointer-events: none;
overflow: hidden;
opacity: 0;
transform: rotateZ(0) rotate(0);
}
.border.animate-border:before {
opacity: 1;
height: 100%;
width: 100%;
transition: opacity 0s ease,width 0.5s ease, height 0.5s 0.5s ease;
overflow: hidden;
transform: rotateZ(0) rotate(0);
}
.border:after {
border: 2px solid black;
border-radius: 8px;
content: '';
position: absolute;
top: 0;
right: 0;
width: 0;
height: 0;
border-bottom: 0;
border-right: 0;
opacity: 0;
overflow: hidden;
transform: rotateZ(0) rotate(0);
}
.border.animate-border:after {
opacity: 1;
height: 100%;
width: 100%;
overflow: hidden;
transition: opacity 0s 1s ease,width 0.5s 1s ease, height 0.5s 1.5s ease;
transform: rotateZ(0) rotate(0);
}
First of all, you may apply box-sizing: border-box in all elements (and pseudo-elements) to make the alignment easier. It makes the browser count the border on width and height calculation. That solves your misalignment problem.
Second, since you're resizing the element, the rounded corners get stretched in the middle of the animation. I see no easy way prevent that from happening. But you can disguise it by also animating the right property of the :after pseudo-element, like I did below. That and a faster timing may get you there with your animation.
BTW, it would be more performant if you animated transform: scaleX(...) scaleY(...) instead of width and height, because they're GPU accelerated.
setTimeout(function(){
document.getElementsByClassName('border')[0].classList.add('animate-border');
},100)
body {
background: white;
}
*, *:before, *:after { /* Applies to ALL elements and pseudo-elements */
box-sizing: border-box;
}
.main-container {
position:absolute;
top:50%;
left:50%;
transform: translate(-50%, -50%);
width: 300px;
height: 160px;
background: ;
}
.border:before {
border:2px solid black;
border-radius: 8px;
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 0;
border-top: 0;
border-left: 0;
pointer-events: none;
overflow: hidden;
opacity: 0;
transform: rotateZ(0) rotate(0);
}
.border.animate-border:before {
opacity: 1;
height: 100%;
width: 100%;
transition: opacity 0s ease,width 0.5s ease, height 0.5s 0.5s ease;
overflow: hidden;
transform: rotateZ(0) rotate(0);
}
.border:after {
border: 2px solid black;
border-radius: 8px;
content: '';
position: absolute;
top: 0;
right: 6px; /* a little offset to hide the squared edge */
width: 0;
height: 0;
border-bottom: 0;
border-right: 0;
opacity: 0;
overflow: hidden;
transform: rotateZ(0) rotate(0);
}
.border.animate-border:after {
opacity: 1;
height: 100%;
width: 100%;
right: 0; /* the wanted right position */
overflow: hidden;
transition: opacity 0s 1s ease,width 0.5s 1s ease, height 0.5s 1.5s ease,right 1s 1s ease; /* Animated 'right' so it slowly gets back to its position */
transform: rotateZ(0) rotate(0);
}
<div class='main-container border'></div>
PS.: I changed the box height to make it fit inside the snippet here.
You just need to specify properties below to pseudo elements because they are position absolute
Add top:0 to .border:before css and add left:0 to .border:after css

Border animation Keyframes/CSS Animation

I have an animation that I want to achieve and I am not able to be getting it right.
I've searched the internet and found some solutions, however they have a slight change in the animation.
I want a border animation that starts at the bottom left goes to top left then top right then bottom right and finally back to bottom left. Each animation after another and the borders once appeared should stay visible afterwards.
This is the code I've managed to get: https://jsfiddle.net/gwbn427m/
div {
width: 300px;
height: 200px;
display: inline-block;
padding: 30px;
/*bottom: -25;*/
position: relative;
border: 0;
}
.draw {
transition: color 0.25s;
}
.draw::before,
.draw::after {
/* Set border to invisible, so we don't see a 4px border on a 0x0 element before the transition starts*/
border: 2px solid transparent;
width: 0;
height: 0;
box-sizing: inherit;
content: '';
position: absolute;
}
/* This covers the top & right borders (expands right, then down)*/
.draw::before {
left: 0;
bottom: 0;
}
/* And this the bottom & left borders (expands left, then up) */
.draw::after {
right: 0;
top: 0;
}
.draw:hover {
color: red;
}
/* Hover styles */
.draw:hover::before,
.draw:hover::after {
width: 100%;
height: 100%;
}
.draw:hover::before {
border-top-color: res; /*Make borders visible */
border-right-color: red;
transition:
width 0.25s ease-out 0.25s, /* And then height */
height 0.25s ease-out; /* Width expands first */
}
.draw:hover::after {
border-bottom-color: red; /* Make borders visible */
border-left-color: red;
transition:
border-color 0s ease-out 0.5s, /* Wait for ::before to finish before showing border*/
width 0.25s ease-out 0.75s, /* And finally height*/
height 0.25s ease-out 0.5s; /*And then exanding width*/
}
<div class="draw">
<img src="http://via.placeholder.com/200x100">
</div>
However I've tried it with those https://codepen.io/sean_codes/pen/YZWqLo keyframe animation and couldn't get it right either.
I really would appreciate any help!
To achieve that you will need two divs so that you can create four different elements using its pseudo elements :before and :after and then use transition-delay to delay the transition
.main {
width: 200px;
height: 200px;
position: relative;
}
.item {
height: 100%;
}
.main:before,
.main:after,
.item:before,
.item:after {
content: "";
position: absolute;
background: red;
}
.main:before {
width: 2px;
height: 0;
bottom: 0;
left: 0;
}
.main:after {
height: 2px;
width: 0;
top: 0;
left: 0;
}
.item:before {
width: 2px;
height: 0;
top: 0;
right: 0;
}
.item:after {
height: 2px;
width: 0;
right: 0;
bottom: 0;
}
.main:hover:before {
height: 100%;
transition: all .5s linear;
}
.main:hover:after {
width: 100%;
transition: all .5s linear .5s;
}
.main:hover .item:before {
height: 100%;
transition: all .5s linear 1s;
}
.main:hover .item:after {
width: 100%;
transition: all .5s linear 1.5s;
}
<div class="main">
<div class="item">
Some Content
</div>
</div>

make parent div same size as child div and center additional child element in parent

I am making a slideshow. The parent container is called slide and has the following child elements:
prev, next and figure.
I would like the parent div to be the same size as the child element 'figure' so that the next and prev divs are aligned to the right and left of the 'figure' element. I do not wish to set the width and height of the parent fixed as it would not be responsive.
I do not wish to add the 'next' and 'prev' divs inside the 'figure' element as i plan to have a lot of figure element and would not like it to be repetitive, adding these divs inside each figure element.
/* Styles go here */
.slide{
padding: 0;
width: 100%;
display: inline-block;
margin: 0 auto;
position: relative;
}
.slide:before{
display: block;
padding-top: 25%;
}
.next, .prev{
color: #fff;
position: absolute;
background: rgba(0,0,0, 1);
top: 50%;
z-index: 1;
font-size: 2em;
margin-top: -.75em;
opacity: 0.9;
user-select: none;
}
.next:hover, .prev:hover{
cursor: pointer;
opacity: 1;
}
.next{
right: 0;
padding: 10px 5px 15px 10px;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
.prev{
left: 0;
padding: 10px 10px 15px 5px;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
figure{
width: 100%;
position: absolute;
opacity: 0;
margin:0;
padding:0;
transform: scale(0);
transition: all .7s ease-in-out;
-webkit-transition: all .7s ease-in-out;
-moz-transition: all .7s ease-in-out;
-o-transition: all .7s ease-in-out;
}
img{
width: 100%;
height: auto;
border-radius: 3px;
}
figcaption{
position: absolute;
font-family: sans-serif;
font-size: 1em;
bottom: .35em;
right: .15em;
color: #fff;
background: rgba(0,0,0, .9);
border-radius: 3px;
padding: .2em;
}
figcaption a{
color: #fff;
}
figure.show{
width: 100%;
opacity: 1;
position: absolute;
transform: scale(1);
transition: opacity 1s ease-in-out;
-webkit-transition: opacity 1s ease-in-out;
-moz-transition: opacity 1s ease-in-out;
-o-transition: opacity 1s ease-in-out;
}
<div id='slide' class='slide'>
<figure id="0" class="show">
<img src="http://www.naamagazine.com/wp-content/uploads/2016/05/couple-getaways-image-520x400.jpeg">
<figcaption>Some Text</figcaption>
</figure>
<span class="prev">‹</span>
<span class="next">›</span>
</div>
I would just like the parent to be responsive and same size as the child element with prev and next divs attached to the parent.
The buttons actually are aligned to the edges of the container already - the issue is just that the image doesn't scale up along with it. In your style.css, change this:
img{
max-width: 100%;
to this:
img{
width: 100%;
and you should see the image edges and the arrows line up, and scale as the window does.
As far as getting the arrows vertically centered - that could be tricky unless you set a height on the .slide element. This can still be responsive, as long as you know the aspect ratios of the images in the slides. Here's a trick to do that using bottom padding - set it based on the aspect ratio you want. Then set your images to width: 100%; height: 100%; position: relative; and as long as the proportions are right, they should all fit properly.
figure {
position: absolute;
width: 100%;
height: 0;
/* This will make a box that's always twice as wide as it is tall */
padding-bottom: 50%;
/* This one's twice as tall as it is wide */
padding-bottom: 200%;
}

Unable to set height of hover overlay to 100% of container

I'm using the Instafeed.js plugin and trying to style the "likes" hover overlay to fill the entire image box, however, I'm struggling to set the height to 100%.
I'm trying to avoid setting the container's height to a pixel value since the entire plugin is currently responsive.
I've looked around and tried different combinations of display and position values, but it's been mostly trial and error.
CSS:
#instafeed {
width: 100%;
margin-bottom: 80px;
}
#instafeed a {
position: relative;
}
#instafeed .ig-photo {
width: 25%;
vertical-align: middle;
}
#instafeed .likes {
width: 100%;
height: auto;
top: 0;
left: 0;
right: 0;
position: absolute;
background: #f18a21;
opacity: 0;
font-family: 'LinotypeUniversW01-Thin_723604', Arial, sans-serif;
font-size: 28px;
color: #ffffff;
line-height: 100%;
text-align: center;
text-shadow: 0 1px rgba(0, 0, 0, 0.5);
-webkit-font-smoothing: antialiased;
-webkit-transition: opacity 100ms ease;
-moz-transition: opacity 100ms ease;
-o-transition: opacity 100ms ease;
-ms-transition: opacity 100ms ease;
transition: opacity 100ms ease;
}
#instafeed a:hover .likes {
opacity: 0.8;
}
Demo: http://jsfiddle.net/rc1wj5t9/
Any help/advice would be appreciated!
It's because the anchor elements are inline by default, which means that they are not inheriting the height of their children img elements.
One possible solution is to set the display of the anchor elements to inline-block, and specify a width of 25%. Then for the children img elements, set a max-width of 100%:
Updated Example
#instafeed a {
position: relative;
display: inline-block;
max-width: 25%;
}
#instafeed .ig-photo {
max-width: 100%;
vertical-align: middle;
}
#instafeed .likes {
width: 100%;
height: auto;
top: 0; right: 0;
bottom: 0; left: 0;
}
To center the text, I used one of the techniques for vertically/horizontally centering text from one of my previous answers.
#instafeed .likes > span {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
white-space: nowrap;
}
Here is how I fixed it.
CSS
#instafeed {
width: 100%;
margin:0px;
}
#instafeed a {
position: relative;
display:inline-block;
float:left;
width: 25%;
}
#instafeed .ig-photo {
width: 100%;
vertical-align: middle;
}
#instafeed .likes {
position: absolute;
width: 100%;
opacity: 0;
font-family: 'LinotypeUniversW01-Thin_723604', Arial, sans-serif;
font-size: 28px;
color: #ffffff;
text-align: center;
top: 50%;
transform: translateY(-50%);
text-shadow: 0 1px rgba(0,0,0,0.5);
-webkit-font-smoothing: antialiased;
-webkit-transition: opacity 100ms ease;
-moz-transition: opacity 100ms ease;
-o-transition: opacity 100ms ease;
-ms-transition: opacity 100ms ease;
transition: opacity 100ms ease;
z-index:10;
}
#instafeed a:hover .likes {
opacity: 1;
}
#instafeed a:hover::after{
content:"";
position:absolute;
width: 100%;
height: 100%;
top: 0; left: 0;
background: #f18a21;
opacity:0.7;
z-index: 5;
}
updated fiddle

How to make a transition slide from down to up not up to down

So basically I got this transition.
At the beginning height is 0 and when you hover the DIV specified height becomes 100px.
it all works smoothly except, the height starts from the top.
How can I make it start from bottom?
this is what I mean.
http://i.stack.imgur.com/HHBVY.gif
So how can i make it slide from down to up?
This is the css I am using for this.
.bd-box tr td .bd-name {
background: rgba(186,0,0,.8);
width: 100px;
height: 0;
text-align: center;
margin-top: -20px;
position: absolute;
opacity: 1;
transition: .3s ease-in-out;
overflow: hidden;
}
.bd-box tr td:hover .bd-name {
height: 20px;
}
Use positioning and move the element up rather than changing the height.
div
{
width: 100px;
height: 100px;
position: relative;
background: black;
overflow: hidden;
}
div div
{
background: red;
position: absolute;
top: 100px;
-webkit-transition-duration: 0.5s;
-moz-transition-duration: 0.5s;
-ms-transition-duration: 0.5s;
-o-transition-duration: 0.5s;
transition-duration: 0.5s;
}
div:hover div
{
top: 80px;
}
JSFiddle