hamburger menu on close animation - css

I'm creating a hamburger menu but I have some problems with an animation.
I created 2 divs, 1 for the 3 basic horizontal lines, and one for the " X ". I know how to hide and show them with jQuery ( like, one you click on the 3 lines, the 3 lines hides, and the " X " shows ) but I want to create an animation on that " X " like it's drawn both " \ " and " / " simultaneously. Like it stars from the top corner and it ends and the bottom. I don't really know how to explain this and my english is bad. here's what I did so far
<div class="x">
<div></div>
<div></div>
</div>
and the CSS
.x {
position: fixed;
top:47%;
left: 5%; }
.x div {
width: 40px;
height: 2px;
background-color: #000000; }
.x div:nth-child(1) {
transform: rotate(45deg); }
.x div:nth-child(2) {
transform: rotate(-45deg); }
I tried to create an animation on each line which starts from witdh:0 ( 0% ) and witdh:40px ( 100% ) but because I used the transform property it doesn't animate the way I want, it changes the positions and stuff.
Ty and I'm really sorry, but I don't know how to explain this.

I think you're looking for something like this:
document.addEventListener('DOMContentLoaded', function(){
var menus = document.querySelectorAll('.menu');
var onClick = function(){
this.classList.toggle('open');
}
menus.forEach(function(menu, index){
menu.addEventListener('click', onClick);
});
});
body {
margin: 20px;
}
.menu {
cursor: pointer;
height: 24px;
list-style: none;
margin: 0;
padding: 0;
width: 30px;
position: relative;
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
-webkit-transition: .3s ease-in-out;
-moz-transition: .3s ease-in-out;
-o-transition: .3s ease-in-out;
transition: .3s ease-in-out;
}
.menu li {
background-color: #111;
border-radius: 4px;
display: block;
height: 4px;
left: 0;
margin: 0;
opacity: 1;
padding: 0;
position: absolute;
width: 100%;
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
-webkit-transition: .15s ease-in-out;
-moz-transition: .15s ease-in-out;
-o-transition: .15s ease-in-out;
transition: .15s ease-in-out;
}
.menu li:nth-child(1) {
top: 0;
-webkit-transform-origin: left center;
-moz-transform-origin: left center;
-o-transform-origin: left center;
transform-origin: left center;
}
.menu li:nth-child(2) {
top: 9px;
-webkit-transform-origin: left center;
-moz-transform-origin: left center;
-o-transform-origin: left center;
transform-origin: left center;
}
.menu li:nth-child(3) {
top: 18px;
-webkit-transform-origin: left center;
-moz-transform-origin: left center;
-o-transform-origin: left center;
transform-origin: left center;
}
.menu.open li:nth-child(1) {
left: 4px;
top: -1px;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
.menu.open li:nth-child(2) {
opacity: 0;
width: 0;
}
.menu.open li:nth-child(3) {
left: 4px;
top: 20px;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
}
<ul class="menu">
<li></li>
<li></li>
<li></li>
</ul>
with jQuery
$(document).ready(function(){
$('.menu').click(function(){
$(this).toggleClass('open');
});
});

Bogdan. I made an example for you, if I correctly understood your question.
HTML:
<div id="hamburger" class="hamburger hamburger_active">
<div class="hamburger__line"></div>
<div class="hamburger__line"></div>
</div>
CSS:
.hamburger {
width: 40px;
height: 40px;
position: fixed;
top:50%;
left: 50%;
border: 1px solid red;
}
.hamburger.hamburger_active .hamburger__line {
width: 100%;
}
.hamburger__line {
width: 0;
height: 2px;
position: absolute;
transform-origin: 20px 0;
top: 50%;
left: 0;
background-color: #000000;
transition: width .3s ease;
}
.hamburger__line:nth-child(1) {
transform: rotate(45deg);
}
.hamburger__line:nth-child(2) {
transform: rotate(135deg);
}
jQuery:
var $menu = $("#hamburger");
$menu.click(function() {
$(this).toggleClass('hamburger_active');
});

Related

Transitions with css

I am working on giving style to my menu, I really am something new in this
What I try to do is that when my menu appears it will see a transition from left to right, when it is hidden from it will be hidden from the left
I am really learning how to work with style sheets, I search the web and I have not managed to make it work as I wish
#media (max-width: 828px) {
#menu-header.show {
-webkit-transform: translateX(0);
-ms-transform: translateX(0);
transform: translateX(0);
}
#menu-header {
display: block ;
position: fixed;
z-index: 1;
background-color: #FFF;
left: 0;
top: 100px;
height: -webkit-calc(100% - 50px);
height: -moz-calc(100% - 50px);
height: calc(100% - 50px);
width: 90%;
padding: 20px 20px;
max-width: 87.5%;
-webkit-transform: translateX(-100%);
-ms-transform: translateX(-100%);
transform: translateX(-100%);
-webkit-transition: all 350ms ease;
-moz-transition: all 350ms ease;
-ms-transition: all 350ms ease;
-o-transition: all 350ms ease;
transition: all 350ms ease;
}
Some example where you can help me to solve my problem, since my menu currently makes a transition from top to bottom, and what I am looking for is from left to right
var header = document.getElementById('menu-header');
var button = document.getElementById('button');
button.addEventListener('click', function(){
header.classList.toggle('show');
});
#media (max-width: 828px) {
#menu-header {
display: block;
position: fixed;
z-index: 1;
background-color: #FFF;
left: 0;
top: 0;
height: 100%;
width: 40%;
padding: 20px 20px;
transform: translateX(-100%);
transition: transform 350ms ease;
background: #c33;
}
#menu-header.show {
transform: translateX(0);
}
}
#button {
position: fixed;
right: 0;
top: 0;
}
<div id="menu-header">
MENU
</div>
<button id="button">
Click me
</button>

