Flip Menu with Fixed Top Menu - javascript

I have a doubt.
I need to implement a flip menu, but on the internet I found only examples using css transformations, and vendors prefix. But all examples show divs that are not fixed, and the css below have a fixed menu (copied and pasted code and reduce the net, is not very pretty) and when I have a menu and the approaches of put font and back divs don't work.
I need help with this. I need a way in which whole site (including the set menu) are replaced with other content (as a great turning of the page).
Example: http://davidwalsh.name/css-flip
I need a horizontal flip, and right horizontal flip.
Thank you so much.
CodePen: http://codepen.io/anon/pen/BuHql
HTML:
<div class="nav">
<ul>
<li>Home</li>
<li>CSS</li>
<li>PHP</li>
<li>SEO</li>
<li>jQuery</li>
<li>Wordpress</li>
<li>Services</li>
</ul>
<div class="clear"></div>
</div>
</div>
CSS:
body { height: 800px; background: black; }
.nav{ background: white; z-index: 9999; position: fixed; left: 0; top: 0; width: 100%;}
.nav { height: 42px; background: white;}
.nav ul { list-style: none; }
.nav ul li{float: left; margin-top: 6px; padding: 6px; border-right: 1px solid #ACACAC;}
.nav ul li:first-child{ padding-left: 0;}
.nav ul li a { }
.nav ul li a:hover{ text-decoration: underline;}

An easy way to do this, in otherwise case, is using the following construction:
HTML:
<div class="flipper">
<div class="front">Front content</div>
<div class="back">Back content</div>
</div>
CSS:
/*Placing colors to facilitate understanding.*/
.front { background: green; }
.back { background: red; }
/*Add this class to a ".flipper" element using the way that is well to you (using a click, a hover or any other trigger).*/
.flip {
transform: rotateY(180deg);
-webkit-transform: rotateY(180deg);
/*Add others vendors styles to more compatibility*/
}
/*Configuring the duration and the 3d mode of command*/
.flipper {
position: relative; /*relative is very important*/
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
transition: 2s;
-webkit-transition: 0.6s;
}
/*Required for no appear both at the same time*/
.front {
z-index: 2;
}
/*Causes the back start hidden (it is rotated 180 degrees, so it will not appear)*/
.back {
transform: rotateY(180deg);
-webkit-transform: rotateY(180deg);
}
/*Hide the rear face during the flip.*/
.front, .back {
position: relative; /*Again, the relative position is very important to work on any layout without crash.*/
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
/*needed for webkit browsers understand what's in front and what is behind*/
body {
perspective: 1000;
-webkit-perspective: 1000;
}
JS (jQuery) use example:
$('body').hover(function () {
$('.flipper').addClass('flip');
});
$('body').click(function () {
$('.flipper').removeClass('flip');
});

There is a simple jquery plugin that can help you achieving this effect.
You can find it here:
http://guilhemmarty.com/flippy//
It is easy to use and you can choose what kind of flip you want. ;)

Related

Text color in CSS Animation doesn't update with rest of content when 'theme toggle' is clicked on iOS

I have text that scrolls horizontally in a marquee style effect. This works great.
In addition to this I have a 'toggle' that when clicked adds the class .dark-mode to the html tag which basically inverts all the colours. So by default it's white page, black text. When toggled, black page, white text.
This works perfectly on my desktop browser. However I've noticed on iOS Safari and Chrome the text within the CSS Animation does not update with the rest of the copy. I haven't been able to test if that's the case on Android as well.
I've included the code for this but also put it on a CodePen here incase it's easier to view for people: https://codepen.io/moy/pen/eYjryXN
What's additional strange, if I scroll down the page then back up the text DOES change colour? Which indicates to me maybe once the animation is running, it leaving the viewport and re-entering somehow renders it again and corrects the colour?
I thought adding:
document.querySelector(‘.marquee’).offsetWidth;
Might force a 'reflow' of the page but it didn't do anything. Really appreciate some help on this. Strange one!
const html = document.querySelector('html');
const button = document.querySelector('.contrast__link');
button.addEventListener('click', e => {
e.preventDefault();
html.classList.toggle('dark-mode');
});
:root {
--color-primary: black;
--color-secondary: white;
--spacing: 24px;
}
.dark-mode {
--color-primary: white;
--color-secondary: black;
}
body {
background: var(--color-secondary);
color: var(--color-primary);
margin: 0 auto;
padding: 48px 24px;
max-width: 800px;
}
.marquee {
margin: 0 calc(var(--spacing) * -1);
margin-bottom: 120px;
}
.marquee h1 {
display: flex;
flex: 1 1 auto;
flex-wrap: nowrap;
overflow: hidden;
}
.marquee span {
-webkit-animation: 8s linear infinite 0s forwards running marquee;
animation: 8s linear infinite 0s forwards running marquee;
box-sizing: border-box;
flex: 1 0 50%;
padding: 0 var(--spacing);
white-space: nowrap;
text-align: center;
}
/**
* The looping animation for the marquee.
*/
#-webkit-keyframes marquee {
from {
transform: translateX(0);
}
to {
transform: translateX(-100%);
}
}
#keyframes marquee {
from {
transform: translateX(0);
}
to {
transform: translateX(-100%);
}
}
<div class="grid__item">
<div class="hgroup">
<div class="marquee">
<h1 class="page-title">
<span>Hello... is it me you're looking 404?</span>
<span>Hello... is it me you're looking 404?</span>
<span>Hello... is it me you're looking 404?</span>
<span>Hello... is it me you're looking 404?</span>
</h1>
</div>
</div>
<p class="contrast">Toggle Here</p>
</div>

