On-click transitioning <ul> does not respond - html

I have a responsive navigation which should display a menu when a button is clicked. When it is clicked, the ul containing the navigation list is added a class (.show-nav) to by jQuery/JS. When this happens a CSS-rule for .show-nav changes the opacity and top-values, so that the ul comes down. I tried adding a transition to this, but the ul refuses to respond to that.
On the other hand, I also have a header-element, which changes the background-color when a certain y scroll value is reached (also done by JS). This works in the exacly same way as the latter, by adding a class to the header and having the CSS applying a background-color.
function toggleClass(jqo, c) {
var o = $(jqo);
if (!o.hasClass(c)) {
o.addClass(c);
} else {
o.removeClass(c);
}
}
header {
width: 100%;
text-align: right;
position: fixed;
background-color: rgba(0, 0, 0, 0);
transition: background-color 0.3s;
}
header .mobile-list {
display: none;
}
.mobile-header .mobile-list {
width: 100%;
height: 100%;
padding-top: 90px;
right: 0;
top: -50%;
opacity: 0.5;
position: fixed;
z-index: -1;
background-color: #005163;
transition: top 2s, opacity 2s;
}
.show-nav .mobile-list {
display: block;
top: 0;
opacity: 1;
}
.compact {
background-color: #005163;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<nav>
<button class="hamburger" onclick="toggleClass('.hamburger', 'is-active'); toggleClass('header', 'show-nav')" type="button">
<span class="hamburger-box">
<span class="hamburger-inner"></span>
</span>
</button>
<ul class="mobile-list">
<li>PHYSICS</li>
<li>CHEMISTRY</li>
<li>BIOLOGY</li>
<li>MATH</li>
<li>TOOLS</li>
</ul>
</nav>
</header>
.compact is assigned by JS, just like .show-nav. But header is responding to the transition and the ul is not!
Note that .mobile-header is active in every case, so that's no concern.
I also concluded that the ul does respond to all other CSS, just not the transition. I've looked at other websites (dashlane.com) that have the same kind of navigation system and tried to copy it's structure, but without much avail. How can I achieve the ul having a transition and why does my header react where my ul doesn't?
Thanks in advance.
EDIT:
Added transition line in CSS under .mobile-header .mobile-list.
EDIT: Added jQuery code.

You have to know that the css display property cannot be animated,
So you have to try another solution, best thing at the meanwhile is the visibility and opacity properties.
just remove the display: none / display: block and replace it with:
/*Element style when it's hidden*/
.elementStyle {
opacity: 0;
visibility: hidden;
}
/*Element style when it's visible*/
.elementStyle {
opacity: 1;
visibility: visible;
}
function toggleClass(jqo, c) {
var o = $(jqo);
if (!o.hasClass(c)) {
o.addClass(c);
} else {
o.removeClass(c);
}
}
header {
width: 100%;
text-align: right;
position: fixed;
background-color: rgba(0, 0, 0, 0);
transition: background-color 0.3s;
}
.mobile-header .mobile-list {
width: 100%;
height: 100%;
padding-top: 90px;
right: 0;
top: -50%;
opacity: 0.5;
position: fixed;
z-index: -1;
background-color: #005163;
transition: top 2s, opacity 2s;
}
header .mobile-list {
visibility: hidden;
transition: 1s;
/*Add whatever transition you want*/
opacity: 0;
display: block;
}
.show-nav .mobile-list {
top: 0;
opacity: 1;
visibility: visible;
}
.compact {
background-color: #005163;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<nav>
<button class="hamburger" onclick="toggleClass('.hamburger', 'is-active'); toggleClass('header', 'show-nav')" type="button">Test Button
<span class="hamburger-box">
<span class="hamburger-inner"></span>
</span>
</button>
<ul class="mobile-list">
<li>PHYSICS</li>
<li>CHEMISTRY</li>
<li>BIOLOGY</li>
<li>MATH</li>
<li>TOOLS</li>
</ul>
</nav>
</header>

Related

How do you position a menu to start at the end of its parent with transition?

I have a menu inside a link positioned to the bottom of this link with position: absolute. I use translateY rule because link have diferent height on diferent screens, but I use an animation and it override the translateY rule while transitions happens.
nav {
text-align: right
}
.dropdown,
.trigger,
.menu {
display: inline-block;
}
.dropdown {
position: relative;
}
.trigger {
background: yellow
}
.menu {
opacity: 0;
background: orange;
bottom: 0;
right: 0;
transform: translateY(100%);
height: 50px; /* The height is variable*/
position: absolute;
}
.trigger:focus + .menu{
opacity: 1;
animation: toogle-show-menu 0.25s;
}
#keyframes toogle-show-menu {
0% {
transform: scale(0.95);
transform-origin: 100% 0;
opacity: 0;
}
100% {
transform: scale(1);
opacity: 1;
}
}
<nav>
<div class="dropdown">
<button class="trigger">
LINK MENU
</button>
<div class="menu">
menu
</div>
</div>
</nav>
Otherwise, I would like to know if there is another html structure to handle this easier.
Use top:100%
nav {
text-align: right
}
.dropdown,
.trigger,
.menu {
display: inline-block;
}
.dropdown {
position: relative;
}
.trigger {
background: yellow
}
.menu {
background: orange;
top:100%;
right: 0;
height: 50px; /* The height is variable*/
position: absolute;
}
<nav>
<div class="dropdown">
<div class="trigger">
LINK MENU
</div>
<div class="menu">
menu
</div>
</div>
</nav>

Display link on top of image and lower image opacity when mouseover of centre of image only?

Is it possible to only lower opacity and display link when I hover over the centre of my image? Have gone through trial and error, adding width, height, margins all over with no success. Currently the code works fine when I mouse over the image. But I would like it to only change opacity and display the link on mouseover of the centre of the image, something like an area of 500px width x 325px height.
<div class="processor-container">
<div class="processor-image-container">
<img class="processor-image" src="images/shop/cpu.png" alt="">
<div class="processor-link-container">
<a class="processor-link" href="shopprocessors.html">Shop Processors</a>
</div>
</div>
</div>
CSS
.processor-container {
padding: 100px 0 100px 0;
}
.processor-image-container {
position: relative;
margin: 0 auto 0 auto;
}
.processor-image {
width: 100%;
height: 100%;
}
.processor-image, .processor-link-container {
transition: opacity 0.3s ease;
}
.processor-link-container {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
opacity: 0;
transition: opacity 0.3s ease;
}
.processor-link {
display: block;
font-size: 2.6em;
color: white;
text-decoration: underline #f76441;
}
.processor-image-container:hover .processor-link-container {
opacity: 1;
}
.processor-image-container:hover .processor-image {
opacity: 0.4;
}
You will have to use the onmouseover Javascript event, which provides the properties offsetX and offsetY.

Element shaking on Hover/Class Toggle only in Safari

I have a sidebar menu with logo toggle button which toggles the class "toggled" and on large screens also appears on hover.
The sidebar is left: 100% and on toggle/hover left: 0;
On all browsers except safari it works fine. Only on safari the logo button wiggles/shakes when letting the navigation appear.
Here a short overview of the code:
.main-navigation {
//Structure
display: inline-block;
width: 160px;
transition: all 250ms ease-in;
height: 100vh;
z-index: 100;
position: fixed;
left: -100%;
background-color: $color__primary;
&.toggled {
left: 0;
}
.menu-toggle {
margin-left: auto;
align-self: flex-end;
display: inline-block;
position: fixed;
background: none;
border: none;
border-radius: 0;
left: 20px;
top: 25px;
width: auto;
height: auto;
padding: 0;
z-index: 110;
&:focus, &:active {
outline: none;
}
}
}
And on large screens i just add the hover:
.main-navigation{
&:hover {
left: 0;
}
}
You can see it live under https://rocket.creos.agency/
I hope im just overlooking something small.
Thanks for the help!
In order to fix your problem you need to move your 'logo' from the nav element. If it is inside, like you have it's trying too animate all elements inside nav.
Here is your logic with simple code (logo is inside nav):
body {
margin: 0;
padding: 0;
}
nav {
position: fixed;
height: 100vh;
width: 160px;
left: -160px;
background-color: tomato;
-webkit-transition: all 250ms ease-in-out;
transition: all 250ms ease-in-out;
}
nav:hover {
left: 0;
}
button {
position: fixed;
top: 10px;
left: 10px;
}
.content {
margin-top: 50px;
}
<nav>
<button>
Hover me
</button>
<div class='content'>
<ul>
<li>
one
</li>
<li>
two
</li>
</ul>
</div>
</nav>
And this is when 'logo' is outside the nav:
(() => {
const btn = document.getElementById('animateNav');
const nav = document.getElementById('navigation');
const content = document.getElementById('content');
btn.addEventListener('mouseover', () => {
nav.classList.add("animate");
});
nav.addEventListener('mouseout', () => {
nav.classList.remove("animate");
});
nav.addEventListener('mouseover', () => {
nav.classList.add("animate");
});
content.addEventListener('mouseover', () => {
nav.classList.add("animate");
});
})();
body {
margin: 0;
padding: 0;
}
nav {
position: fixed;
height: 100vh;
width: 160px;
left: -160px;
background-color: tomato;
-webkit-transition: all 250ms ease-in-out;
transition: all 250ms ease-in-out;
}
nav.animate {
left: 0;
}
button {
position: fixed;
top: 10px;
left: 10px;
}
#content {
margin-top: 50px;
}
<nav id='navigation'>
<div id='content'>
<ul>
<li>
one
</li>
<li>
two
</li>
</ul>
</div>
</nav>
<button id='animateNav'>
Hover me
</button>
All difference is in second example that you need to toggle a class for nav using JavaScript. I provided not efficient logic to toggle a class, but I just wanted to present to you working solution.
P.S. don't use <a> tag inside of <button> tag

