How to make elements stay in place when using transitions on hover - css

How do I make li elements not move around when applying transitions using :hover? The circles are made applying height and border-radius to the li elements. I've tried making the ul container bigger, but that didn't seem to work. Thanks for your help.
Code:
body {}
main {
display: flex;
background: #eeeeee;
min-height: 100vh;
padding: 1em;
}
h1 {
font-family: arial;
font-size: 1.4em;
padding-left: 1em;
}
ul {
padding-top:50px;
min-height: 600px;
position:relative;
}
li {
position:relative;
background-color: purple;
border-radius: 50%;
width: 50px;
height: 50px;
padding: 1em;
text-align: center;
list-style: none;
display: inline-block;
line-height: 50px;
border: 5px solid red;
margin-right: -1em;
z-index: 0;
transition: width 0.5s, height 0.5s, background-color 1s, line-height 0.5s;
}
li:hover {
display: inline-block;
position:relative;
width: 90px;
height: 90px;
z-index: 10;
background-color: green;
line-height: 90px;
}
<body>
<main>
<h1>
My animated Menu
</h1>
<div class="menu">
<ul>
<li>X</li>
<li>Y</li>
<li>Z</li>
</ul>
</div>
</main>
</body>

Use CSS3 transforms, this way the element can freely move or scale into the DOM without affecting the layout size.
A nice bonus: the animation will be more efficient in terms of fps as the layout won't be re-computed on each frame (an the GPU will be used)
ul {
padding-top: 50px;
}
li {
background-color: purple;
border-radius: 50%;
width: 50px;
height: 50px;
padding: 1em;
text-align: center;
list-style: none;
display: inline-block;
line-height: 50px;
border: 5px solid red;
margin-right: -1em;
z-index: 0;
transition: transform 0.5s, background-color 1s;
}
li:hover {
display: inline-block;
position: relative;
transform: scale(1.5);
z-index: 10;
background-color: green;
}
<div class="menu">
<ul>
<li>X</li>
<li>Y</li>
<li>Z</li>
</ul>
</div>

Related

Position fixed is not working with Backdrop-filter

I am tring to make a glass effect in navbar of my website. Here is the code:
HTML:
<nav class="navbar">
<div class="logo">
Logo
</div>
<div class="mobile_nav">
<i class="fa-solid fa-bars"></i>
</div>
<menu class="menu">
Home
Pricing
About
Get in Touch
</menu>
</nav>
CSS:
#import url('https://fonts.googleapis.com/css2?family=Roboto:wght#300;400;500;700;900&display=swap');
:root{
--black: #0f0f19;
--gray: #7a7b7f;
--light-gray: #ddd;
--primary: #0da87c;
--white: #fff;
}
*{
margin: 0;
padding: 0;
font-family: 'Roboto', sans-serif;
box-sizing: border-box;
}
a{
text-decoration: none;
color:var(--black);
}
.navbar{
width:100vw;
width: calc(100vw - 100px);
margin-left: 50px;
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
background: #e2e2e2a6;
display:flex;
justify-content:space-evenly;
height:70px;
line-height: 70px;
position:fixed;
top: 0;
left: 0;
z-index: 99;
backdrop-filter: blur(5px);
}
.navbar a{
padding: 5px 10px;
color: var(--gray);
font-size: 14px;
font-weight: bold;
transition: all .25s ease-in-out;
}
.navbar menu a:hover{
color: var(--black);
}
.mobile_nav{
display: none;
}
.navbar + *{
margin-top:70px;
}
#media screen and (max-width: 768px) {
.mobile_nav{
display: block;
position: fixed;
right: 24px;
}
.navbar menu{
width: calc(100% - 20px);
margin: 0 10px;
position: fixed;
left: 0;
bottom: -50%;
display: flex;
flex-direction: column;
background-color: #333;
line-height: 30px;
border-radius: 30px 30px 0 0;
padding: 10px;
transition: bottom .25s ease-in-out;
}
.mobile_nav{
font-size: 24px;
}
.active{
bottom: 0 !important;
}
}
If you try to view the above code on a mobile screen, you will notice that when you click on the hamburger icon the menu should come from the bottom of the screen but when I add backdrop-filter: unset; to the .navbar class, it is working fine but when I add this, it removes the glass effect.
I'm trying to add the glass effect on both desktop and mobile screens with position: fixed on the inner tag. Help me out please!