HTML - Second IMG hover issue

I have 2 semicircles stuck next to each other forming a circle. When I hover on the left semicircle, the right one lowers it's opacity (which is what is supposed to do) but when I hover on the right one, the opacity doesn't change at all.
HTML:
<div id="animation-components">
<img src="leftball.svg" alt="" class="animation-item-01">
<img src="rightball.svg" alt="" class="animation-item-02">
</div>
CSS:
#animation-components {}
.animation-item-01 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(631px,80px);
height: 320px;
transition: opacity ease 0.5s;
}
.animation-item-02 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(627px,80px);
height: 320px;
transition: opacity ease 0.5s;
}
.animation-item-01:hover + .animation-item-02{
opacity: 50%;
}
.animation-item-02:hover + .animation-item-01{
opacity: 50%;
}
What can I alter to make this work?
The issue is that you can only select the next sibling with the adjacent sibling selector.
.element-1 + .element-2 /* good */
.element-2 + .element-1 /* not so good */
Since .animation-item-02 comes after .animation-item-01, there is no way to select the previous .animation-item-01 from .animation-item-02
Doing the following will fix the issue:
#animation-components:hover > div {
opacity: 50%;
}
#animation-components > div:hover {
opacity: 100%;
}
CSS Combinators can't be used to apply styles to elements before target element.
The adjacent sibling selector (+) will aply to all adjacent elements, not to it's opposite elements.
CSS It's in the name: Cascading Style Sheets only supports styling in cascading direction, not up.
To achieve the desired, you can do the folowwing:
#animation-components:hover img {
opacity: .5;
}
#animation-components img:hover{
opacity: 1;
}
<div id="animation-components">
<img src="https://via.placeholder.com/150.png/ff0000" alt="" class="animation-item-01">
<img src="https://via.placeholder.com/150.png/ff0000" alt="" class="animation-item-02">
</div>
It might just be me but I find it heaps easier to throw in just a little bit of javascript and avoid messy css combinators. Heres my fix, script goes anywhere in your html file, I put it after the closing body tag.
<script>
function fadeOut(obj) {
document.getElementById(obj).style.animationName = "fadeOut";
}
function fadeIn(obj) {
document.getElementById(obj).style.animationName = "fadeIn";
}
</script>
#item1 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(631px,80px);
height: 320px;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
#item2 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(627px,80px);
height: 320px;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
#keyframes fadeOut {
0%{opacity: 1;}
100%{opacity: 0.5;}
}
#keyframes fadeIn {
0%{opacity: 0.5;}
100%{opacity: 1;}
}
<div id="animation-components">
<img src="leftball.svg" alt="" id="item1" onmouseover="fadeOut('item1')" onmouseout="fadeIn('item1')">
<img src="rightball.svg" alt="" id="item2" onmouseover="fadeOut('item2')" onmouseout="fadeIn('item2')">
</div>
Also its just a me thing, but you have class attributes where id attributes should be. If your applying seperate styles to two completely seperate elements its a good idea to use id, but if your applying same style to two elements

