I have a jQuery animation that turns a flashcard. This is the HTML:
<div class="stage">
<div class="flashcard">
<div class="front">
<p>Front</p>
</div>
<div class="back">
<p>Back</p>
</div>
</div>
This is my CSS:
.stage {
-webkit-perspective: 1000;
}
.flashcard {
height: 300px;
width: 500px;
margin: 10% auto;
border: 1px solid gray;
box-shadow: 2px 2px 2px #000;
-webkit-transform-style: preserve-3d;
transition: all 0.3s;
-webkit-transition: all 0.3s;
}
.flipped, .back {
transform: rotateX(180deg);
-webkit-transform: rotateX(180deg);
}
.front, .back {
position: absolute;
-webkit-backface-visibility: hidden;
height: 300px;
width: 500px;
text-align: center;
}
.front p, .back p {
margin-top: 25%;
font-size: 3em;
}
And this is my jQuery code:
$(document).ready(function() {
$('.flashcard').on('click', function() {
$('.flashcard').toggleClass('flipped');
});
});
I made a For loop with PHP to loop my HTML code, so it can show multiple flashcards at once. The problem is that if I click on a random flashcard, all the flashcards turn at once.
What do I have to change in my code to make sure only the clicked flashcard turns around?
Try using $(this) not $(".flashcard") on the toggleClass() function. Because on your script, you are literally toggling all the class. Use that to fire event on a specific element that you want to trigger.
here is a working code
http://codepen.io/mozzi/pen/akwVrg
I've change the javascript to
$(document).ready(function() {
$('.flashcard').on('click', function() {
$(this).toggleClass('flipped');
});
});
Related
I am trying to create a tooltip for whatever that needs it on my website, e.g. a button, text, etc. So far I have something like this:
https://jsfiddle.net/f06q3cLg/
.content {
display: grid;
width: 100vw;
height: 100vh;
place-content: center;
}
.content .parent {
border: 1px red solid;
padding: 10px;
position: relative;
}
.content .parent:hover .tooltip-wrapper {
animation: 0.1s fadeInTooltip;
animation-fill-mode: forwards;
animation-delay: 0.4s;
}
.content .parent:hover:before {
animation: 0.1s fadeInTooltip;
animation-fill-mode: forwards;
animation-delay: 0.4s;
}
.content .parent:active .tooltip-wrapper {
animation: 0.05s fadeOutTooltip;
animation-fill-mode: forwards;
}
.content .parent:active:before {
animation: 0.05s fadeOutTooltip;
animation-fill-mode: forwards;
}
.content .parent:before {
content: "";
display: block;
width: 0;
height: 0;
position: absolute;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
left: 50%;
transform: translateX(-50%);
opacity: 0;
}
.content .parent .tooltip-wrapper {
position: absolute;
display: grid;
left: 0;
width: 300px;
height: 100%;
opacity: 0;
pointer-events: none;
}
.content .parent .tooltip-wrapper.bottom {
top: calc(100% + 8px);
}
.content .parent .tooltip-wrapper .tooltip {
max-width: 300px;
width: fit-content;
padding: 8px;
position: absolute;
display: inline-block;
background: blue;
border-radius: 5px;
padding: 8px;
color: white;
font-size: 11px;
box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
line-height: 1.3;
text-align: left;
}
/* Keyframes */
#keyframes fadeInTooltip {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes fadeOutTooltip {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
<div class="content">
<div class="parent">
Hover me
<div class="tooltip-wrapper">
<span class="tooltip">This is my tooltip</span>
</div>
</div>
</div>
As such, it works somewhat fine. My issue is that I would like the tooltip to disappear when I click the button. Now it vanishes, and then comes back with a 0.4s delay as the hover effect actually has. Ideally the tooltip should disappear as long as my mouse is still on the button, but when I remove it and re-enters the button, then the tooltip should re-appear.
I'm not sure if this is even achievable with pure CSS, but any JS would also do.
The problem is that :active is only applied as long as the mouse is down.
mdn: :active:
The :active CSS pseudo-class represents an element (such as a button) that is being activated by the user. When using a mouse, "activation" typically starts when the user presses down the primary mouse button.
What you could do (if you want to stay CSS only) is to use tabindex="0" on the <div class="parent"> and :focus instead of :active. But you need to verify that using tabindex="0" here won't hurt usability.
Ideally the tooltip should disappear as long as my mouse is still on the button, but when I remove it and re-enters the button, then the tooltip should re-appear.
That won't work with :focus either. I'm pretty sure that this behavior can only be achieved with JS. If it is possible with CSS only it likely would be a pretty hacky solution.
But from the perspective of a user, this seems to be counterintuitive that the tooltip won't appear after clicked.
A JavaScript solution that does what you want could look like this.
It is a simplified version of the tooltip to only show the relevant parts.
Every element having a tooltip has an attribute data-has-tooltip.
// event delegation for all mouse down event:
// this ensures that the code also works for elements that have been added to the DOM after that script was executed.
document.addEventListener('mousedown', (evt) => {
// check if the mousedown happened in an element with a tooltip
const element = evt.target.closest('[data-has-tooltip]');
if (element) {
// if the user already clicked on the element ignore the click
if (!element.classList.contains('active')) {
// add the active class to the element so that hover won't show the toolip
element.classList.add('active');
function removeActiveOnLeave() {
// remove the active class
element.classList.remove('active');
// remove the mouseleave event listener again
element.removeEventListener('mouseleave', removeActiveOnLeave)
}
// add an event listener for mouseleave to remove the active class
element.addEventListener('mouseleave', removeActiveOnLeave)
}
}
});
.parent {
display: inline-block;
border: 1px solid red;
padding: 0.5rem;
margin: 0.5rem;
}
.tooltip-wrapper {
display: none;
}
.parent:hover .tooltip-wrapper {
display: block;
}
.parent.active:hover .tooltip-wrapper {
display: none;
}
<div class="content">
<div class="parent" data-has-tooltip>
Hover me A
<div class="tooltip-wrapper">
<span class="tooltip">This is my tooltip A </span>
</div>
</div>
</div>
<div class="content">
<div class="parent" data-has-tooltip>
Hover me B
<div class="tooltip-wrapper">
<span class="tooltip">This is my tooltip B</span>
</div>
</div>
</div>
HTML
<div class="content">
<div class="parent" onClick="myFunction()">
Hover me
<div class="tooltip-wrapper">
<span class="tooltip" id="tooltip">This is mytooltip</span>
</div>
</div>
</div>
Javascript
function myFunction(){
var tooltip=document.getElementById("tooltip");
if (tooltip.style.display=="none") {
document.getElementById("tooltip").style.display="block";
} else {
document.getElementById("tooltip").style.display="none";
}
}
Manipulating 'display' property.
const parent = document.querySelector('.parent');
const toolTip = document.querySelector('.tooltip');
parent.addEventListener('click', () => {
if(toolTip.style.display !== 'none') {
toolTip.style.display = 'none';
}else {
toolTip.style.display = 'grid';
}
});
A solution using jQuery 3.4.1:
$(".parent").click(function () {
$(".tooltip-wrapper").css("display", "none");
});
The only downfall with that solution is once you click and re-hover in the same session, the SCSS :hover doesn't work properly.
No need to stress, just add the following if you want that functionality:
$(".parent").hover(function () {
$(".tooltip-wrapper").css("display", "block");
});
Try it out in the attached snippet:
$(".parent").click(function () {
$(".tooltip-wrapper").css("display", "none");
});
$(".parent").hover(function () {
$(".tooltip-wrapper").css("display", "block");
});
.content {
display: grid;
width: 100vw;
height: 100vh;
place-content: center;
}
.content .parent {
border: 1px red solid;
padding: 10px;
position: relative;
}
.content .parent:hover .tooltip-wrapper {
animation: 0.1s fadeInTooltip;
animation-fill-mode: forwards;
animation-delay: 0.4s;
}
.content .parent:hover:before {
animation: 0.1s fadeInTooltip;
animation-fill-mode: forwards;
animation-delay: 0.4s;
}
.content .parent:active .tooltip-wrapper {
animation: 0.05s fadeOutTooltip;
animation-fill-mode: forwards;
}
.content .parent:active:before {
animation: 0.05s fadeOutTooltip;
animation-fill-mode: forwards;
}
.content .parent:before {
content: "";
display: block;
width: 0;
height: 0;
position: absolute;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
left: 50%;
transform: translateX(-50%);
opacity: 0;
}
.content .parent .tooltip-wrapper {
position: absolute;
display: grid;
left: 0;
width: 300px;
height: 100%;
opacity: 0;
pointer-events: none;
}
.content .parent .tooltip-wrapper.bottom {
top: calc(100% + 8px);
}
.content .parent .tooltip-wrapper .tooltip {
max-width: 300px;
width: fit-content;
padding: 8px;
position: absolute;
display: inline-block;
background: blue;
border-radius: 5px;
padding: 8px;
color: white;
font-size: 11px;
box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
line-height: 1.3;
text-align: left;
}
/* Keyframes */
#keyframes fadeInTooltip {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes fadeOutTooltip {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="content">
<div class="parent">
Hover me
<div class="tooltip-wrapper">
<span class="tooltip">This is my tooltip</span>
</div>
</div>
</div>
OR, you can see it working in this Fiddle. with your initial
SCSS.
You can uncomment the second function to see the hover working again after clicking.
I put a down-directed arrow icons on the bottom of the first view of my website. I set the css for the icons like below. However I scroll down the page, they follow. I just want leave them on the first view. Does anyone have any tips to fix that?
function scrollDown() {
var businessPage = document.getElementById("businessPage");
businessPage.scrollIntoView();
}
.box {
position: absolute;
top: 90%;
left: 50%;
transform: translate(-50%, -50%);
}
.box span {
display: block;
width: 20px;
height: 20px;
border-bottom: 3px solid white;
border-right: 3px solid white;
transform: rotate(45deg);
margin: -10px;
animation: animate 2s infinite;
}
.box span:nth-child(1) {
opacity: 0.3
}
.box span:nth-child(2) {
opacity: 0.5;
}
<body>
<div class="box">
<span onclick="scrollDown()"></span>
<span onclick="scrollDown()"></span>
<span onclick="scrollDown()"></span>
</div>
</body>
I want a css option for this
currently i am using this css classes
.a{
top:-102px;
height: 140px !important;
}
.b{
top:0px;
height: 240px !important;
}
but this is opening the div from top to bottom and i want it to open from bottom to top
can Anyone please help its very important
thanks in advance
You need to wrap your div in another div
Give the parent div position:relative
Give the child div position:absolute
Anchor the child div using bottom:0
Demo 1 uses minimal JavaScript:
classList.toggle()
Demo 2 uses only CSS:
<label> and <input type='checkbox'> needed for "trigger"
Demo 1 (Plain JavaScript)
var x = document.querySelector('.x');
x.addEventListener('click', function(e) {
this.classList.toggle('b');
});
.y {
position: relative;
height: 240px;
width: 50px;
background: brown;
}
.x {
position: absolute;
height: 140px;
width: 50px;
background: red;
bottom: 0;
transition: height .5s ease;
}
.b {
height: 240px;
transition: height .5s ease;
}
<div class='y'>
<div class='x'>Click the Red</div>
</div>
Demo 2 (Pure CSS)
.y {
position: relative;
height: 240px;
width: 50px;
background: brown;
}
.x {
position: absolute;
height: 140px;
width: 50px;
background: red;
bottom: 0;
transition: height .5s ease;
}
#chx {
display: none
}
#chx:checked+.y .x {
height: 240px;
transition: height .5s ease;
}
<input id='chx' type='checkbox'>
<div class='y'>
<label for='chx'>
<div class='x'>Click on the Red</div>
</label>
</div>
why don't you try something like this?
.b{
top:0px;
height: 240px !important;
display:hidden;
}
and with jquery
$('.a').click(function(){
$('.b').show('fast');
})
You can put one div inside the main div. And give it overflow: hidden;
HTML
<div class='main_div'>
<div class='overlay_div'>
</div>
</div>
CSS
.main_div{
height: 240px;
}
.overlay_div{
height: 140px;
overflow: hidden;
}
Javascript
$('.overlay_div').click(function(){
$('.overlay_div').css({'overflow': 'visible'});
});
Please check below solution. I hope this will help you.
$('.a').click(function(){
$(this).toggleClass('b');
})
.a{
position:absolute;
top:100px;
height: 50px !important;
border:1px solid red;
transition-property: all;
transition-duration: .5s;
}
.b{
top:0px;
height: 150px !important;
border:1px solid red;
transition-property: all;
transition-duration: .5s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="a">Hello World!</div>
You can't handle click with CSS. you must add JavaScript for this.
I have made a sample code for hover
Here it's
<div class="wrapper">
<div class="face">Face</div>
<div class="back">Back</div>
</div>
And styling
.wrapper {
border: 1px solid red;
height: 100px;
width: 100px;
overflow: hidden;
}
.wrapper:hover .face {
margin-top: -100%;
}
.face, .back {
height: 100%;
transition: margin ease 0.2s;
}
.face {
background-color: yellow;
}
.back {
background-color: orange;
}
Here's the a CodePen for you:
https://codepen.io/AbuMuslim/pen/GvEwYz
You can use JS as following:
document
.querySelector('.wrapper')
.addEventListener('click', function() {
this.classList.toggle('active');
});
And instead of using hover selector, we change to .active, as following:
.wrapper.active .face {
margin-top: -100%;
}
Here's a CodePen for that: https://codepen.io/AbuMuslim/pen/QMgJVw
I have two panels at the top of my application and one button at the button. By default only panel one must be visible, but by clicking on the button panel one fades away, and panel two fades in. I created the layout, but I do not know how to achieve it.
$(".panel2").hide();
$(document).ready(function() {
$(".grid-button").on("click", function() {
$(".grid").toggleClass("open close");
});
});
div.app {
margin:50px auto;
width: 400px;
height: 400px;
border-radius:10px;
overflow: hidden;
position: relative;
}
div.app > .blur {
width: 100%;
height: 100%;
background: url(http://goo.gl/0VTd9W);
-webkit-filter: blur(5px);
}
div.mainSection, div.dashboard{
position: absolute;
left: 0px;
text-align:center;
color:#fff;
font-size:20px;
}
div.mainSection{
width:100%;
height:85%;
background:rgba(0,0,0,0.5);
top:0;
}
div.dashboard{
width:100%;
height:15%;
background:rgba(255,0,0,0.5);
bottom:0;
}
div.mainSection > .panel1,
div.mainSection > .panel2 {
width: 100%;
Height: 100%;
Background: rgba(0, 0, 0, 0.5);
position: absolute;
left: 0px;
top: 0px;
}
.grid-button {
background: none;
border: none;
padding: 3px;
width: 100%;
}
.grid {
display: inline-block;
height: 4px;
position: relative;
width: 32px;
transition: all 0.3s ease-in-out;
}
.grid:after, .grid:before {
content: '';
position: absolute;
background-color: #FFF;
display: inline-block;
height: 4px;
left: 0;
width: 32px;
transition: all 0.3s ease-in-out;
}
.grid.open {
background-color: #FFF;
}
.grid.open:after {
top: 10px;
}
.grid.open:before {
top: -10px;
}
.grid.close {
background-color: transparent;
transform: scale(0.9);
}
.grid.close:after, .grid.close:before {
top: 0;
transform-origin: 50% 50%;
}
.grid.close:before {
transform: rotate(135deg);
}
.grid.close:after {
transform: rotate(45deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="app">
<div class="blur"></div>
<div class="mainSection">
<div class="panel1">Panel1</div>
<div class="panel2">Panel2</div>
</div>
<div class="dashboard">
<div class="grid-button">
<span class="grid open"></span>
</div>
</div>
</div>
First of all since I did $('.panel2').hide();, in page load first it loads the panel then hides it. How can I make it invisible from the beginning?
Secondly how can I make the panel2 visible only by pressing the button?
And finally is there anyway to add some transitions effects for changing panels?
You may try:
$(".grid-button").on("click", function() {
var visibleObj = $('.mainSection div:visible');
var inVisibleObj = $('.mainSection div:hidden');
visibleObj.fadeOut(500, function() {
inVisibleObj.fadeIn(500);
});
});
While for the visibility you need:
<div class="panel2" style="display: none;">Panel2</div>
The running snippet:
$(function () {
$(".grid-button").on("click", function() {
var visibleObj = $('.mainSection div:visible');
var inVisibleObj = $('.mainSection div:hidden');
visibleObj.fadeOut(500, function() {
inVisibleObj.fadeIn(500);
});
});
});
div.app {
margin:50px auto;
width: 400px;
height: 400px;
border-radius:10px;
overflow: hidden;
position: relative;
}
div.app > .blur {
width: 100%;
height: 100%;
background: url(http://goo.gl/0VTd9W);
-webkit-filter: blur(5px);
}
div.mainSection, div.dashboard{
position: absolute;
left: 0px;
text-align:center;
color:#fff;
font-size:20px;
}
div.mainSection{
width:100%;
height:85%;
background:rgba(0,0,0,0.5);
top:0;
}
div.dashboard{
width:100%;
height:15%;
background:rgba(255,0,0,0.5);
bottom:0;
}
div.mainSection > .panel1,
div.mainSection > .panel2 {
width: 100%;
Height: 100%;
Background: rgba(0, 0, 0, 0.5);
position: absolute;
left: 0px;
top: 0px;
}
.grid-button {
background: none;
border: none;
padding: 3px;
width: 100%;
}
.grid {
display: inline-block;
height: 4px;
position: relative;
width: 32px;
transition: all 0.3s ease-in-out;
}
.grid:after, .grid:before {
content: '';
position: absolute;
background-color: #FFF;
display: inline-block;
height: 4px;
left: 0;
width: 32px;
transition: all 0.3s ease-in-out;
}
.grid.open {
background-color: #FFF;
}
.grid.open:after {
top: 10px;
}
.grid.open:before {
top: -10px;
}
.grid.close {
background-color: transparent;
transform: scale(0.9);
}
.grid.close:after, .grid.close:before {
top: 0;
transform-origin: 50% 50%;
}
.grid.close:before {
transform: rotate(135deg);
}
.grid.close:after {
transform: rotate(45deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="app">
<div class="blur"></div>
<div class="mainSection">
<div class="panel1">Panel1</div>
<div class="panel2" style="display: none;">Panel2</div>
</div>
<div class="dashboard">
<div class="grid-button">
<span class="grid open"></span>
</div>
</div>
</div>
To make one of the panels hidden in the first place, I'd use a css class called hidden:
.hidden{
display : none;
}
Which simply makes what it sounds like, hiding the element.
Than, I'd set this class in the HTML decleration:
<div class="panel2 hidden">Panel2</div>
That will hide panel2 on page load, and by that you don't have to hide it using js code.
Than, I'd use a helper css class called panel that stands to be a panel identifier (you can either use the data attribute, or any other way of identifying those elements).
For 5 panels, it would look like this:
<div class="panel panel1">Panel1</div>
<div class="panel panel2 hidden">Panel2</div>
<div class="panel panel3 hidden">Panel3</div>
<div class="panel panel4 hidden">Panel4</div>
<div class="panel panel5 hidden">Pane5</div>
At last, to make this work for any number of panels you want (not necesseraly 2), I'd use a "carousel" effect to toggle the panels visibility, while having a way to keep track with them (adding and removing the hidden class), and use the fadeIn/fadeOut effect. (again, instead of identifying the panels using the panel1,panel2,panel3... classes, you can always use the data attribute (please read more about it in jQuery docs), or in any other way).
var currentPanel = 1;
$(".grid-button").on("click", function() {
$(".grid").toggleClass("open close");
$(".panel"+currentPanel).fadeOut("normal", function(){
$(this).addClass('hidden');
});
currentPanel = currentPanel >= $(".panel").length ? 1 : currentPanel+1;
$(".panel"+currentPanel).fadeIn().removeClass('hidden');
});
Just note that the hidden class actually "looses" it's functionality after the first click, since jQuery changes the display property inline, but I think that it might not be harmful to keep them anyway (it will be easier to track them).
You can see an example here: https://jsfiddle.net/j79y5kdb/3/
I am trying to use the new AngularJS way of doing animations between page transitions and would like to incorporate a card flip (like http://jsfiddle.net/nicooprat/GDdtS/)
body {
background: #ccc;
}
.flip {
-webkit-perspective: 800;
width: 400px;
height: 200px;
position: relative;
margin: 50px auto;
}
.flip .card.flipped {
-webkit-transform: rotatex(-180deg);
}
.flip .card {
width: 100%;
height: 100%;
-webkit-transform-style: preserve-3d;
-webkit-transition: 0.5s;
}
.flip .card .face {
width: 100%;
height: 100%;
position: absolute;
-webkit-backface-visibility: hidden ;
z-index: 2;
font-family: Georgia;
font-size: 3em;
text-align: center;
line-height: 200px;
}
.flip .card .front {
position: absolute;
z-index: 1;
background: black;
color: white;
cursor: pointer;
}
.flip .card .back {
-webkit-transform: rotatex(-180deg);
background: blue;
background: white;
color: black;
cursor: pointer;
}
I am just a bit unsure how to update that code to make it work with AngularJS for a page transition.
Any thoughts?
I realize this was a long time ago, but I was just doing this, and it took zero javascript. The key is ng-class. Here is a JSFIDDLE.
The key is this line
<div class="card" ng-class="{'flipped':isFlipped}" ng-click="isFlipped=!isFlipped">
It will assign the class 'flipped' to the card when $scope.isFlipped is true. Here is a little NFL flash cards game I put together for fun. Check out the source code (which isn't super pretty), it should be helpful if you are doing something like this.
NFL Flash Cards
Here is an alternate solution where it's more clear from the html what's happening. Specifically, the flip mechanism is in angularjs rather than buried in css magic. Perhaps easier to follow for anyone who's not a css expert:
<div class="card" ng-click="isFlipped=!isFlipped">
<div class="face front" ng-class="{'flipped':isFlipped}">
Front
</div>
<div class="face back" ng-class="{'flipped':!isFlipped}">
Back
</div>
</div>