How to move border-bottom up on hover?

I want to transition border-bottom up on hover but cannot figure out how to make it work. Any suggestions?
.nav h1 {
display: inline-block;
border-bottom: 2px solid #fff;
padding-bottom: 8px;
margin: 20px;
}
.nav h1 a:hover::after {
padding-bottom: -8px;
transition: 0.5s ease-in;
}
One way to achieve that is to change the value of bottom: value.
/*DEMO*/
*,*::before,*::after{box-sizing: border-box}
div{margin-top:3rem}
/****************************/
h1,
span{
position:relative
}
h1:after,
span:after{
content:'';
position:absolute;
left:0;
bottom:-20px;
right:0;
border-bottom:2px red solid;
transition:.5s
}
h1:hover:after,
span:hover:after{
bottom:0;
transition:.5s
}
<h1>Example block element</h1>
<div>
<span>Inline element</span>
<div>
Other method that may work is to set height of :after element and change it on hover.
here is the simplest version
transition of the border-bottom up 8px on hover (as asked by you)
body {background-color: #eee;}
.nav {
width: 100px;
height: 100px;
display: inline-block;
border-bottom: 2px solid #fff;
margin: 20px;
background: #ddd;
transition-duration: 0.5s;
}
.nav:hover {
width: 100px;
height: 92px;
}
<h1 class="nav"></h1>
Hi Try using the following code:
h1.nav {
border-bottom: 2px solid red;
display: inline-block;
line-height: 40px;
padding: 5px;
margin: 5px;
}
h1.nav:hover {
line-height: 20px;
transition: all 1s ease-in;
}
<h1 class="nav">Hey</h1>
<h1 class="nav">hello</h1>
<h1 class="nav">Hey</h1>
Hope this was what you intended to do.
If not please elaborate more.
You can consider a simple background to create the border and easily adjust the position using background-position
.box {
font-size:30px;
padding:8px 0;
display:inline-block;
background:linear-gradient(red,red) no-repeat;
background-size:100% 1px;
background-position:bottom 2px left 0;
transition:0.5s;
}
.box:hover {
background-position:bottom 20px left 0;
}
<div class="box"> some text </div>
You can also transition from bottom to top
.box {
font-size:30px;
padding:8px 0;
display:inline-block;
background:linear-gradient(red,red) no-repeat;
background-size:100% 1px;
background-position:bottom;
transition:0.5s;
}
.box:hover {
background-position:top;
}
<div class="box"> some text </div>
Here is Simple example of How to move border-bottom up on hover
li {
margin-bottom: 10px;
}
.cool-link {
display: inline-block;
color: #000;
text-decoration: none;
}
.cool-link::after {
content: '';
display: block;
width: 0;
height: 2px;
background: #000;
transition: width .3s;
}
.cool-link:hover::after {
width: 100%;
//transition: width .3s;
}
<ul>
<li><a class="cool-link" href="#">A cool link</a></li>
<li><a class="cool-link" href="#">A cool link</a></li>
<li><a class="cool-link" href="#">A cool link</a></li>
</ul>
If you want to move the border higher then use height instead of line height
h1.nav:hover {
height: 0px;
transition: all 1s ease-in;
}
h1.nav {
border-bottom: 2px solid red;
display: inline-block;
height: 40px;
padding: 5px;
margin: 5px;
}
<h1 class="nav">Hey</h1>
<h1 class="nav">hello</h1>
<h1 class="nav">Hey</h1>

Z-index not rendering properly in Safari - works in all other browsers

I have a nav menu that slides into view from the right side of the screen once the hamburger icon is clicked. It works correctly in Chrome and Firefox - basically when triggered it takes up 50vw and fills the screen vertically. However in Safari it seems as if the z-index is not behaving correctly because the menu appears to be buried underneath the other elements of the page and ultimately not visible at all.
I've tried adjusting the z-index of a variety of elements to see if that was the simple fix and it has proven to be something more complicated. I have read a few forums that suggested including "-webkit-transform: translate3d(0, 0, 0);" but unfortunately that doesnt seem to work either. If you inspect the sidebarMenu element in Safari you can see that it is in the correct position, it is just not rendering correctly.
Below is a link to a codepen - I am missing some styles on this so the positioning isnt quite right but it effectively shows the general functionality that I am looking for. When opening this link in Safari you can see that the sidebarMenu does not appear to be rendering at all.
https://codepen.io/rmann20/pen/EzbeaV
sample code:
<div class="header">
<hr class="nav-rule">
<div class="nav-container">
<div class="nav-logo-container">
<img class="nav-logo" src="images/nav_logo.png">
<input type="checkbox" class="openSidebarMenu" id="openSidebarMenu">
<label for="openSidebarMenu" class="sidebarIconToggle">
<div class="spinner diagonal part-1"></div>
<div class="spinner horizontal"></div>
<div class="spinner diagonal part-2"></div>
</label>
<div id="sidebarMenu">
<ul class="sidebarMenuInner">
<li>Rooms & Suites</li>
<li>Packages</li>
<li>Eat & Drink</li>
<li>Meetings & Events</li>
<li>Weddings</li>
<li>Experiences</li>
<li>Neighborhood</li>
</ul>
<ul class="sidebarMenuInnerSecondary">
<li>ABOUT</li>
<li>HISTORY</li>
<li>GALLERY</li>
<li>PRESS</li>
<li>CONTACT</li>
<li>CAREERS</li>
</ul>
</div>
</div>
<img class="nav-tagline" src="images/nav_tagline.png">
<a class="nav-reservation-button" href="" target="_blank">RESERVE NOW</a>
</div>
<hr class="nav-rule">
</div>
.header {
display: flex!important;
flex-wrap: wrap;
margin: 0;
padding: 10px 0 10px 0;
width: 100%;
max-width: 100%;
box-shadow: none;
background-color: #f5f4f0;
position: fixed;
height: 110px!important;
overflow: hidden;
z-index: 10;
justify-content: space-between!important;
}
.nav-container {
display: flex;
height: 79px;
width: 100%;
align-items: center;
justify-content: space-between;
}
.main {
margin: 0 auto;
display: block;
height: 100%;
margin-top: 60px;
}
.mainInner{
display: table;
height: 100%;
width: 100%;
text-align: center;
}
.mainInner div{
display:table-cell;
vertical-align: middle;
font-size: 3em;
font-weight: bold;
letter-spacing: 1.25px;
}
#sidebarMenu {
min-height: 100%;
position: fixed;
right: 0;
width: 50vw;
margin-top: 42px;
transform: translateX(50vw);
transition: transform 250ms ease-in-out;
background-color: #f5f4f0;
overflow: scroll;
padding: 60px 60px 60px 60px;
z-index: 10000!important;
}
.sidebarMenuInner{
margin:8px;
padding:0;
border-top: 1px solid rgba(255, 255, 255, 0.10);
list-style: none;
}
.sidebarMenuInner li a{
color: #3d3936;
font-family: 'QuincyCF-ExtraBold', Helvetica, Arial, Sans-Serif;
font-weight: normal;
font-style: normal;
cursor: pointer;
text-decoration: none;
font-size: 3.2em;
}
.sidebarMenuInnerSecondary {
margin-top: 60px;
list-style: none;
}
.sidebarMenuInnerSecondary li {
margin-top: 14px;
margin-bottom: 14px;
}
input[type="checkbox"]:checked ~ #sidebarMenu {
transform: translateX(0);
}
input[type=checkbox] {
transition: all 0.3s;
box-sizing: border-box;
display: none;
}
.sidebarIconToggle {
transition: all 0.3s;
box-sizing: border-box;
cursor: pointer;
position: absolute;
z-index: 99;
height: 100%;
width: 100%;
top: 48px;
right: 40px;
height: 28px;
width: 28px;
}
.spinner {
transition: all 0.3s;
box-sizing: border-box;
position: absolute;
height: 3px;
width: 100%;
background-color: #3d3936;
}
.horizontal {
transition: all 0.3s;
box-sizing: border-box;
position: relative;
float: left;
margin-top: 3px;
}
.diagonal.part-1 {
position: relative;
transition: all 0.3s;
box-sizing: border-box;
float: left;
}
.diagonal.part-2 {
transition: all 0.3s;
box-sizing: border-box;
position: relative;
float: left;
margin-top: 3px;
}
input[type=checkbox]:checked ~ .sidebarIconToggle > .horizontal {
transition: all 0.3s;
box-sizing: border-box;
opacity: 0;
}
input[type=checkbox]:checked ~ .sidebarIconToggle > .diagonal.part-1 {
transition: all 0.3s;
box-sizing: border-box;
transform: rotate(135deg);
margin-top: 8px;
}
input[type=checkbox]:checked ~ .sidebarIconToggle > .diagonal.part-2 {
transition: all 0.3s;
box-sizing: border-box;
transform: rotate(-135deg);
margin-top: -9px;
}
.nav-logo-container {
width: 260px;
margin-left: 40px;
}
I dont get any errors and everything else seems to be working correctly, can't figure out why it's not showing at this point. Any help would be greatly appreciated!