CSS transition div width from center

I am working on a little menu animation, nothing groundbreaking but just as an experiment. This is what I currently have:
HTML
<div class="menu">
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
</div>
SCSS
div.menu {
width: 24px;
height: 24px;
position: relative;
margin: 48px;
cursor: pointer;
div.bar {
display: block;
width: 100%;
height: 2px;
background-color: #444;
position: absolute;
transition: all 0.25s ease-in-out;
&:nth-child(1) {
}
&:nth-child(2) {
top: 11px;
}
&:nth-child(3) {
top: 11px;
}
&:nth-child(4) {
bottom: 0;
}
}
&.active {
div.bar {
&:nth-child(1) {
width: 0;
}
&:nth-child(2) {
transform: rotate(-45deg);
}
&:nth-child(3) {
transform: rotate(45deg);
}
&:nth-child(4) {
width: 0;
}
}
}
}
JAVASCRIPT
var menu = document.querySelector('.menu');
menu.addEventListener('click', function(){
menu.classList.toggle('active');
});
And this is a pen of it in action:
https://codepen.io/mikehdesign/pen/eWJKKN
Currently, when the menu is active the top and bottom div.bar reduce their width to 0 to the left. I would like to adjust this so they reduce their width to the center. I have tried messing with margins for them but had no luck, if anyone could shed some light or suggest a different approach if needed that would be great.
Mike
You can use transform-origin to do this:
with respect to your dimensions it would be 12px up and down(+ and -) as in the code below:
&.active {
div.bar {
&:nth-child(1) {
transform-origin:12px 12px;
transform: scale(0);
}
&:nth-child(2) {
transform: rotate(-45deg);
}
&:nth-child(3) {
transform: rotate(45deg);
}
&:nth-child(4) {
transform-origin:12px -12px;
transform: scale(0);
}
}
}
Check this out: JsFiddle Link
I would use the pseudo elements to split up the transform animation.
Demo (no script version)
HTML (note only three bars)
<input type="checkbox" id="toggle-menu" hidden>
<label for="toggle-menu" class="menu">
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
</label>
SCSS
// two step transition
// as translate and rotation can't (yet) be animated individually
// we use the pseudo elements to split up the animation
//
// - bar elements will handle the vertical transform
// - :after elements will handle rotation/scale
// variables to control transition time and delay
$transition-time: 300ms;
$transition-delay: 300ms;
.menu {
width: 24px;
height: 24px;
position: relative;
cursor: pointer;
display: block;
}
.bar {
height: 2px;
position: absolute;
top: 50%;
width:100%;
// Entering `hamburger` state
// 1) add a delay on bars to wait for the :after elements to rotate/scale back
// 2) the :after elements have no delay
transition: $transition-time $transition-delay; // 1
&:after {
content:'';
display:table;
background: black;
position: inherit; width: inherit; height:inherit;
transition: $transition-time; // 2
}
// transform the bars into hamburger
&:nth-child(1){ transform: translateY(-8px); }
&:nth-child(3){ transform: translateY(8px);}
}
// when toggle-menu checkbox is checked transform to `X`
[id="toggle-menu"]:checked ~ .menu {
.bar {
// Entering `X` state
// 1) to animate bars to the center we simply remove the transform
// 2) as we are now animating backwards we switch the transition
// on the bars and their :after elements
transform: none; // 1
transition: $transition-time; // 2
&:after { transition: $transition-time $transition-delay } // 2
// rotate the top and bottom :after elements
&:nth-child(1):after{ transform: rotate(-45deg); }
&:nth-child(3):after{ transform: rotate(45deg);}
// hide the middle :after by scaling to zero
// (when all bars are at the center)
&:nth-child(2):after{ transform: scale(0); }
}
}

