I am working on a pure css based menu. I tried to create a slide up animation of the menu but couldn't get it to work. I looked at a lot of solutions online but none of them worked for my case.
Here's the laydown of my case.
The menu has a title and subitems (submenu). This menu will only be one level.
I need the height of the submenu to zap behind the menu title.
Since the number of sub items are dynamic I want to achieve this without using specific height.
transform: translateY seemed like a better option but the menu items are visible above the title.
I do not want the menu items to appear above the menu title and use translate or something similar.
I'm not sure if I'm on the right track or if I'm missing something elementary.
$(function() {
$('.accordion-tabs__header').click(function() {
$('.accordion-tabs__body').toggleClass('collapsed');
$('.accordion-tabs__body').toggleClass('expanded');
});
});
.accordion-tabs {
position: relative;
top: 2rem;
width: 60%;
}
.accordion-tabs__header {
transition-delay: 1s;
display: flex;
align-items: center;
padding: 1rem 0.5rem;
z-index: 10;
position: relative;
background-color: azure;
}
.accordion-tabs__header__title {
margin: 0;
padding: 0;
}
.accordion-tabs__body {
position: absolute;
width: 100%;
transition: 200ms transform ease-in-out;
}
.accordion-tabs__body.expanded {
z-index: 1;
transform: translateY(0%);
}
.accordion-tabs__body.collapsed {
z-index: 1;
transform: translateY(-100%);
}
.accordion-tabs__body .accordion-tabs__body__link {
display: flex;
align-items: center;
padding: 0.875rem;
background-color: antiquewhite;
}
.accordion-tabs__body .accordion-tabs__body__link a{
text-decoration: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='wrapper'>
<div class="accordion-tabs">
<div class="accordion-tabs__header">
<div class="accordion-tabs__header__title">Menu Title Looong</div>
</div>
<div class="accordion-tabs__body collapsed">
<div class="accordion-tabs__body__link"><a class="link" href="#">Item One</a></div>
<div class="accordion-tabs__body__link"><a class="link" href="#">Item One</a></div>
<div class="accordion-tabs__body__link"><a class="link" href="#">Item Three</a></div>
</div>
</div>
</div>
Here's the codepen to my code - https://codepen.io/flexdinesh/pen/VybwwE
I managed to achieve this with max-height.
Slide-up animation was a bit slow to trigger when I used this code in react. However I made it look okay with ease-out transition.
$(function() {
$('.accordion-tabs__header').click(function() {
$('.accordion-tabs__body').toggleClass('collapsed');
$('.accordion-tabs__body').toggleClass('expanded');
});
});
.accordion-tabs {
position: relative;
top: 2rem;
width: 60%;
}
.accordion-tabs__header {
transition-delay: 1s;
display: flex;
align-items: center;
padding: 1rem 0.5rem;
position: relative;
background-color: azure;
}
.accordion-tabs__header__title {
margin: 0;
padding: 0;
}
.accordion-tabs__header.expanded {
border-bottom: none;
}
.accordion-tabs__body {
overflow: hidden;
position: absolute;
width: 100%;
border-bottom-width: 2px;
border-bottom-style: solid;
}
.accordion-tabs__body.expanded {
max-height: 100vh;
transition: max-height 500ms ease-in;
}
.accordion-tabs__body.collapsed {
max-height: 0;
transition: max-height 200ms ease-out;
}
.accordion-tabs__body__link {
display: flex;
align-items: center;
padding: 0.875rem;
border-top-width: 1px;
border-top-style: solid;
background-color: antiquewhite;
}
.accordion-tabs__body__link a {
text-decoration: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='wrapper'>
<div class="accordion-tabs">
<div class="accordion-tabs__header">
<div class="accordion-tabs__header__title">Menu Title Looong</div>
</div>
<div class="accordion-tabs__body collapsed">
<div class="accordion-tabs__body__link"><a class="link" href="#">Item One</a></div>
<div class="accordion-tabs__body__link"><a class="link" href="#">Item One</a></div>
<div class="accordion-tabs__body__link"><a class="link" href="#">Item Three</a></div>
</div>
</div>
</div>
Here's the updated codepen that works -
https://codepen.io/flexdinesh/pen/VyWzKo
Related
Hi I'm trying to get an animation working when I hover over links with Nextjs and Tailwind. Anything would help thanks
Example of the working code in standard CSS/HTML
<div class="link-cont">
<div class="link-wrapper">
<a class="link hover-1" href="#">#1 - left to right</a>
</div>
</div>
CSS
.link-cont {
position: relative;
font-size: 24px;
}
.link {
display: inline-block;
position: relative;
text-decoration: none;
padding: 10px 0;
color: #fff;
}
.link-wrapper {
position: relative;
display: block;
padding: 20px 0;
}
.hover-1 {
&:after {
content:'';
position: absolute;
width: 100%;
height: 3px;
bottom: 0;
left: 0;
background-color: #red;
transform: scaleX(0);
transform-origin: bottom right;
transition: transform 0.3s;
}
&:hover {
&:after {
transform-origin: bottom left;
transform: scaleX(1);
}
}
}
My code in tailwind
<div className="">
<Link href="/models">
<a className="
ml-auto
font-serif
text-6xl
inline-block
relative
no-underline
px-[10px]
after:absolute
after:w-[100%]
after:h-[5px]
after:bg-black
after:bottom-0
after:left-0
after:scale-x-0
after:origin-bottom-right
after:transition-transform
hover:after:origin-bottom-left
hover:after:scale-x-1
">
models
</a>
</Link>
<Link href="/contact">
<a className="mx-10 font-serif text-6xl">contact</a>
</Link>
</div>
Not sure if this is bugging out from the after and hover states but you should be able to stack pseudo selectors and stuff as per the tailwind docs. Don't really know what's wrong with the code as the after portion of the css does not show up in the inspector.
I cannot understand how, in my case, possible to properly positioned the menu by creating only one class menu, instead of menu_left and menu_right classes.
How can I optimize css here?
Here's code example:
html:
<div class="menu_left" >
<div class="menu__item">
<span class="menu__item__link__text">SHOP</span>
</div>
<div class="menu__item">
<span class="menu__item__link__text">ABOUT</span>
</div>
</div>
<a href="" class="logo">
<img src="assets/sds.jpgf" class="logo__image">
</a>
<div class ="menu_right">
<div class="menu__item">
<span class="menu__item__link__text">CART</span>
</div>
<div class="menu__item">
<span class="menu__item__link__text">EUR</span>
</div>
</div>
Menu Image
css
.menu_left {
background: rgba(0, 0, 0, 0.85);
position: relative;
top: auto;
right: auto;
bottom: auto;
left: auto;
background: transparent;
float: left;
width: auto;
opacity: 1;
visibility: visible;
-webkit-transition: none;
-moz-transition: none;
transition: none; }
.menu_right{
position: relative;
top: auto;
right: auto;
bottom: auto;
left: auto;
background: transparent;
float: right;
width: auto;
opacity: 1;
visibility: visible;
-webkit-transition: none;
-moz-transition: none;
transition: none; }
}
Try it with Flexbox
See flexbox menu here
HTML
<div class="menu">
<ul>
<li>
Lorem
</li>
<li>
Lorem
</li>
</ul>
<div class="img"> <!-- replace div with the <img src="" alt="" /> tag -->
img here
</div>
<ul>
<li>
Lorem
</li>
<li>
Lorem
</li>
</ul>
</div>
CSS
.menu {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding: 5px 10px;
background: #ddd;
}
ul {
display: flex;
padding: 0;
list-style: none;
}
a {
padding: 5px 10px;
color: #000;
text-decoration: none;
text-transform: uppercase;
}
.img {
width: 200px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
background-color: #000;
color: #fff;
}
To optimize CSS when using very similar settings, use three classes instead of two: One common class for both elements which contains all the common settings, and two separate classes for the two elements which contain the different settings:
CSS:
.menu_all {
position: relative;
top: auto;
right: auto;
bottom: auto;
left: auto;
background: transparent;
width: auto;
opacity: 1;
visibility: visible;
-webkit-transition: none;
-moz-transition: none;
transition: none;
top: auto;
right: auto;
bottom: auto;
left: auto;
background: transparent;
}
.menu_left {
background: rgba(0, 0, 0, 0.85);
float: left;
}
.menu_right{
float: right;
}
and HTML:
<div class="menu_all menu_left" >
<div class="menu__item">
<span class="menu__item__link__text">SHOP</span>
</div>
<div class="menu__item">
<span class="menu__item__link__text">ABOUT</span>
</div>
</div>
<a href="" class="logo">
<img src="assets/sds.jpgf" class="logo__image">
</a>
<div class ="menu_all menu_right">
<div class="menu__item">
<span class="menu__item__link__text">CART</span>
</div>
<div class="menu__item">
<span class="menu__item__link__text">EUR</span>
</div>
</div>
This question already has an answer here:
Why is a flex item limited to parent size?
(1 answer)
Closed 2 years ago.
I have a flex container that has items set in a row and when it reaches the end of the viewport width I want it to overflow-x: scroll. Instead it shrinks all items with more items added to fit the screen.
How can I allow it to overflow and still scroll in the x direction while keeping the items from shrinking?
.footer-container {
width: 100%;
height: 12rem;
background-color: #fff;
position: fixed;
bottom: 0;
display: flex;
overflow-x: scroll;
padding: 1rem;
animation: slide-up;
animation-duration: 1s;
visibility: hidden;
opacity: 0;
}
.footer-items {
background-color: rgb(214, 218, 219);
width: 17rem;
list-style-type: none;
border-radius: 4px;
margin-right: 1.5rem;
padding: 1rem;
font-size: 1.5rem;
position: relative;
animation: fade-in;
animation-duration: 2s;
display: flex;
}
.side-col {
display: flex;
flex-direction: column;
}
.cart-image {
min-width: 10rem;
height: 6rem;
}
.cart-price {
position: absolute;
top: 50%;
right: 1rem;
transform: translateY(-50%);
font-weight: 600;
}
<footer class="footer">
<ul class="footer-container">
<li class="footer-items">
<div class="side-col">
<p>Bike<p/>
<img class="cart-image" src="bike.png"/>
</div>
<span class="cart-price">$2345</span>
</li>
</ul>
</footer>
Here is how it looks without overflowing items https://i.stack.imgur.com/ZUrZS.png
and with overflowing items
https://i.stack.imgur.com/18obq.png
If I got you right, Just add flex-shrink: 0; to the item you don't want to shrink.
If something else needed, pls let me know.
You can have a look at flex-shrink here.
.footer-container {
width: 100%;
height: 12rem;
background-color: #fff;
position: fixed;
bottom: 0;
display: flex;
overflow-x: scroll;
padding: 1rem;
animation: slide-up;
animation-duration: 1s;
}
.footer-items {
background-color: rgb(214, 218, 219);
width: 17rem;
flex-shrink: 0; /*add this property only*/
list-style-type: none;
border-radius: 4px;
margin-right: 1.5rem;
padding: 1rem;
font-size: 1.5rem;
position: relative;
animation: fade-in;
animation-duration: 2s;
display: flex;
}
.side-col {
display: flex;
flex-direction: column;
}
.cart-image {
min-width: 10rem;
height: 6rem;
}
.cart-price {
position: absolute;
top: 50%;
right: 1rem;
transform: translateY(-50%);
font-weight: 600;
}
<footer class="footer">
<ul class="footer-container">
<li class="footer-items">
<div class="side-col">
<p>Bike<p/>
<img class="cart-image" src="bike.png"/>
</div>
<span class="cart-price">$2345</span>
</li>
<li class="footer-items">
<div class="side-col">
<p>Bike<p/>
<img class="cart-image" src="bike.png"/>
</div>
<span class="cart-price">$2345</span>
</li>
<li class="footer-items">
<div class="side-col">
<p>Bike<p/>
<img class="cart-image" src="bike.png"/>
</div>
<span class="cart-price">$2345</span>
</li>
<li class="footer-items">
<div class="side-col">
<p>Bike<p/>
<img class="cart-image" src="bike.png"/>
</div>
<span class="cart-price">$2345</span>
</li>
<li class="footer-items">
<div class="side-col">
<p>Bike<p/>
<img class="cart-image" src="bike.png"/>
</div>
<span class="cart-price">$2345</span>
</li>
</ul>
</footer>
I'm trying to make a card that flipping on hover. To hide the back part of a card I use backface-visibility: hidden. But it only hides background of the back part while all the elements are still visible on the front side in rotated variant.
I use Google Chrome.
Here's my html code
<div class="card">
<div class="card__side card__side--front">
<div class="card__picture card__picture--1"></div>
<div class="card__heading">
<span class="card__heading-span card__heading-span--1">
The sea explorer
</span>
</div>
<div class="card__details">
<ul class="card__list">
<li class="card__item">3 day tour</li>
<li class="card__item">Up to 30 people</li>
<li class="card__item">2 tour guides</li>
<li class="card__item">Sleep in cozy hotels</li>
<li class="card__item">Difficulty: easy</li>
</ul>
</div>
</div>
<div class="card__side card__side--back card__side--back-1">
<div class="card__cta">
<div class="card__price-box">
<p class="card__price--only">Only</p>
<p class="card__price--value">$297</p>
</div>
Book now
</div>
</div>
</div>
And here's my SASS code
.card {
position: relative;
height: 52rem;
perspective: 150rem;
&__side {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 52rem;
border-radius: 3px;
overflow: hidden;
box-shadow: 0 1.5rem 4rem rgba($color-black, .15);
transform-style: preserve-3d;
backface-visibility: hidden;
transition: all .8s ease;
&--front {
background-color: $color-white;
}
&--back {
transform: rotateY(180deg);
&-1 {
background-image:
linear-gradient(to right bottom,$color-secondary-light,$color-secondary-dark);
}
&-2 {}
&-3 {}
}
}
&:hover &__side--front {
transform: rotateY(-180deg);
}
&:hover &__side--back {
transform: rotateY(0);
}
// Front side styles
&__picture {
&--1 {}
&--2 {}
&--3 {}
}
&__heading {
}
&__heading-span {
&--1 {}
&--2 {}
&--3 {}
}
&__details {
}
&__list {
width: 80%;
margin: 0 auto;
list-style-type: none;
}
&__item {
&:not(:last-child) {
border-bottom: 1px solid $color-gray-light-2;
}
}
//Back side styles
&__cta {
#include absoluteCenter();
width: 90%;
text-align: center;
}
&__price-box {
margin-bottom: 6rem;
color: $color-black;
text-align: center;
}
&__price--only {
font-size: 1.4rem;
text-transform: uppercase;
}
&__price--value {
font-size: 6rem;
font-weight: 300;
}
}
And this is how the problem actually looks like in Chrome.
Adding transform-style: preserve-3d to .card instead of .card__side fixed the bug for me.
Currently I am trying to create some links that look like buttons. It's working fairly well, except I want to be able to align them horizontally. This what I have so far:
.border {
display: table;
width: 220px;
height: 120px;
border: 2px solid #1E5034;
transition: all 250ms ease-out;
box-sizing: border-box;
border-spacing: 10px;
float:left;
}
.border:hover {
border-spacing: 2px;
}
a.btn {
display: table-cell;
vertical-align: middle;
text-align: center;
color: #ffffff;
font: 17.5px sans-serif;
text-decoration: none;
background-color: #1E5034;
line-height: 20px;
margin-bottom: 0;
}
a.btn:hover,
a.btn:focus,
a.btn:active,
a.btn:visited,
a.btn:link {
color: #ffffff;
background-color: #1E5034;
text-decoration: none;
cursor: pointer;
}
<div class="btn-grp">
<div class="border">
<a class="btn" href="#">Some really long text link #1</a>
</div>
<div class="border">
<a class="btn" href="#">Some other really long text link #2</a>
</div>
<div class="border">
<a class="btn" href="#">Some more really really long text link #3</a>
</div>
<div class="border">
<a class="btn" href="#">The last really long text link #4</a>
</div>
</div>
Edit:
If it has display:inline-block; it will mess up with formatting with heights and not center the text.
I'm trying to create something as shown here, but then be able to center this on the page as well.
Thanks!
Support in all browsers including IE.
.btn-grp {
position: absolute;
top: 0%;
left: 50%;
transform: translate(-50%, 0%);
width: 80vw;
}
.border {
display: table;
width: 25%;
height: 120px;
border: 2px solid #1E5034;
transition: all 250ms ease-out;
box-sizing: border-box;
border-spacing: 10px;
float: left;
}
.border:hover {
border-spacing: 2px;
}
a.btn {
display: table-cell;
vertical-align: middle;
text-align: center;
color: #ffffff;
font: 17.5px sans-serif;
text-decoration: none;
background-color: #1E5034;
line-height: 20px;
margin-bottom: 0;
}
a.btn:hover,
a.btn:focus,
a.btn:active,
a.btn:visited,
a.btn:link {
color: #ffffff;
background-color: #1E5034;
text-decoration: none;
cursor: pointer;
}
<div class="btn-grp">
<div class="border">
<a class="btn" href="#">Some really long text link #1</a>
</div>
<div class="border">
<a class="btn" href="#">Some other really long text link #2</a>
</div>
<div class="border">
<a class="btn" href="#">Some more really really long text link #3</a>
</div>
<div class="border">
<a class="btn" href="#">The last really long text link #4</a>
</div>
</div>
If you need the 4 div at vertically centered then use:
.btn-grp {
position: absolute;
top: 50%;
left:50%;
transform: translate(-50%, -50%);
}
Because you are using width in px thats why then don't come in a single row...So try to use % width i.e. 25%...
.border {
display: table;
width: 25%;
height: 120px;
border: 2px solid #1E5034;
transition: all 250ms ease-out;
box-sizing: border-box;
border-spacing: 10px;
float: left;
}
.border:hover {
border-spacing: 2px;
}
a.btn {
display: table-cell;
vertical-align: middle;
text-align: center;
color: #ffffff;
font: 17.5px sans-serif;
text-decoration: none;
background-color: #1E5034;
line-height: 20px;
margin-bottom: 0;
}
a.btn:hover,
a.btn:focus,
a.btn:active,
a.btn:visited,
a.btn:link {
color: #ffffff;
background-color: #1E5034;
text-decoration: none;
cursor: pointer;
}
<div class="btn-grp">
<div class="border">
<a class="btn" href="#">Some really long text link #1</a>
</div>
<div class="border">
<a class="btn" href="#">Some other really long text link #2</a>
</div>
<div class="border">
<a class="btn" href="#">Some more really really long text link #3</a>
</div>
<div class="border">
<a class="btn" href="#">The last really long text link #4</a>
</div>
</div>
Well I recommend you to use Flexbox here...It will give you the full control to align the item vertically and horizontally...Also you will need to use :after for the background, as flexbox does not allow border-spacing
.btn-grp {
display: flex;
justify-content: center;
}
.border {
width: 20%;
height: 120px;
border: 2px solid #1E5034;
transition: all 250ms ease-out;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
position: relative;
padding: 10px;
}
a.btn {
text-align: center;
color: #ffffff;
font: 16px sans-serif;
text-decoration: none;
line-height: 20px;
margin-bottom: 0;
flex: 1;
}
a.btn:hover,
a.btn:focus,
a.btn:active,
a.btn:visited {
color: #ffffff;
background-color: #1E5034;
text-decoration: none;
cursor: pointer;
}
.border:before {
content: "";
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #1f5034;
position: absolute;
z-index: -1;
transition: all .3s ease;
transform: scale(0.85);
}
.border:hover:before {
transform: scale(0.95);
}
<div class="btn-grp">
<div class="border">
<a class="btn" href="#">Some really long text link #1</a>
</div>
<div class="border">
<a class="btn" href="#">Some other really long text link #2</a>
</div>
<div class="border">
<a class="btn" href="#">Some more really really long text link #3</a>
</div>
<div class="border">
<a class="btn" href="#">The last really long text link #4</a>
</div>
</div>
Well for IE 8 support use display:inline-block and transform to place the content in center...
.btn-grp {
text-align: center;
font-size: 0;
}
.border {
width: 20%;
height: 120px;
border: 2px solid #1E5034;
transition: all 250ms ease-out;
box-sizing: border-box;
display: inline-block;
vertical-align: top;
position: relative;
padding: 10px;
}
a.btn {
text-align: center;
color: #ffffff;
font: 16px sans-serif;
text-decoration: none;
line-height: 20px;
margin-bottom: 0;
position: relative;
top: 50%;
transform: translateY(-50%);
display: block;
}
.border:before {
content: "";
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #1f5034;
position: absolute;
z-index: -1;
transition: all .3s ease;
transform: scale(0.85);
}
.border:hover:before {
transform: scale(0.95);
}
<div class="btn-grp">
<div class="border">
<a class="btn" href="#">Some really long text link #1</a>
</div>
<div class="border">
<a class="btn" href="#">Some other really long text link #2</a>
</div>
<div class="border">
<a class="btn" href="#">Some more really really long text link #3</a>
</div>
<div class="border">
<a class="btn" href="#">The last really long text link #4</a>
</div>
</div>