How to animate bottom: value to bottom: auto - css

I'm trying to create a menu that is hidden off screen on the top of the document. There is a little portion showing that will be hoverable which will bring the rest of the menu into view. Trying to animate bottom to auto but it isn't working. Was wondering if someone knows how or better way to create a menu off screen similar to my codepen.
http://codepen.io/anthony-dandrea/pen/EjqYqj
.hud is the class that's giving me the animation problem.
.hud {
position: absolute;
width: 100%;
text-align: center;
transition: all 1s;
bottom: calc(100% - 39px);
}
.hud:hover {
bottom: 80%;
bottom: auto;
}

As already mentioned by Patrick Allen in comments, you cannot animate/transition from or to an "auto" value using CSS. For your case, you could replace it with transform: translate() like in the below snippet and achieve the same effect.
Below is the relevant SCSS code and what it does:
The transform: translateY(-100%) moves the elements content upwards by the exact height of the container element. This would hide the whole container.
A top: 39px is added such that the chevron icon is still shown and only the content is hidden.
On hover the transform is nullified by doing transform: translateY(0%). This puts the element back in its original position.
But because of the top: 39px present in the unhovered state, the position of the container would be offset a bit and that can be nullified by adding top: 0px on hover.
.hud {
position: absolute;
width: 100%;
text-align: center;
transition: all 1s;
top: 39px;
transform: translateY(-100%);
&:hover {
top: 0px;
transform: translateY(0%);
}
}
body {
background: #121111;
}
.hud {
position: absolute;
color: red;
width: 100%;
text-align: center;
-webkit-transition: all 1s;
transition: all 1s;
top: 39px;
-webkit-transform: translateY(-100%);
-ms-transform: translateY(-100%);
transform: translateY(-100%);
}
.hud:hover {
top: 0px;
-webkit-transform: translateY(0%);
-ms-transform: translateY(0%);
transform: translateY(0%);
}
.pull-down {
color: #e6e6e6;
-webkit-transition: all 0.2s;
transition: all 0.2s;
cursor: pointer;
height: 24px;
margin-top: 15px;
font-size: 1.5em;
}
.pull-down:hover {
color: #fff;
}
.hud:hover .pull-down {
color: #fff;
-ms-transform: rotate(-180deg);
-webkit-transform: rotate(-180deg);
transform: rotate(-180deg);
}
<link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" rel="stylesheet" />
<div class="hud">
<div class="hud-internal">
<p>foobar</p>
</div>
<i class="fa fa-chevron-down pull-down" data-hud-toggle></i>
</div>

$('#click').click(function () {
var windowHeight = $(window).height();
var lineHeight = $('#line').height();
var desiredBottom = 100;
var newPosition = windowHeight - (lineHeight + desiredBottom);
$('#line').animate({top:newPosition},1000,function () {
$('#line').css({
bottom: desiredBottom,
bottom: 'auto'
});
});
});
Here jsfiddle

Give top: 0; to .hud element and it will work fine. Here is the codepen: http://codepen.io/anon/pen/KpOKdE

Related

CSS text alignment issue over Safari