Using 2 ::before and 2 ::after pseudo element for 1 class

Hi can i know how can use 2 pseudo element for 1 class or 2 class. I tried both ways was still being overridden. Your help and advice much appreciated.
I tried 2 ways. First as below
<div class="custom_class">
<p>Custome Text</p>
</div>
.custom_class::before
{
}
.custom_class::after
{
}
.custom_class::before
{
}
.custom_class:::after
{
}
Second wat as below
<div class="custom_class1 custom_class2">
<p>Custome Text</p>
</div>
.custom_class1::before
{
}
.custom_class1::after
{
}
.custom_class2::before
{
}
.custom_class2:::after
{
}
But both not working. Can please advice on this
-------Edited------------------
This is my html code
<div class="classOne transx transy">
<div class="flex-row">
Custome Text
</div>
</div>
Added my code css code
.classOne {
position: absolute;
left: 50%;
width: 20%;
height: 55px;
border-radius: 0px;
box-shadow: 4px 8px 16px 0 rgba(0, 0, 0, 0.1);
outline: 3px solid gold;
overflow: hidden;
background: #ffbb00;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: antialiased;
-webkit-text-shadow: rgba(0,0,0,.01) 0 0 1px;
text-shadow: rgba(0,0,0,.01) 0 0 1px;
margin-left:30.6%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
a.classOneBtn
{
color: white;
font-family: 'Chivo Black', sans-serif;
font-size: 18px;
font-weight: 500;
}
.transy::before
{
height: 100%;
width: 5px;
background: white;
content: "";
position: absolute;
left: 0;
top: 0;
-moz-transform: scaleY(0);
-ms-transform: scaleY(0);
-webkit-transform: scaleY(0);
transform: scaleY(0);
-moz-transition: 0.3s;
-o-transition: 0.3s;
-webkit-transition: 0.3s;
transition: 0.3s;
}
.transy::after
{
height: 100%;
width: 5px;
background: white;
content: "";
position: absolute;
right: 0;
top: 0;
-moz-transform: scaleY(0);
-ms-transform: scaleY(0);
-webkit-transform: scaleY(0);
transform: scaleY(0);
-moz-transition: 0.3s;
-o-transition: 0.3s;
-webkit-transition: 0.3s;
}
.transx::before
{
height: 5px;
width: 100%;
background: white;
content: "";
position: absolute;
left: 0;
top: 0;
-moz-transform: scaleX(0);
-ms-transform: scaleX(0);
-webkit-transform: scaleX(0);
transform: scaleX(0);
-moz-transition: 0.3s;
-o-transition: 0.3s;
-webkit-transition: 0.3s;
transition: 0.3s;
}
.transx::after
{
height: 5px;
width: 100%;
background: white;
content: "";
position: absolute;
left: 0px;
bottom: 0;
-moz-transform: scaleX(0);
-ms-transform: scaleX(0);
-webkit-transform: scaleX(0);
transform: scaleX(0);
-moz-transition: 0.3s;
-o-transition: 0.3s;
-webkit-transition: 0.3s;
transition: 0.3s;
}
.transx:hover::before, .transx:hover::after
{
-moz-transform: scaleX(1);
-ms-transform: scaleX(1);
-webkit-transform: scaleX(1);
transform: scaleX(1);
}
.transy:hover::before, .transy:hover::after
{
-moz-transform: scaleY(1);
-ms-transform: scaleY(1);
-webkit-transform: scaleY(1);
transform: scaleY(1);
}
This was for the animation part whereby when hover will show a line of box This the code which i was performing.
If you would like see output. you need comment the transx
In the same element you can not.
It is not the same item but you can get something similar.
.transx{
position:absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.classOne {
text-align: center;
position: absolute;
left: 50%;
width: 20%;
height: 55px;
border-radius: 0px;
box-shadow: 4px 8px 16px 0 rgba(0, 0, 0, 0.1);
outline: 3px solid gold;
overflow: hidden;
background: #ffbb00;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: antialiased;
-webkit-text-shadow: rgba(0,0,0,.01) 0 0 1px;
text-shadow: rgba(0,0,0,.01) 0 0 1px;
margin-left:30.6%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
a.classOneBtn
{
color: white;
font-family: 'Chivo Black', sans-serif;
font-size: 18px;
font-weight: 500;
}
.transy::before
{
height: 100%;
width: 5px;
background: white;
content: "";
position: absolute;
left: 0;
top: 0;
-moz-transform: scaleY(0);
-ms-transform: scaleY(0);
-webkit-transform: scaleY(0);
transform: scaleY(0);
-moz-transition: 0.3s;
-o-transition: 0.3s;
-webkit-transition: 0.3s;
transition: 0.3s;
}
.transy::after
{
height: 100%;
width: 5px;
background: white;
content: "";
position: absolute;
right: 0;
top: 0;
-moz-transform: scaleY(0);
-ms-transform: scaleY(0);
-webkit-transform: scaleY(0);
transform: scaleY(0);
-moz-transition: 0.3s;
-o-transition: 0.3s;
-webkit-transition: 0.3s;
}
.transx::before
{
height: 5px;
width: 100%;
background: white;
content: "";
position: absolute;
left: 0;
top: 0;
-moz-transform: scaleX(0);
-ms-transform: scaleX(0);
-webkit-transform: scaleX(0);
transform: scaleX(0);
-moz-transition: 0.3s;
-o-transition: 0.3s;
-webkit-transition: 0.3s;
transition: 0.3s;
}
.transx::after
{
height: 5px;
width: 100%;
background: white;
content: "";
position: absolute;
left: 0px;
bottom: 0;
-moz-transform: scaleX(0);
-ms-transform: scaleX(0);
-webkit-transform: scaleX(0);
transform: scaleX(0);
-moz-transition: 0.3s;
-o-transition: 0.3s;
-webkit-transition: 0.3s;
transition: 0.3s;
}
.transx:hover::before, .transx:hover::after
{
-moz-transform: scaleX(1);
-ms-transform: scaleX(1);
-webkit-transform: scaleX(1);
transform: scaleX(1);
}
.transy:hover::before, .transy:hover::after
{
-moz-transform: scaleY(1);
-ms-transform: scaleY(1);
-webkit-transform: scaleY(1);
transform: scaleY(1);
}
<div class="classOne transy">
<div class="transx"></div>
<div class="flex-row">
Custome Text
</div>
</div>
You can only have one ::before and one ::after pseudo-element per element, but with some CSS magic you can make it look like the pseudo-elements of a child element belongs to its parent:
*::before,
*::after {
display: block;
}
.custom_class1::before {
content: "outer before"
}
.custom_class1::after {
content: "outer after"
}
.custom_class1 p::before {
content: "inner before";
position: absolute;
top: -18px;
}
.custom_class1 p::after {
content: "inner after";
position: absolute;
bottom: -18px;
}
.custom_class1 p {
position: relative;
background-color: lightblue;
}
.custom_class1 {
background-color: pink;
display: inline-block;
}
<div class="custom_class1 custom_class2">
<p>Custome Text</p>
</div>
You can achieve what you want without any pseudo element:
.box {
display:inline-block;
border:1px solid #000;
padding:4px;
background:
linear-gradient(#fff,#fff) left,
linear-gradient(#fff,#fff) bottom,
linear-gradient(#fff,#fff) right,
linear-gradient(#fff,#fff) top;
background-repeat:no-repeat;
background-origin:content-box;
background-size:5px 0%,0% 5px;
background-color:orange;
transition:0.5s;
}
.box:hover {
background-size:5px 100%,100% 5px;
}
.box a {
display:inline-block;
padding:20px 50px;
}
<div class="box">
text
</div>

How can I change the direction of my CSS underline transition and make it move from right to left?

I found this css code on internet it creates underline animation effect, i need to reverse it to be right-to-left instead of left to right.
.nav-item a {
display: inline-block !important;
&:after {
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
-webkit-transition: all .3s cubic-bezier(.19,1,.22,1);
-moz-transition: all .3s cubic-bezier(.19,1,.22,1);
transition: all .3s cubic-bezier(.19,1,.22,1);
-webkit-transform: scaleX(0) translate3d(0,0,0);
-moz-transform: scaleX(0) translate3d(0,0,0);
transform: scaleX(0) translate3d(0,0,0);
-webkit-transform-origin: 0 0;
-moz-transform-origin: 0 0;
-ms-transform-origin: 0 0;
-o-transform-origin: 0 0;
transform-origin: 0 0;
display: block;
height: 4px;
width: 100%;
background-color: #6cb2eb;
-o-transition: all .3s cubic-bezier(.19,1,.22,1);
opacity: 1;
content: "";
}
&:hover {
&:after {
-webkit-transform: scaleX(1) translate3d(0,0,0);
-moz-transform: scaleX(1) translate3d(0,0,0);
transform: scaleX(1) translate3d(0,0,0);
}
}
}
i tried to change &:after from scaleX(1) to scaleX(-1) it works as i needed but far from the text.
Just change transform-origin from 0 0 to 100% 100%:
.nav-item a {
display: inline-block !important;
}
.nav-item a:after {
border-radius: 10px;
transition: all 0.3s cubic-bezier(0.19, 1, 0.22, 1);
transform: scaleX(0) translate3d(0, 0, 0);
transform-origin: 100% 100%;
display: block;
height: 4px;
width: 100%;
background-color: #6cb2eb;
opacity: 1;
content: "";
}
.nav-item a:hover:after {
-webkit-transform: scaleX(1) translate3d(0, 0, 0);
-moz-transform: scaleX(1) translate3d(0, 0, 0);
transform: scaleX(1) translate3d(0, 0, 0);
}
<div class="nav-item">
<a>test</a>
</div>
Note: I converted scss to css and I removed useless vendor-specific properties
You have to float: right .nav-item a::after. It will work
.nav-item > a {
display: inline-block;
border-radius: 10px;
padding: 10px 20px;
transition: all 0.3s cubic-bezier(.19,1,.22,1);
text-decoration: none;
}
.nav-item > a::after {
content: '';
display: block;
height: 4px;
width: 0%;
background-color: #6cb2eb;
float: right;
transition: all 0.3s cubic-bezier(.19,1,.22,1);
}
.nav-item > a:hover::after {
width: 100%;
}
Check this fiddle - https://jsfiddle.net/jfgq2kva/6/

CSS Animation break transform

I have a little problem with my CSS file. I try to make an icon that scale to infinite (works), and when I click on icon, an animation rotate the parent to 90deg and the icon rotate to 45deg (works). But, if I combine the 2 behavior, the rotate of icon break. I want rotate the icon of 45deg, and keep the animation.
A demo example: https://codepen.io/KevinPy/pen/ooEbKY?editors=1100
In my demo, the first occurence works with the rotate to 45deg. The second occurence add the animation (via class), but the rotate is break.
Thank you for your answers.
HTML
<div id="first"><span>+</span></div>
<div id="second"><span class="anim">+</span></div>
SCSS
div {
margin: 25px;
display: inline-block;
position: relative;
background-color: blue;
width: 80px;
height: 80px;
&::before {
position: absolute;
top: 20px;
left: -20px;
content: '';
width: 0;
height: 0;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-right: 20px solid blue;
}
&.open {
transition: .2s transform linear;
transform: rotate(90deg);
span {
transition: .2s transform linear;
transform: rotate(-45deg);
}
}
&.close {
transition: .2s transform linear;
transform: rotate(0deg);
span {
transition: .2s transform linear;
transform: rotate(0deg);
}
}
}
span {
position: absolute;
top: 5px;
bottom: 0;
left: 0;
right: 0;
text-align: center;
color: white;
font-size: 60px;
}
.anim {
animation: keyAnim 3.4s linear infinite;
transform-origin: 50%;
}
#keyframes keyAnim {
0%, 100% {
transform: scale(1);
}
35%, 65% {
transform: scale(1.2);
}
50% {
transform: scale(1.5);
}
}
Your animation overrides the transform attribute. You could add a surrounding element:
var first = document.querySelector('#first');
first.onclick = function(event) {
if (first.classList.contains('open')) {
first.classList.remove('open');
first.classList.add('close');
} else {
first.classList.add('open');
first.classList.remove('close');
}
};
var second = document.querySelector('#second');
second.onclick = function(event) {
if (second.classList.contains('open')) {
second.classList.remove('open');
second.classList.add('close');
} else {
second.classList.add('open');
second.classList.remove('close');
}
};
div {
margin: 25px;
display: inline-block;
position: relative;
background-color: blue;
width: 80px;
height: 80px;
}
div::before {
position: absolute;
top: 20px;
left: -20px;
content: '';
width: 0;
height: 0;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-right: 20px solid blue;
}
div.open {
-webkit-transition: .2s transform linear;
transition: .2s transform linear;
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
}
div.open .anim_wrap {
-webkit-transition: .2s transform linear;
transition: .2s transform linear;
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
}
div.close {
-webkit-transition: .2s transform linear;
transition: .2s transform linear;
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
div.close .anim_wrap {
-webkit-transition: .2s transform linear;
transition: .2s transform linear;
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
span {
position: absolute;
top: 5px;
bottom: 0;
left: 0;
right: 0;
text-align: center;
color: white;
font-size: 60px;
}
.anim {
-webkit-animation: keyAnim 3.4s linear infinite;
animation: keyAnim 3.4s linear infinite;
-webkit-transform-origin: 50%;
transform-origin: 50%;
}
#-webkit-keyframes keyAnim {
0%, 100% {
-webkit-transform: scale(1);
transform: scale(1);
}
35%, 65% {
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
50% {
-webkit-transform: scale(1.5);
transform: scale(1.5);
}
}
#keyframes keyAnim {
0%, 100% {
-webkit-transform: scale(1);
transform: scale(1);
}
35%, 65% {
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
50% {
-webkit-transform: scale(1.5);
transform: scale(1.5);
}
}
<div id="first"><span class="anim_wrap">+</span></div>
<div id="second"><span class="anim_wrap"><span class="anim">+</span></span></div>

CSS3 Transform Translate to the left

I have titles that I want to add CSS3 animation to it
I want to transform
Title
to
[Title]
And I want the square brackets to animate from the center of the word to the borders of it with animation.
something like..
Ti[]tle
to
[Title]
with animation (ofcourse i'm using :before :after to add the brackets with opacity 0 to 1)
my p style:
p:before {
content: "[";
position: absolute;
left: 50%; /*to add the bracket to the center of the word*/
opacity: 0;
transition: all 0.7s ease;
}
Thank You !
p {
display: table;
position: relative;
}
p:before,
p:after{
position: absolute;
opacity: 0;
transition: all 0.7s ease;
}
p:before {
content: "[";
left: 50%;
}
p:after {
content: "]";
right: 50%;
}
p:hover:before {
left: -5px;
opacity: 1;
}
p:hover:after {
right: -5px;
opacity: 1;
}
<p>Title</p>
<p>A Longer Title</p>
Is this what you are looking for?
with this html:
<div>
TESTING
</div>
and these css's:
div{
padding: 18px 0 18px 0;
display: inline-block;
margin-right: 40px;
}
a {
color: #999;
display: inline-block;
text-align: center;
width: 200px;
text-decoration: none;
}
a:before, a:after {
display: inline-block;
opacity: 0;
-webkit-transition: -webkit-transform 0.3s, opacity 0.2s;
-moz-transition: -moz-transform 0.3s, opacity 0.2s;
transition: transform 0.3s, opacity 0.2s;
}
a:before {
margin-right: 10px;
content: '[';
-webkit-transform: translate(20px, -1px);
-moz-transform: translate(20px, -1px);
transform: translate(20px, -1px);
vertical-align: top;
}
a:after {
margin-left: 10px;
content: ']';
-webkit-transform: translate(-20px, -1px);
-moz-transform: translate(-20px, -1px);
transform: translate(-20px, -1px);
}
a:hover:after {
opacity: 1;
-webkit-transform: translate(0px, -1px);
-moz-transform: translate(0px, -1px);
transform: translate(0px, -1px);
}
a:hover:before {
opacity: 1;
-webkit-transform: translate(0px, -1px);
-moz-transform: translate(0px, -1px);
transform: translate(0px, -1px);
}
You get this JSFIDDLE
You can achieve this using frame animations. This way you won't have to hover the element (or anything else) for the animation to start.
See: http://jsfiddle.net/Paf_Sebastien/j2cvagjf/
Set :before and :after like this :
h1:before {
content: "[";
position: absolute;
display: block;
top: 0;
-webkit-animation: bracketleft 1s 1 forwards;
animation: bracketleft 1s 1 forwards;
}
Then handle the animation :
#-webkit-keyframes bracketleft {
0% { opacity: 0; left: 50%; }
100% { opacity: 1; left:-10px; }
}
#-webkit-keyframes bracketright {
0% { opacity: 0; right: 50%; }
100% { opacity: 1; right: -10px; }
}

Resources