CSS transition - expanding child div to its parent width and height - css

Here's what I got up to in terms of starting point - https://codepen.io/illianyh/pen/bGpJgma.
/*For IE CSS3 transition property works starting IE10*/
* {box-sizing: border-box;}
body {font-family: 'Playfair Display', serif; margin: 0;text-align: center}
h1 {font-weight: normal;color: #6A5953}
kbd {font-size: 0.9em;display:inline-block;line-height:1.1;}
div, h2, img {
-webkit-transition: .5s ease-in-out;
-moz-transition: .5s ease-in-out;
-o-transition: .5s ease-in-out;
transition: .5s ease-in-out;
}
h2 {
color: #E39F81;
text-shadow: 1px 1px 0 #FFE3BD;
}
h2:hover {
text-shadow: 1px 1px 0 #FFE3BD, 2px 2px 0 #FFE3BD, 3px 3px 0 #FFE3BD, 4px 4px 0 #FFE3BD, 5px 5px 0 #FFE3BD;
}
.parent {
width: 560px;
height: 386px;
margin: 0 auto;
background: black;
position: relative;
}
.box {
width: 50%;
position: absolute;
right: 0;
top: 153px;
}
.four {
width: 423px;
height: 248px;
background-color: #95A1B1;
margin: 0 auto;
}
.four:hover {
width: 500px;
height: 300px;
box-shadow: 0 15px 15px -10px rgba(0,0,0, .5);
}
<h1>CSS3 Transition examples</h1>
<div class="parent"></div>
<div class="box"><div class="four"><kbd>width, height, box-shadow</kbd></div></div>
</div>
How do I make the child to expand itself towards, inside and on top of the its parent instead of expanding itself on the outside.
Here's a diagram what I'm trying to achieve:
Initial state (the arrows represent the direction of the child expanding):
this is the final state and in the end the child div has the same width and height of the parent. The parent is now hidden behind the child:

Parent has fixed size with position relative
Child has percentage or any size type with position absoulte and top left positions related to parent fixed size (could be even percentage parent)
Transition works over known sizes
Here is an example i fixed for you: CODEPEN
.parent {
position:relative;
width: 560px;
height: 386px;
margin: 0 auto;
background: black;
position: relative;
background: red;
}
.child {
position:absolute;
background: blue;
height:70%;
width: 50%;
right: -20%;
top:15%;
box-shadow: 0 15px 15px -10px rgba(0,0,0, .5);
transition: all 0.5s ease;
}
.parent:hover .child{
top: 0%;
right: 0;
width:100%;
height:100%;
box-shadow: 0 0px 0px 0px rgba(0,0,0, .5);
}
.text{
position:absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}

The solution is first to place the child inside the parent with position and size so that it is completely congruent with the parent (Let's call this the actual position of the child). Then you use the transform property with the scale and translate functions to position the child at its starting position. Finally, when the user hovers over the child, you reset the translate and scale values back to their defaults. This has the result of animating the child to the actual position.
.parent {
width: 200px;
height: 150px;
margin: 0 auto;
background: black;
position: relative;
}
.box {
transform: translate(100px, 53px) scale(0.5);
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
transition: .5s ease-in-out;
background: orange;
}
.box:hover {
transform: translate(0, 0) scale(1);
}
<h1>CSS3 Transition examples</h1>
<div class="parent">
<div class="box"></div>
</div>
This is a simplified version of the FLIP technique.

Related

How to permanently fix position of a div inside absolute div or how to use overflow hidden outside of a div

I want to transform on hover .div1 absolute div but .div2 will be fix at the same position. I don't want to use transform for .div2, because of lag.
Without Fix Position
What i want (Fixed Position)
If this is not possible, then there anyway to use overflow hidden outside the div?
Codepen - https://codepen.io/Ayan90510/pen/xxEwdQV
CSS & HTML
.div1 {
height: 200px;
width: 200px;
background: #ffc107;
top: 70px;
left: 10px;
right: 10px;
margin: 0 auto;
padding: 5px;
border-radius: 5px;
position: absolute;
transition: all .3s cubic-bezier(0.5, 0, 0, 0.5);
transform: translate(0);
overflow: hidden
}
.div2 {
width: calc(100% - 10px);
height: calc(100% - 10px);
margin: 5px;
background: #dc3545;
border-radius: 5px;
position: relative;
transition: all .3s cubic-bezier(0.5, 0, 0, 0.5);
}
.div1:hover {
transform: translate(50px, 50px);
}
.div1:hover .div2 {
/*transform: translate(-50px, -50px);*/
{
<div class="div1">
<div class="div2"></div>
</div>

CSS transform scalex line unconsistant height

I have a hover animation on a link. A line is drawn below the text. It's 2px in height. the problem is that it starts with one height and continues with another height.
Why is it doing that? It does not need to calculate anything because 2px is a fixed number.
How can I get around it?
The animated GIF is taken in Chrome.
:root {
--cp-500: #c53e3a;
--cp-700: #8d1d2d;
--cp-800: #721228;
}
.action a {
background: linear-gradient(45deg, var(--cp-500), var(--cp-800));
color: #fff;
border-radius: 100vh;
padding: .5rem 2rem;
display: inline-block;
border: 1px solid var(--cp-700);
transition: box-shadow 150ms ease-in;
box-shadow: 0 1.25rem 1rem -1rem var(--cp-800);
z-index: 1;
text-decoration: none;
position: relative;
}
.action a:hover {
box-shadow: 0 1rem 1rem -1rem var(--cp-800);
background: var(--cp-700);
}
.action a:before {
content: '';
position: absolute;
bottom: .5rem;
left: 2rem;
width: calc(100% - 4rem);
height: 2px;
background: var(--cp-500);
transform: scaleX(0);
transform-origin: top right;
transition: transform 1000ms ease-in;
z-index: -1;
}
.action a:hover:before {
transform-origin: top left;
transform: scaleX(1);
}
<div class="action">
Test
</div>
I was also able to reproduce your issue. As AlexioVay mentioned above, you should add a scaleY also. But it's not enough, you should set the scaleY to be almost the same as scaleX. Now the line has the same height from the start till the end. See this code: https://jsfiddle.net/q236tmuk/30/
I added the following change to your css:
.action a:hover:before {
transform-origin: top left;
transform: scaleX(1) scaleY(0.99);
}
The following scenario will also work well:
.action a:hover:before {
transform-origin: top left;
transform: scaleX(1) scaleY(1.01);
}
On hover the line height is the same from the start till the end. Don't use the same value for scaleX and scaleY, because that way the height will change after the transform event. It's a browser issue. The only solution is to use a small different value for scaleY.
You mentioned that this behaviour occurs when your browser size is 125%. I could also reproduce this behaviour and tested a lot, including attributes like height and max-height which didn't affect anything.
It seems that scaleX is the main issue and because you use an increased browser size, this behaviour is only visible in this specific browser size (or a bigger browser size than 125%). So it may also behave like this at 100%, but can't be seen since 2px is too small to see it with the human eye is my guess.
Therefore I have also added scaleY(1.2) to transform: on .action a:hover:before which prevents this jittery behaviour.
:root {
--cp-500: #c53e3a;
--cp-700: #8d1d2d;
--cp-800: #721228;
}
.action a {
background: linear-gradient(45deg, var(--cp-500), var(--cp-800));
color: #fff;
border-radius: 100vh;
padding: .5rem 2rem;
display: inline-block;
border: 1px solid var(--cp-700);
transition: box-shadow 150ms ease-in;
box-shadow: 0 1.25rem 1rem -1rem var(--cp-800);
z-index: 1;
text-decoration: none;
position: relative;
}
.action a:hover {
box-shadow: 0 1rem 1rem -1rem var(--cp-800);
background: var(--cp-700);
}
.action a:before {
content: '';
position: absolute;
bottom: .5rem;
left: 2rem;
width: calc(100% - 4rem);
height: 2px;
background: var(--cp-500);
transform: scaleX(0);
transform-origin: top right;
transition: transform 1000ms ease-in;
z-index: -1;
}
.action a:hover:before {
transform-origin: top left;
transform: scaleX(1) scaleY(1.2);
}
<div class="action">
Test
</div>

Span position absolute is not centered with top and left

I want to create a "X" with css spans and position absolute, but the spans aren't centered even if they should.
The container has the font-size of 1px. and a height and width of 100em. Therefore I can use 1em as 1% of the parents size.
I used transform-origin: 0px 5em; on the span, to rotate it without changing the starting point. The Element starts in 20% top and left (20em) and ends in 80% (top and left).
To get the required width i simply calculated: Square root( square of (60) * 2) (Pythagorean theorem) (60 because start and end 20 -- 100-20*2)
But for some reason the X is clearly not centered. Do you know what i did wrong?
body
{
margin: 0px;
}
.check
{
font-size: 1px;
position: relative;
height: 100em;
width: 100em;
background-color: white;
border-radius: 50%;
transition: .3s;
box-shadow: 0px 0px 10px red inset;
}
.check span
{
position: absolute;
display: block;
height: 10em;
width: 0px;
background-color: #00FF00;
transition:.3s;
}
.check.red span
{
background-color: #FF0000;
transform-origin: 0px 5em;
transform: rotate(45deg);
top: 20em;
left: 20em;
}
.check.red span:nth-of-type(2)
{
transform: rotate(135deg);
top: 20em;
left: 80em;
}
.check.red:hover span
{
width: 84.852813742em;
}
<body>
<div class="check red">
<span></span>
<span></span>
</div>
</body>
This isn't an automatic solution, but changing some values in your css i solved it:
body
{
margin: 0px;
}
.check
{
font-size: 1px;
position: relative;
height: 100em;
width: 100em;
background-color: white;
border-radius: 50%;
transition: .3s;
box-shadow: 0px 0px 10px red inset;
}
.check span
{
position: absolute;
display: block;
height: 10em;
width: 0px;
background-color: #00FF00;
transition:.3s;
}
.check.red span
{
background-color: #FF0000;
transform-origin: 0px 5em;
transform: rotate(45deg);
top: 18em;
left: 22em;
}
.check.red span:nth-of-type(2)
{
transform: rotate(135deg);
top: 18em;
left: 78em;
}
.check.red:hover span
{
width: 78em;
}
<body>
<div class="check red">
<span></span>
<span></span>
</div>
</body>
There are a few things you can do to make life easier here.
Firstly you can transform origin using a percentage, which means you don't need to calculate it yourself.
You can also position using a percentage, then offset using a transform (again with a percentage) to center no matter the size.
You can also set the width of the cross using a percentage, which will take it size from its parent.
Update:
Change the cross to animate from the top, rather than the center by using background gradients.
.check
{
position: relative;
height: 200px;
width: 200px;
background-color: white;
border-radius: 50%;
box-shadow: 0px 0px 10px red inset;
}
.check span
{
position: absolute;
display: block;
height: 20px;
width: 0%;
background: linear-gradient(to right, white 50%, red 50%);
background-size: 200% 100%;
background-position: left bottom;
top: 50%;
left: 50%;
transform-origin: center;
transition: background 0.3s ease;
}
.check.red span
{
transform: translate(-50%, -50%) rotate(-45deg);
}
.check.red span:last-child
{
transform: translate(-50%, -50%) rotate(-135deg);
}
.check.red:hover span
{
background-position: right bottom;
width: 70%;
}
<div class="check red">
<span></span>
<span></span>
</div>
Try this
use margin-top:-0.5rem;
.check span
{
position: absolute;
display: block;
height: 10em;
width: 0px;
background-color: #00FF00;
transition:.3s; margin-top:-0.5rem;
}
body
{
margin: 0px;
}
.check
{
font-size: 1px;
position: relative;
height: 100em;
width: 100em;
background-color: white;
border-radius: 50%;
transition: .3s;
box-shadow: 0px 0px 10px red inset;
}
.check span
{
position: absolute;
display: block;
height: 10em;
width: 0px;
background-color: #00FF00;
transition:.3s; margin-top:-0.5rem;
}
.check.red span
{
background-color: #FF0000;
transform-origin: 0px 5em;
transform: rotate(45deg);
top: 20em;
left: 20em;
}
.check.red span:nth-of-type(2)
{
transform: rotate(135deg);
top: 20em;
left: 80em;
}
.check.red:hover span
{
width: 84.852813742em;
}
<body>
<div class="check red">
<span></span>
<span></span>
</div>
</body>

I want .tabcontent to appear from 0 center to full size animated over .3 seconds

Sample of hover effect
I want the hover effect to be animated starting from 0 center out to full size over 0.3s. The effect is what I want ,but the animation isn't working.The page I'm going to build will consist of eight different images (two columns four in each) I want this hover effect to work as you hove hover each image.
#tabbox{
height: 300px;
position: relative;
//border: 2px solid #888;
}
#tabbox img{
cursor: pointer;
display: block;
width: 240px;
height: 240px;
}
.tab {
float: left;
}
.tabcontent{
position: absolute;
padding:10px;
top:0;
width: 0px;
height: 0px;
background:rgba(0, 0, 0, .5);
border:1px solid #fff;
margin:10px;
color:#fff;
display:none;
overflow:hidden;
-webkit-transition: height 0.3s ease-in-out;
-moz-transition: height 0.3s ease-in-out;
-o-transition: height 0.3s ease-in-out;
transition: height 0.3s ease-in-out;
}
.tabcontent:before{
content: "";
position: absolute;
z-index: -1;
top: 0;
left: 0;
right: 0;
bottom: 0;
-webkit-transform: scale(0);
transform: scale(0);
-webkit-transition-property: transform;
transition-property: transform;
-webkit-transition-duration: 0.3s;
transition-duration: 0.3s;
-webkit-transition-timing-function: ease-out;
transition-timing-function: ease-out;
}
.tab:hover > .tabcontent{
display: block;
width: 200px;
height: 200px;
}
.tab:hover:before, .tab:active:before{
-webkit-transform: scale(1);
transform: scale(1);
}
<div id="tabbox">
<div class="tab">
<img src="http://zone1.gingermartinco.netdna-cdn.com/wp-content/uploads/2012/04/Napa-Real-Estate-Realtor.jpg" />
<div class="tabcontent">
<p>Text box to describe the images around when you hover over them, this description will change depending on what image you hover over.</p>
</div><!--tabcontent-->
</div><!--tab-->
</div><!--tabbox-->
Just remove the display: none; from .tabcontent as this property can't be animated, only number properties can be animated.
Fiddle:
https://jsfiddle.net/uxouomoy/
Your fiddle and your question code is not the same.
But taking the code from the fiddle you should put the transition only in .tabcontent style. Use top and left properties to animate from the center position to the left corner position.
See the fiddle
Here's the css it is using:
#tabbox {
height: 300px;
position: relative;
//border: 2px solid #888;
}
#tabbox img {
cursor: pointer;
display: block;
width: 240px;
height: 240px;
}
.tab {
float: left;
}
.tabcontent {
position: absolute;
padding: 10px;
width: 0px;
height: 0px;
background: rgba(0, 0, 0, .5);
border: 1px solid #fff;
margin: 10px;
color: #fff;
display: block;
overflow: hidden;
top: 100px;
left: 100px;
visibility: hidden;
transition-timing-function: ease-in-out;
transition-duration: 0.3s;
transition: width top left;
}
.tab:hover > .tabcontent {
visibility: visible;
width: 200px;
height: 200px;
top: 0px;
left: 0px;
}
<div id="tabbox">
<div class="tab">
<img src="http://zone1.gingermartinco.netdna-cdn.com/wp-content/uploads/2012/04/Napa-Real-Estate-Realtor.jpg" />
<div class="tabcontent">
<p>Text box to describe the images around when you hover over them, this description will change depending on what image you hover over.</p>
</div>
<!--tabcontent-->
</div>
<!--tab-->
</div>
<!--tabbox-->