hover appearing and disappearing

Right now I have an image that has another image absolutely positioned on top of the first one. Both images are inside an a tag.
I am trying to get it so that when I hover on any part of the first image, both the first image goes from .5 opacity to full, and the 2nd image goes from 0 opacity to full.
I've been able to make the hover work for the image but the 2nd image only activates it's opacity when I hover directly on it, rather than highlighting both when I'm on either of them.
<div class="of-volume image-column">
<a href="http://www.greatlengthshair.co.uk/hair-extensions/">
<img src="img/artistry-1-bg.jpg" alt="artisans of volume link" class="image-link">
<img src="img/artistry-1-icon.png" alt="" class="artisan-icon">
</a>
</div>
/*//////////////////////////////////////
IMAGE NAV
//////////////////////////////////////*/
.image-column {
background-color: black;
float: left;
width: 33.3333%;
position: relative;
margin-bottom: -3px;
}
.image-column a {
opacity: .5;
}
.image-column a:hover {
opacity: 1;
}
.artisan-icon {
position: absolute;
margin-right: auto;
margin-left: auto;
right: 0;
left: 0;
bottom: 25px;
}
You have mixed up most of your CSS rules. Just attach the desired effects to the correct hover state:
.image-link { opacity: 0.5; }
.artisan-icon { opacity: 0; }
a:hover .image-link { opacity: 1; }
a:hover .artistan-icon { opacity: 1; }
I put both absolute images inside a relative div, then did set the :hover selector on this container.
body {
width: 100%;
height: 100%;
margin: 0px;
}
#container {
position:relative;
width:100%;
height:200px;
}
img {
position:absolute;
top: 0px;
left:0px;
width:100%;
height:200px;
-webkit-transition: opacity 1s; /* Safari */
transition: opacity 1s;
}
#pic1 {
opacity:0.0;
}
#pic2 {
opacity:0.5;
}
#container:hover #pic1, #container:hover #pic2 {
opacity: 1;
}
<div id=container>
<img id=pic1 class=picture src="http://i.imgur.com/tMVGqP6.jpg" alt=img>
<img id=pic2 class=picture src="http://i.imgur.com/Goy7oBy.gif" alt=img>
</div>