The text is properly aligned in Chrome but as it goes in Safari the text messes up its position and touches the top of the container (text container)
Chrome: Chrome view
Safari: Safari view
As you can see in Safari, the text container (span) has its proper size but the text inside is touching the roof. I've tried things to solve this by messing the height, line height, position, etc but still no luck.
The current approach used in the image is I've made the span position absolute and align it in the center and it (span) is in the center but the text is not being aligned vertically. (Also tried the vertical-align property but no luck)
Are there any fix/workarounds for this?
Tech Stack: Gatsby with Tailwind + Modular sass
.linkButton {
padding-right: 30px;
padding-left: 8px;
position: relative;
background-color: rgb(85, 85, 85);
transition: 0.25s all ease-in-out;
display: flex;
line-height: 36px;
width: 180px;
min-height: 35px;
.text {
transition: 0.25s all ease-in-out;
height: 20px;
line-height: 20px;
position: absolute;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
&::after {
content: "";
background-color: #fff;
height: 12px;
width: 9px;
position: absolute;
top: 50%;
right: 9px;
transform: translateY(-50%);
clip-path: polygon(0 0, 100% 50%, 0 100%);
transition: 0.25s all ease-in-out;
z-index: 10;
}
&::before {
height: 100%;
width: 100%;
content: "";
position: absolute;
background-image: linear-gradient(to right, #4100a3 0%, #0d52ff 100%);
top: 0px;
left: 0px;
z-index: 5;
opacity: 0;
transition: 0.25s all ease-in-out;
}
&:hover {
width: 185px;
cursor: pointer;
.text {
transform: translate(4%, -50%);
-webkit-transform: translate(4%, -50%);
}
&::after {
transform: scale(1.25) translateY(-40%);
}
&::before {
opacity: 1;
}
}
}
<a href="/features">
<div class="index-module--linkButton--3DaPN mt-3 md:mt-12 mx-auto md:mx-0 flex items-center justify-center text-white">
<span class="index-module--text--QcmPb z-10">View all Features</span>
</div>
</a>
Solved! The issue was with font rendering as it differs between browsers, not some line-height issue...
This resolved my issue: Font Rendering / Line-Height Issue on Mac/PC (outside of element)

CSS Flipcard using Bulma tiles

I am hoping some of you might have some ideas regarding using Bulma Tiles (https://bulma.io/documentation/layout/tiles/). I am partially successful with getting the flip functionality to work using the input checkbox, but the content inside the tile is flipping, not the entire tile.
/* ==========================================
reference --> https://codepen.io/amazingrando/pen/yjbAh
========================================== */
.tile input[type="checkbox"] {
/*Hiding the checkbox. We never want to see it.*/
position: absolute;
left: -9999em;
}
.flip-tile {
cursor: pointer;
/*Animation elements*/
display: block;
perspective: 600px;
position: relative;
transition: all 0.1s;
&:hover {
transform: scale(1.02, 1.02);
}
}
.flip-tile-front, .flip-tile-back{
//position: absolute; top: 0; left: 0;
//width: inherit; height: inherit; /*Size of the card is set by the container*/
backface-visibility: hidden; /*Makes a card invisible from behind.*/
transform-style: preserve-3d;
transition: all 0.4s ease-in-out;
}
.flip-tile-front {
/*Default rotation values*/
transform: rotateX(0deg) rotateY(0deg);
}
.flip-tile-back {
background: MediumPurple;
visibility: hidden;
/*Default rotation value*/
transform: rotateY(-180deg);
}
/*When the container is clicked the checkbox is marked as checked. This activates the CSS below. */
.tile input[type="checkbox"]:checked {
~ .flip-tile {
//animation: lift 0.4s linear;
.flip-tile-back {
visibility: visible;
transform: rotateX(0deg) rotateY(0deg);
}
.flip-tile-front {
transform: rotateY(180deg);
}
}
}
https://codepen.io/lostcook/pen/QWyvBey
Any ideas or help would greatly be appreciated.
Thanks

Ripple effect problem: not reaching edges

I am currently trying to create a CSS ripple effect. When I scale the button the ripple don't reach the edges of the button. The speed of the growth of the ripple is the same for every button size. It is a regular button. The CSS is added when the button is pressed.
This is my CSS code:
position: absolute;
background: #000;
border-radius: 50%;
width: 5px;
height: 5px;
animation: ripple 0.88s linear;
opacity: 0;
pointer-events: none;
#keyframes ripple {
from {
transform: scale(1);
opacity: 0.4
}
to {
transform: scale(100);
opacity: 0;
}
}
Thanks in advance!
Separate the ripple effect from the button element. Use a span element to execute the animation. Like so:
$(document).ready(function(){
$('button').on('click',function(){
$(this).find('.ripple').remove();
$(this).append($('<span class="ripple"></span>'));
});
});
button{
position: relative;
overflow: hidden;
width: 100px;
height: 25px;
}
button.big{
width: 200px;
height: 50px;
}
button.bigger{
width: 400px;
height: 100px;
}
.ripple{
position: absolute;
background: #000;
border-radius: 50%;
width: 5px;
height: 5px;
opacity: 0;
pointer-events: none;
animation: ripple 0.88s linear;
transform: scale(1);
top: 50%;
left: 50%;
}
#keyframes ripple {
from {
transform: scale(1);
opacity: 0.4
}
to {
transform: scale(100);
opacity: 0;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="">Ripple!</button>
<button class="big">Ripple!</button>
<button class="bigger">Ripple!</button>
Keep in mind that, since you're scaling to a 100x size, the biggest buttons your effect will support is a little under 500px wide (because of the ripple's borders)

CSS circle Spin/Grow transition, text starting outside

I have a circle that I want to grow both width and height and spin to face upright. The problem is you can see the embedded checkmark starts outside of the circle and spirals inwards as opposed to growing with the circle.
$(function() {
$("span").addClass("active");
})
span {
position: absolute;
display:block;
color: red;
font-size: 0px;
font-weight: bold;
width: 0px;
height: 0px;
top: 50%;
left: 50%;
transform: translateY(-50%) translateX(-50%);
line-height:80px;
text-align: center;
background: rgba(32,167,110,0.9);
border: 2px solid rgb(32,167,110);
border-radius: 50%;
-webkit-transform: rotateZ(-360deg);
-ms-transform: rotateZ(-360deg);
transform: rotateZ(-360sdeg);
transition: all 5s;
margin-left: -20px;
margin-top:-34px;
}
span.active {
-webkit-transform: rotateZ(0deg);
-ms-transform: rotateZ(0deg);
transform: rotateZ(0sdeg);
width: 80px;
height: 80px;
font-size: 45px;
margin-left: -40px;
margin-top:-68px;
}
<span>✓</span>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I would like to keep the checkmark centered inside the circle as it grows.
I'm not sure if I got your question correctly, but if you want to hide the checkmark outside of the green circle you can add the css property overflow: hidden;.
EDIT: According to the author's comment, I added a new solution.
If you want to position the checkmark sign inside the circle and nevertheless transform it together with the circle, it is best to add another element (or pseudoelement) for the checkmark sign and only assign the transformation to the circle. Here is an example of the transformation with a pseudoelement.
$(function() {
$("span").addClass("active");
});
/* <div> is only for layouting (centering into the middle) */
div {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
span {
display: block;
position: relative; /* needs to be set, that the checkmark is positioned relative to the <span> */
color: red;
font-size: 0;
font-weight: bold;
width: 0;
height: 0;
text-align: center;
background: rgba(32,167,110,0.9);
border: 2px solid rgb(32,167,110);
border-radius: 50%;
-webkit-transform: rotate(-360deg);
-ms-transform: rotate(-360deg);
transform: rotate(-360deg);
transition: all 5s;
}
span:after {
content: "✓";
position: absolute;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
}
span.active {
-webkit-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
width: 80px;
height: 80px;
font-size: 45px;
}
<div>
<span></span>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

CSS transition between left -> right and top -> bottom positions

Is it possible to use CSS transitions to animate something between a position set as left: 0px to right: 0px so it goes all the way across the screen? I need to accomplish the same thing with top to bottom. Am I stuck calculating the screen width / object-size?
#nav {
position: absolute;
top: 0px;
left: 0px;
width: 50px;
height: 50px;
-webkit-transition: all 0.5s ease-out;
}
.moveto {
top: 0px;
right: 0px;
}
and then I use jQuery's .addClass
You can animate the position (top, bottom, left, right) and then subtract the element's width or height through a CSS transformation.
Consider:
$('.animate').on('click', function(){
$(this).toggleClass("move");
})
.animate {
height: 100px;
width: 100px;
background-color: #c00;
transition: all 1s ease;
position: absolute;
cursor: pointer;
font: 13px/100px sans-serif;
color: white;
text-align: center;
}
/* ↓ just to position things */
.animate.left { left: 0; top: 50%; margin-top: -100px;}
.animate.right { right: 0; top: 50%; }
.animate.top { top: 0; left: 50%; }
.animate.bottom { bottom: 0; left: 50%; margin-left: -100px;}
.animate.left.move {
left: 100%;
transform: translate(-100%, 0);
}
.animate.right.move {
right: 100%;
transform: translate(100%, 0);
}
.animate.top.move {
top: 100%;
transform: translate(0, -100%);
}
.animate.bottom.move {
bottom: 100%;
transform: translate(0, 100%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Click to animate
<div class="animate left">left</div>
<div class="animate top">top</div>
<div class="animate bottom">bottom</div>
<div class="animate right">right</div>
And then animate depending on the position...
For elements with dynamic width it's possible to use transform: translateX(-100%); to counter the horizontal percentage value. This leads to two possible solutions:
1. Option: moving the element in the entire viewport:
Transition from:
transform: translateX(0);
to
transform: translateX(calc(100vw - 100%));
#viewportPendulum {
position: fixed;
left: 0;
top: 0;
animation: 2s ease-in-out infinite alternate swingViewport;
/* just for styling purposes */
background: #c70039;
padding: 1rem;
color: #fff;
font-family: sans-serif;
}
#keyframes swingViewport {
from {
transform: translateX(0);
}
to {
transform: translateX(calc(100vw - 100%));
}
}
<div id="viewportPendulum">Viewport</div>
2. Option: moving the element in the parent container:
Transition from:
transform: translateX(0);
left: 0;
to
left: 100%;
transform: translateX(-100%);
#parentPendulum {
position: relative;
display: inline-block;
animation: 2s ease-in-out infinite alternate swingParent;
/* just for styling purposes */
background: #c70039;
padding: 1rem;
color: #fff;
font-family: sans-serif;
}
#keyframes swingParent {
from {
transform: translateX(0);
left: 0;
}
to {
left: 100%;
transform: translateX(-100%);
}
}
.wrapper {
padding: 2rem 0;
margin: 2rem 15%;
background: #eee;
}
<div class="wrapper">
<div id="parentPendulum">Parent</div>
</div>
Demo on Codepen
Note: This approach can easily be extended to work for vertical positioning. Visit example here.
This worked for me on Chromium. The % for translate is in reference to the size of the bounding box of the element it is applied to so it perfectly gets the element to the lower right edge while not having to switch which property is used to specify it's location.
topleft {
top: 0%;
left: 0%;
}
bottomright {
top: 100%;
left: 100%;
-webkit-transform: translate(-100%,-100%);
}
In more modern browsers (including IE 10+) you can now use calc():
.moveto {
top: 0px;
left: calc(100% - 50px);
}

Resources