CSS transition - tilting test-tube containing liquid

I have a simple CSS3 transition that involves a test tube, containing liquid, being tilted 60 degrees to the right.
Of course, liquid always stays on the horizontal plane, and it's this effect I'm having trouble with. I do have it working in a fashion, but the liquid's transition is far from convincing.
The idea was to simply rotate the liquid element, which is a child of the tube element, by the same but opposite degree, so -60. So the net, visual effect is the liquid stays at rotation 0deg. The liquid element has adequate width to allow for this rotation without showing white space.
Code Pen: http://codepen.io/anon/pen/sIDtp (currently has only -moz prefixes, no -webkit)
HTML:
<div id='container'>
<div id='tube'><div></div></div>
<div id='tube_bottom'></div>
</div>
CSS
div, button { display: block; position: relative; }
#container {
width: 50px;
height: 150px;
top: 30px;
margin: 0 auto;
transition: -moz-transform 1s
}
#container.transition { moz-transform: rotate(60deg); }
#tube {
border: solid 6px red;
border-top: none;
border-bottom: none;
width: 100%;
height: 100%;
z-index: 1;
background: #fff;
overflow: hidden;
}
#tube_bottom {
width: 100%;
height: 30%;
border-radius: 50%;
position: absolute;
bottom: -15%;
border: solid 6px red;
background: blue;
}
#tube div {
position: absolute;
left: -175px;
width: 400px;
height: 85%;
top: 30%;
background: blue;
transition: -moz-transform 1s, top 1s;
}
#container.transition #tube div { moz-transform: rotate(-60deg); top: 70%; }
As you can see, I'm having to also modify the top property, which isn't ideal and tells me I'm probably not going about this the right way. It almost looks as if the liquid element is failing to rotate about its central point (which I believe is the default value for transform-origin.
Can anyone give me some tips as to how to make this transition look natural?
Different approach : How about skewing the water?
This tube is made with :
one div and 2 pseudo elements
transform skew and rotate
box-shadows
DEMO (no vendor prefixes)
HTML :
<div class="tube"></div>
CSS :
.tube {
border: solid 6px red;
border-top: none;
border-bottom:none;
width:50px;
height:180px;
position:relative;
margin:0 auto;
transition:transform 1s;
}
.tube:after, .tube:before {
content:'';
position:absolute;
width:100%;
background:blue;
}
.tube:after {
top:100%;
left:-6px;
width:100%;
padding-bottom:100%;
border: solid 6px red;
border-top: none;
border-bottom-left-radius: 50%;
border-bottom-right-radius: 50%;
box-shadow: 0px -30px 0px -6px blue, 0px -50px 0px -6px blue;
}
.tube:before {
bottom:0;
height: 100px;
width:50px;
z-index:-1;
transition:transform 1s;
}
.tube:hover {
transform: rotate(60deg);
}
.tube:hover:before {
transform: skewY(-60deg);
}
Since the width perspective of the tube increases as it turns, the effect speed of the tilting liquid should be inversely proportional, slower when it turns, and faster when it gets back...
I got a better looking effect by setting a different transition speed for turn, and turn back:
Updated Codepen
#tube div {
position: absolute;
left: -175px;
width: 400px;
height: 85%;
top: 30%;
background: blue;
transition: -webkit-transform 1s, top 0.5s;
}
#container.transition #tube div {
-webkit-transform: rotate(-60deg);
transition: -webkit-transform 1s, top 1.4s;
top: 70%;
}
Though it could still get some improvements... (Sorry, I changed it all to -webkit-)
But perhaps you should consider using animation and #keyframes, so you could set specific values on each percentage of the transition.

Resources