top
and left
take precedence over bottom
and right
. This means that when these values are specified, they will override the effects of the properties considered "less important."
Take a look at the demonstration below:
div {
position: absolute;
left: 0;
right: 0;
}
<div>I am positioned both to the left and right,<br>but the left side has priority!</div>
As top
and bottom
are separate CSS properties, transitioning between them is not possible.
Additionally, since top
takes precedence, the transition from an "undefined" state to a newly declared value is not achievable, resulting in CSS immediately applying the final value. (The same applies to left
and right
)
There are two potential methods to achieve your desired outcome:
- Use JavaScript to find either the initial or final value you wish to transition between.
- Utilize CSS'
transform
property for transitioning.
For a CSS-only approach:
- Initiate at the bottom-right corner
- Transition to the top-left corner using
bottom: 100%; right: 100%;
. This action positions the element's bottom-right corner on the top-left corner of its parent, effectively placing it outside the parent by its width and height.
- Employ the
transform
property to counteract the overflow caused by step 2, as the percentages used in transform
are relative to the element's dimensions, not its parent.
Since transform
defaults to values of 0, it can be transitioned without pre-declaration.
View the example below:
// By using 'setTimeout()', the following steps occur:
// 1. The function is placed on the call stack
// 2. The DOM creation continues since the script has executed
// 3. The page initially runs
// 4. The call stack is executed
//
// Step 4 results in: '.drifted' being added after
// the page has been rendered, necessitating the transition
// as a mandatory operation for the rendering engine
setTimeout(() => {
document.querySelector('div').classList.add('drifted');
}, 0);
html, body {
margin: 0;
width: 100%;
height: 100%;
}
div {
position: absolute;
bottom: 0;
right: 0;
transition: 2.5s linear;
white-space: nowrap;
}
div.drifted {
bottom: 100%;
right: 100%;
transform: translate(100%, 100%);
}
<div>I'm drifting!</div>