How to create a drop-down menu in div?

How to show the scrollable menu when passing the pointer over the div of the text 1x the scrollable menu is displayed.
What I want to do is something similar to the following image:
My code structure:
.spdText {
width: 3em;
height: 1.8em;
line-height: 1.8em;
position: relative;
font-size: 1em;
font-weight: 900;
text-shadow: none;
border-radius: 10%;
color: #29303b;
background-color: hsla(0,0%,100%,.9);
}
.speed {
display: none;
position: absolute;
max-height: 0;
transition: max-height 1s;
}
.speed:hover,
.btnSpd:hover .speed {
display: inline-table;
list-style: none;
max-height: 300px;
transition: max-height 1s;
top: -170px;
}
<div class="spdText">1x
<ul class="speed">
<li>x3</li>
<li>x1</li>
</ul>
</div>
Something like this?
Edit:
First you leave a space above 'spdText'. You position 'speed' over 'spdText' giving it a negative top value.
.spdText {
width: 3em;
height: 1.8em;
line-height: 1.8em;
position: relative;
font-size: 1em;
font-weight: 900;
text-shadow: none;
border-radius: 10%;
color: #29303b;
background-color: hsla(0,0%,100%,.9);
margin-top:5rem; /* You leave a space above */
}
.speed {
display: none;
position: absolute;
max-height: 0;
transition: max-height 1s;
}
.spdText:hover .speed {
display: block;
list-style: none;
max-height: 300px;
transition: max-height 1s;
left:-25px;
background-color: black;
opacity: 0.5;
color: white;
top: -4.4rem;
}
<div class="spdText">1x
<ul class="speed">
<li>x3</li>
<li>x1</li>
</ul>
</div>