CSS: Replacing a text on hover, but smooth transition to the new text does not work?

The scenario:
If a user hovers over a text (e.g. an h1-tag), it should change to a new text. The new text should appear smoothly.
What I've done so far:
I was able to replace a text with a new one with the "display:none" and the "content: 'This is the new text' "-property. My problem is that the new text does not appear smoothly (it does not fade in/transitions).
I've also tried to use opacity, but it doesn't replace my old text (instead it just disappears and the new text appears next to it).
Here is a JSFiddle and code snippet:
.my_div {
background-color: red;
}
.my_div:hover {
background-color: green;
transition: all 500ms ease-in-out;
}
.my_div:hover .title span {
display: none;
}
.my_div:hover .title:after {
content: "A wild text appears";
}
<div class="my_div">
<h1 class="title"><span>This is the old text</span></h1>
</div>
Here is a really simple sample
(This hidden snippet use pseudo elements instead of the visible's inner div's)
div, div:after, div:before {
height: 100px;
width: 100px;
position: absolute;
font-size: 40px;
color: black
}
div:after {
content: "New";
opacity: 0;
}
div:before {
content: "Old";
opacity: 1;
}
div:after, div:before {
transition: opacity 0.5s linear;
}
.wrap:hover:before {
opacity: 0;
}
.wrap:hover:after {
opacity: 1;
}
<div class="wrap">
</div>
div {
height: 100px;
width: 100px;
position: absolute;
font-size: 40px;
color: black
}
.new {
opacity: 0;
}
.old, .new {
transition: opacity 0.5s linear;
}
.wrap:hover .old {
opacity: 0;
}
.wrap:hover .new {
opacity: 1;
}
<div class="wrap">
<div class="new">New</div>
<div class="old">Old</div>
</div>
OK, so first part, you cannot animate the display property, you need a work-around. To do this we fall back to what we can animate, opacity and width/height
For what you are trying to accomplish, I'd use two spans inside the <h1> - one with each text version. Since spans are inline elements we give them display: block so we can control there dimensions more cleanly.
.my_div {
background-color: red;
transition: all 500ms ease-in-out;
}
.my_div:hover {
background-color: green;
}
h1 {
overflow: hidden;
}
.old-text,
.new-text {
display: block;
overflow: hidden;
transition: all 500ms ease-in-out;
}
.old-text {
height: auto;
opacity: 1;
width: auto;
}
.new-text {
color: #fff;
height: 0;
opacity: 0;
width: 0;
}
.my_div:hover .old-text {
height: 0px;
opacity: 0;
width: 0px;
}
.my_div:hover .new-text {
height: auto;
opacity: 1;
width: auto;
}
<div class="my_div">
<h1 class="title">
<span class="old-text">This is the old text</span>
<span class="new-text">A wild text appears!</span>
</h1>
</div>
The question has already been answered, but I think the best approach would be to use a pseudo element.
It's very simple and clean.
BUT: you lose the transition effect.
.MySpecialTag:before
{
content: "The old text";
}
.MySpecialTag:hover:before
{
content: "The new text";
}
<h1 class="MySpecialTag"></h1>