I want to change the opacity of some text in my div when hover over happens :
currently my transition looks like this, and it just moved the box up a bit:
.bg-onebyone {
transition: all 0.5s ease;
background: #17B6A4 none repeat scroll 0% 0% !important;
}
.bg-onebyone:hover {
margin-top: -8px;
}
In my div.bg-onebyone I have another div holding some text like this
.bg-onebyone .widget-stats .stats-icon {
color: #FFF;
opacity: 0.5;
}
And what I want to do is just when the main div is hovered over I want to also increased the above opacity in the transition. How can I do this ?
<a href="/url">
<div class="widget widget-stats bg-onebyone">
<div class="stats-icon stats-icon-lg">
<i class="fa fa-search fa-fw"></i>
</div>
<div class="stats-desc">Creating Grouped Unmatched Aliases</div>
</div>
</a>
You need to use the :hover pseudo-class on parent and then select the child element.
.bg-onebyone:hover .stats-icon {
opacity: 0.8;
}
Also .bg-onebyone .widget-stats .stats-icon is incorrect for your HTML markup since it targets .stats-icon as a grand-child of .bg-onebyone which does not exist.
Output:
.bg-onebyone {
width: 300px;
height: 100px;
transition: all 0.5s ease;
background: #17B6A4 none repeat scroll 0% 0% !important;
}
.bg-onebyone:hover {
margin-top: -8px;
}
.bg-onebyone .stats-icon {
color: #FFF;
opacity: 0.5;
}
.bg-onebyone:hover .stats-icon {
opacity: 0.8;
}
<div class="widget widget-stats bg-onebyone">
<div class="stats-icon stats-icon-lg">Test text for opacity
<i class="fa fa-search fa-fw"></i>
</div>
<div class="stats-desc">Creating Grouped Unmatched Aliases</div>
</div>
Via JavaScript, use jQuery .hover() and .css(), like this:
$( "mainDiv" ).hover(
function() {
$("whereToChangeTheOpacity").css( "opacity", "0.5" );
},
function() {
$("whereToChangeTheOpacity").css( "opacity", "0" );
}
);
Related
I have a custom animation that the regular Vue transition doesn't quite cover. I have it implemented elsewhere with a conditional v-bind:class, but that doesn't work well for conditional v-if blocks or v-for groups.
I need to add a class ('open') one frame after the element is entered as with v-enter-to, but I need it to never be removed from the element.
I then need it removed removed when leaving to trigger the closing animation.
Am I using Vue Transition wrong and this is perfectly possible within transition, or is there a way to add/remove the class around the enter/leave functionality?
.accordion {
overflow: hidden;
> div {
margin-bottom: -1000px;
transition: margin-bottom .3s cubic-bezier(.5,0,.9,.8),visibility 0s .3s,max-height 0s .3s;
max-height: 0;
overflow: hidden;
}
&::after {
content: "";
height: 0;
transition: height .3s cubic-bezier(.67,.9,.76,.37);
max-height: 35px;
}
&.open {
max-height: 8000px;
> div {
transition: margin-bottom .3s cubic-bezier(.24,.98,.26,.99);
margin-bottom: 0;
max-height: 100000000px;
position: relative;
}
&::after {
height: 35px;
max-height: 0;
transition: height .3s cubic-bezier(.76,.37,.67,.9),max-height 0s .3s;
}
}
}
<transition name="accordion" :duration="300">
<div class="accordion" v-if="equipmentSelections.length === 0">
<div>
<p>Begin by selecting equipment from the list</p>
</div>
</div>
</transition>
<transition-group name="accordion" :duration="300">
<div v-for="equipment in equipmentSelections" v-bind:key="equipment.unitNumber" class="accordion">
<div>
<h3 v-on:click="updateSelections(equipment)">{{equipment.unitNumber}}</h3>
</div>
</div>
</transition-group>
You can get more power out of the vue transition component by using the javascript hooks.
For example:
Demo: https://codepen.io/KingKozo/pen/QWpBPza
HTML:
<div id="app">
<div>
<button type="button" #click="toggle">Toggle</button>
</div>
<transition name="label" v-on:enter="enter" v-on:before-leave="leave">
<div v-if="isOpen">Hi</div>
</transition>
</div>
CSS
.label-enter-active, .label-leave-active {
transition: opacity 1s;
}
.label-enter, .label-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
}
.staying-visible {
background-color: red;
color: white;
}
Javascript
const vm = new Vue({
el: '#app',
data: {
isOpen: false
},
methods: {
enter(el){
el.classList.add("staying-visible")
},
leave(el){
el.classList.remove("staying-visible")
},
toggle(){
this.isOpen = !this.isOpen
}
}
})
In the example I provided I add a brand new class, "staying-visible", to the element on enter and remove it later on. In the example provided, I remove the class on "before-leave" so as to make the change visible but for your specific use case it seems like you can also just remove it during the 'leave' hook.
To learn more about how to use the javascript transition hooks, check out the official documentation: https://v2.vuejs.org/v2/guide/transitions.html#JavaScript-Hooks
I want to build a simple "carousel" in React. I have a list of questions that I want the user to answer. When you click on next, it shows the next question. I want to also add a previous button in the future. Currently the animation for the item being revealed works.
However on mobile the screen jumps up when its animating from one div to another (with a slight delay)
The height of the parent div is always the same, so why would it jump?
JSX
{ this.state.activeIndex === 0 &&
<div className="surveyContainer--surveyList__animate">
<div>
<SelectField labels={data.meat.labels} value={this.props.survey.meat}/>
</div>
<div>
<Button handleClick={() => this.handleActiveIndex(2)} label="Next"/>
</div>
</div>
}
{this.state.activeIndex === 1 &&
<div className="surveyContainer--surveyList__animate">
<div>
<SelectField labels={data.energy.labels} value={this.props.survey.energy}/>
</div>
<div>
<Button handleClick={() => this.handleActiveIndex(2)} label="Next"/>
</div>
</div>
}
<SelectField/> and Button are both custom components.
CSS
.surveyContainer--surveyList__animate {
animation: slide-in 0.4s ease;
}
#keyframes slide-in {
0% {
opacity: 0;
transform: translateX(200px);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
How do I fix the jumping? Also what might be a better approach to do this entire thing? If I want to add a previous button, then switching the animation will be a painstaking feature.
Edit:
For the jumping issue, try setting the parent's position to relative, then, for the child container:
.child {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
I recommend ReactTransitionGroup:
https://reactcommunity.org/react-transition-group/css-transition
Your code would look something like this:
import { CSSTranstion } from 'react-transition-group'
<CSSTranstion in={this.state.activeIndex === 0} timeout={200} classNames="survey-list" unmountOnExit>
<div className="survey-list">
<div>
<SelectField labels={data.meat.labels} value={this.props.survey.meat}/>
</div>
<div>
<Button handleClick={() => this.handleActiveIndex(2)} label="Next"/>
</div>
</div>
</CSSTransition>
<CSSTranstion in={this.state.activeIndex === 1} timeout={200} classNames="survey-list" unmountOnExit>
<div className="survey-list">
<div>
<SelectField labels={data.energy.labels} value={this.props.survey.energy}/>
</div>
<div>
<Button handleClick={() => this.handleActiveIndex(2)} label="Next"/>
</div>
</div>
</CSSTransition>
Then your CSS:
.survey-list {
opacity: 1;
transform: translateX(0);
}
.survey-list.survey-list-enter {
opacity: 0;
transform: translateX(200px);
}
.survey-list.survey-list-enter-active {
opacity: 1;
transform: translateX(0);
transition: opacity 200ms;
}
.survey-list.survey-list-exit {
opacity: 1;
}
.survey-list.survey-list-exit-active {
opacity: 0;
transform: translateX(-200px);
transition: opacity 200ms;
}
And I'm not sure entirely the breadth of your intention, but you may also want to look into TransitionGroup, since it will automate adding classes to an array of children as they're toggled in and out:
https://reactcommunity.org/react-transition-group/transition-group
As a sidenote, if you're using BEM for your CSS, you shouldn't (i.e. surveyContainer--survey-list) be using a modifier as a block. Just allow survey-list to be its own block if it has its own elements. It prevents long confusing classes.
I have the following HTML structure:
<div class="products-container">
{foreach from=$cart.products item=product}
<div class="product" data-id-product="{$product.id_product}" data-id-product-attribute="{$product.id_product_attribute}">
...
</div>
</div>
Now I have a javascript that can remove any div .product.
Is there a way to fade the deleted div out of the DOM to the right and animate the other divs 'moving up to the free space'?
A simple example
let btt = document.querySelector('button');
let products_cnt = document.querySelector('.products');
let products = document.querySelectorAll('.product');
products[0].addEventListener('transitionend', function() {
[...products].forEach((p) => p.parentNode.removeChild(p))
});
btt.addEventListener('click', function() {
this.setAttribute('disabled', 'disabled');
products_cnt.classList.add('products--delete');
})
div {
border: 1px #9bc solid;
height: 60px;
width: 200px;
margin: 10px;
color: #69A;
font: 1em system-ui;
}
button {
margin-bottom: 3em;
cursor: pointer; }
.products {
overflow-x: hidden; }
.product {
font-weight: bold;
transition: transform 1.5s 0s, opacity 1.25s 0s;
transform: translateX(0);
opacity: 1;
}
.products--delete .product {
transform: translateX(100vw);
opacity: 0;
}
<button type="button">Remove product/s</button>
<section class="products">
<div>Not a product</div>
<div class="product">Product</div>
<div class="product">Product</div>
<div>Not a product</div>
<div class="product">Product</div>
<div>Not a product</div>
</section>
Explanation: when you click the button the class .products--delete is added to the .products_container element: this starts a CSS transition over the .product elements.
Finally, when the transitionend event occurs on a single product element just remove from the DOM all products.
You can use css transitions in your CSS. The part of removing may be different for you. Please click the product to remove it.
let productsRy = Array.from(document.querySelectorAll(".product"));
productsRy.forEach((p,i)=>{
p.style.top = i * (3 + 1) * 16 +"px";
p.addEventListener("click",()=>{
container.removeChild(p);
productsRy = Array.from(document.querySelectorAll(".product"));
productsRy.forEach((p1,i1)=>{p1.style.top = i1 * (3 + 1) * 16 +"px";})
})
})
.products-container{position:relative;}
.product{
position:absolute;
padding:1em;
margin:.5em;
height:3em;
outline:1px solid; width:200px;
height:auto;
transition: all 1s;
}
}
<div class="products-container" id="container">
<div class="product" data-id-product="a" data-id-product-attribute="a">
product a
</div>
<div class="product" data-id-product="b" data-id-product-attribute="b">
product b
</div>
<div class="product" data-id-product="c" data-id-product-attribute="c">
product c
</div>
</div>
CSS really doesn't have the ability to modify an object in the same manner as JavaScript. you can do this easily.
$(".product").fadeTo("slow", 0.00, function(){
$(this).slideUp("slow", function() {
$(this).remove();
});
});
I am developing a web application using Material Design Lite.
One of the requirements is this: A sidebar exists such that by default, it will display the icons of the menu items at a smaller width (say 50px). Clicking on the menu (hamburger) icon then expands the drawer to a larger size and shows not only the icons but the text beside them. Here is an example of what I want to achieve:
Default:
Expand:
Here is my current HTML:
<body>
<!-- Always shows a header, even in smaller screens. -->
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
<header class="mdl-layout__header">
<div class="mdl-layout__header-row">
<button class="mdl-button mdl-js-button mdl-button--icon">
<i class="material-icons">menu</i>
</button>
<!-- Add spacer, to align navigation to the right -->
<div class="mdl-layout-spacer"></div>
<!-- Navigation. We hide it in small screens. -->
<button class="mdl-button mdl-js-button mdl-button--icon">
<i class="material-icons">apps</i>
</button>
</div>
</header>
<div class="mdl-layout__drawer">
<span class="mdl-layout-title"></span>
<nav class="mdl-navigation">
<a class="mdl-navigation__link" href="">
<i class="material-icons md-dark">account_circle</i>
<span>Account</span>
</a>
<a class="mdl-navigation__link" href="">
<i class="material-icons md-dark">home</i>
<span>Home</span>
</a>
<a class="mdl-navigation__link" href="">
<i class="material-icons md-dark">assignment</i>
<span>Reports</span>
</a>
<a class="mdl-navigation__link" href="">
<i class="material-icons md-dark">input</i>
<span>Logout</span>
</a>
</nav>
</div>
<main class="mdl-layout__content">
<div class="page-content">
<!-- Your content goes here -->
#RenderBody()
</div>
</main>
</div>
</body>
Is there a good/correct way of doing this? I was wondering how this could be done and haven't come up with a good solution.
Have a look at this answer. I think it's a good approach to achieving this effect.
You can then just drop the polyfill in and write in your CSS something like:
.mdl-navigation .material-icons {
opacity: 0;
transition: 250ms opacity ease-in-out;
}
.mdl-navigation[min-width~="200px"] .material-icons {
opacity: 1;
}
If you think a polyfill is too much to add just this functionality I can think of one other way that doesn't use any javascript, but it wouldn't be as flexible with regards to how you animate the showing/hiding should you want to animate it. It involves overlapping the main content area over the drawer. Give me a moment and I'll mock up a demo.
EDIT
Here's what I was thinking as far as a non-js approach (still requires some for the toggling of the is-expanded class): https://jsfiddle.net/damo_s/27u4huzf/2/
.mdl-layout__drawer {
transform: translateX(0);
z-index: 1;
box-shadow: none;
border-right: 0;
&.is-expanded {
+ .mdl-layout__header {
margin-left: 240px!important;
&:before {
width: 0;
left: 200px;
}
}
~ .mdl-layout__content {
margin-left: 240px!important;
&:before {
width: 0;
left: 200px;
}
}
}
}
.mdl-layout__header,
.mdl-layout__content {
margin-left: 55px!important;
}
.mdl-layout__header {
z-index: 2;
&:before {
background: #fff;
content: '';
display: block;
position: absolute;
width: 15px;
height: 100%;
left: 40px;
}
}
.mdl-layout__header-row {
padding: 0 16px 0 22px;
}
.mdl-layout__content {
background: #878787;
}
.mdl-layout__drawer-button {
display: none;
}
.mdl-layout__drawer .mdl-navigation .mdl-navigation__link:hover {
background-color: transparent;
}
On looking at it now, I don't think it's a very good approach (for a number of reasons you might notice playing around with it), but I'll leave it here just in case anyone wishes to improve upon it.
EDIT 2
I modified the previous demo to simplify it and allow for opening/closing animation. I don't know if at this point you'd exactly be doing things the "Material" way but I think it's workable and better anyway than my previous attempt. Demo: https://jsfiddle.net/damo_s/Ln6e4qLt/
.mdl-layout__drawer {
overflow: hidden;
width: 55px;
transform: translateX(0);
transition: 250ms width ease-in-out;
.mdl-navigation__link span {
opacity: 0;
transition: 250ms opacity ease-in-out;
}
+ .mdl-layout__header,
~ .mdl-layout__content {
transition: 250ms margin-left ease-in-out;
}
&.is-expanded {
width: 240px;
.mdl-navigation__link span {
opacity: 1;
}
+ .mdl-layout__header,
~ .mdl-layout__content{
margin-left: 240px!important;
}
}
}
.mdl-layout__header,
.mdl-layout__content {
margin-left: 55px!important;
}
.mdl-navigation {
width: 240px;
}
.mdl-layout__header-row {
padding: 0 16px 0 22px;
}
.mdl-layout__content {
background: #878787;
}
.mdl-layout__drawer-button {
display: none;
}
This cannot be done by pure CSS. You have have to use jQuery. Something like this
$('#hamburger-button').on('click',function() {
$('#menu .links').css('display','block');
});
Assuming you have hidden links by display:none.
If you can post here your css and html code I can help with specific example.
I'm trying to make an animated menu that when I hover over it , the background (or image) reduces and at the same time the text expands.
Thats my style sheet :
.menus {
float: left;
background-image: url(images/menus_bg.png);
width: 208px;
height: 283px;
}
.menusimg {
width: 208px;
height: 283px;
position: absolute;
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center center;
background-image: url(images/menu1.png);
}
.menusimg:hover {
background-size: 80% 80%;
}
.menusimg, .menusimg:hover {
-webkit-transition: background-size 0.2s ease-in ;
}
.menustxtbox {
font-family: MP;
padding-top: 240px;
width: 208px;
height: 283px;
color: #4c4c4c;
font-size: large;
text-shadow: gray 0.1em 0.1em 0.2em;
}
.menustxtbox:hover {
padding-top: 235px;
font-size: x-large;
color: #4fa3f9;
}
.menustxtbox, .menutxtbox:hover {
-webkit-transition:font-size 0.1s linear;
-moz-transition:font-size 0.1s linear;
}
and the html :
<div class="menus">
<div class="menusimg">
</div>
<div class="menustxtbox">
Text
</div>
</div>
Any ideas? A simple Java script or anything that will solve this problem? :)
Thank you in advance ^^
I second what ntgCleaner said.
In addition you can use:
$('.menus').hover(function(){
$('.menusimg').addClass('active');
$('.menustxtbox').addClass('active');
}, function(){
$('.menusimg').removeClass('active');
$('.menustxtbox').removeClass('active');
});
And your css would have:
.menusimg.active, .menusimg.active{
-webkit-transition: background-size 0.2s ease-in ;
}
etc.
Well, without any code to see that you've done anything or tried anything with javascript, I would suggest this:
Change your CSS to make real sizes of font size first:
.menustxtbox {
font-size:40px;
}
then make some jquery
$('.menus').hover(function(){
$('.menusimg').animate({width: "100px"});
$('.menustxtbox').animate({fontSize: "90px"});
}, function(){
$('.menusimg').animate({width: "208px"});
$('.menustxtbox').animate({fontSize: "40px"});
});
Then delete your :hover css styles
And if you want to use hover, I would suggest looking into hoverintent
UPDATE for a comment below
To do this for each separate menu item, you will have to name things a certain way. Here's an example.
HTML
<div class="menu">
<div class="menuItem" id="menu1">
<div class="menusimg"></div>
<div class="menustxtbox"></div>
</div>
<div class="menuItem" id="menu2">
<div class="menusimg"></div>
<div class="menustxtbox"></div>
</div>
<div class="menuItem" id="menu3">
<div class="menusimg"></div>
<div class="menustxtbox"></div>
</div>
</div>
Then with jQuery, you will have to use $(this) and .children()
$('.menuItem').hover(function(){
$(this).children('.menusimg').animate({width: "100px"});
$(this).children('.menustxtbox').animate({fontSize: "90px"});
}, function(){
$(this).children('.menusimg').animate({width: "208px"});
$(this).children('.menustxtbox').animate({fontSize: "40px"});
});
When you use $(this), you will do whatever you want to the specific thing you are trying to use. Then you just go up or down from there using parent or children to do something to either of those.