Border-top Extending too far

I've got an interesting one: I was testing methods to get the list-item elements of a nav bar to spread evenly across the length of a nav. I used the display:table and display: table cell method to get the most even spread and that seemed to work fine.
When I went to add an ::after element so I could add a top-bar and have a smoother on-hover effect, I found that the bar extended past where I wanted it to -- I was trying to have it just to the end of the words "Communication Design". So I thought I'd just resize the nav container holding my list-elements but because it's a table/table-cell, when the nav resizes, the list-items shink along with it and I can never shore up the last element in the list.
Is there a way to either affect the size of the last table cell or only show a percentage of the ::after element?
Code:
HTML:
<h3>Test & Co.</h3>
<p id="title2">Communications Design</p>
<div id="navContainer">
<ul>
<li>Home</li>
<li>About</li>
<li>Work</li>
<li>Contact</li>
</ul>
</div>
CSS:
*
{
padding: 0;
margin: 0;
}
h3
{
padding-left: 140px;
display: inline-block;
padding-top: 10px;
padding-bottom: 25px;
}
#title2
{
display: inline-block;
float: right;
font-size: 16px;
margin-right: 252.5px;
padding-top: 14px;
padding-bottom: 25px;
}
#navContainer
{
//border: 1px solid black;
width: 643px;
margin-left: 140px;
height: 30px;
background: white;
}
#navContainer ul
{
list-style:none;
display: table;
width: 100%;
}
#navContainer ul li
{
display: table-cell;
height: 30px;
line-height: 30px;
font-family:arial;
font-size: 12px;
text-align: left;
//border: 1px solid black;
transition: color .2s ease-in-out;
position: relative;
}
#navContainer ul li::after
{
content: "";
display: block;
float: right;
position: absolute;
margin: auto;
height: 1px;
top: 0;
width: 100%;
background: #ccc;
transition: background-color .2s ease;
}
#navContainer ul li:hover::after
{
background: #8c8c8c;
}
#navContainer ul li:hover
{
color: #A6CFEB;
}

Resources