automatic cookie bar pure css works fine but need delay

I added this pure css cookie bar to my website and all works fine, the only problem is that when you enter in the site, you can see FIRST the cookie bar, AND the cookie bar go up and go down at the end.
How can see my cookie bar only go down when i enter in my site, i thought to change de thenimation delay, add set time out .... but nothing change !!
here is the original codepen and you can see what i want to change in it
www.codepen.io/natewiley/pen/uGtcD
HERE IS MY CODE
<input class="checkbox-cb" id="checkbox-cb" type="checkbox" />
<div class="cookie-bar">
<div class="message">
This website uses cookies to give you an incredible experience. By using
this website you agree to the
<div class="buttoncookies-container">
<a style="letter-spacing: 1px;" class="buttoncookies" id="modalcookieslinken" onclick="toggleOverlay()">terms</a>
</div>
</div>
<div class="mobile">
This website uses cookies,
<div class="buttoncookies-container">
<a style="letter-spacing: 1px;" class="buttoncookies" id="modalcookiesshortlink" onclick="toggleOverlay()">
learn more
</a>
</div>
</div>
<label for="checkbox-cb" class="close-cb">X</label>
</div>
</div>
HERE IS MY CSS
.cookie-bar { z-index:9996; position: fixed; width: 100%; top: 0; right: 0; left: 0; height: auto; padding: 20px; line-height:20px; text-align: center; background: #d2c6af; transition: .8s; animation: slideIn .8s; animation-delay: .8s; display: inline-block; }
.mobile { display: none; }
#keyframes slideIn { 0% { transform: translateY(-1000px); } 100% { transform: translateY(0); } }
.close-cb { border: none; background: none; position: absolute; display: inline-block; right: 20px; top: 10px; cursor: pointer; }
.close-cb:hover { color:#fff;; }
.checkbox-cb { display: none;}
#checkbox-cb:checked + .cookie-bar { transform: translateY(-1000px); }
Removing the line in css
animation-delay: .8s;
will give you the result
Make the animation last longer.
animation: slideIn 4s;
Plus add some trick to animation flow:
0% {
transform: translateY(-50px);
}
50% {
transform: translateY(-50px);
}
100% {
transform: translateY(0);
}

The easiest way to change text with flip effect

I am looking for simple way to flip text.
For example I have currently "Hello" text in tag, and I need to flip it to "world", only once , I don't need to flip it back to "Hello", even if sometimes need I don't really need to save previous state. Just pass new text string and it should flip older to newer one.
I know that there are a lot of libraries like https://github.com/daynin/wodry , but for this I need to provide span inside it with specific style, and hardcode all possible flip text strings. I don't need specific part of the text, I need to flip it all at once.
Please suggest the best way to implement this.
Without using span, here is an example of what you are trying to achieve
- from Hello to word, without going back ( you can adjust it later to your needs: height, colour, width and the other attributes)
HTML:
<div class="flip">
<div class="item">
<div class="face front">Hello</div>
<div class="face back">word</div>
</div>
</div>
CSS:
.flip {
-webkit-perspective: 300;
width: 400px;
height: 200px;
}
.flip .item.flipped {
-webkit-transform: rotatex(-180deg);
}
.flip .item {
width: 100%;
height: 100%;
-webkit-transform-style: preserve-3d;
-webkit-transition: 0.5s;
}
.flip .item .face {
width: 100%;
height: 100%;
position: absolute;
-webkit-backface-visibility: hidden ;
z-index: 2;
text-align: center;
line-height: 200px;
}
.flip .item .front {
position: absolute;
z-index: 1;
background: black;
color: white;
cursor: pointer;
}
.flip .item .back {
-webkit-transform: rotatex(-180deg);
background-color: green;
color: black;
}
and a little JS to make it functional:
$('.flip').click(function () {
$(this).find('.item').addClass('flipped');
});
fiddle url: http://jsfiddle.net/GDdtS/9909/

Categories