slidetoggle in pure Javascript - javascript

As you might see I have fixed a kind of text box that will pop up when someone is hovering over that image, but honestly I want a slide-up effect that gone up slowly. Must be completely in pure JavaScript (no jQuery please!). Anyone knows how I can do that.
function show(myText) {
var elements = document.getElementsByClassName(myText)
for(var i = 0; i < elements.length; i++){
elements[i].style.visibility = "visible";
}
}
function hide(myText) {
var elements = document.getElementsByClassName(myText)
for(var i = 0; i < elements.length; i++){
elements[i].style.visibility = "hidden";
}
}
.text1 {
position: relative;
bottom: 28px;
text-align: center;
background-color: grey;
width: 100%;
height: 10%;
font-size: 20px;
color: white;
opacity: 0.7;
display: block;
visibility: hidden;
}
.text2 {
position: relative;
bottom: 28px;
text-align: center;
background-color: grey;
width: 100%;
height: 10%;
font-size: 20px;
color: white;
opacity: 0.7;
display: block;
visibility: hidden;
}
<div class="row">
<div class="col-md-6 col-sm-12">
<div class="tumb-wrapper">
<a href="http://www.bbc.com" target="_blank" class="image" onmouseover="show('text1')" onmouseout="hide('text1')">
<img src="https://i.vimeocdn.com/portrait/8070603_300x300" class="project" alt="print-screen"/>
<div class="text1">AAA</div>
</a>
</div>
</div>
<div class="col-md-6 col-sm-12">
<div class="tumb-wrapper">
<a href="http://www.cnn.com" target="_blank" class="image" onmouseover="show('text2')" onmouseout="hide('text2')">
<img src="https://lh6.ggpht.com/mSKQgjFfPzrjqrG_d33TQZsDecOoVRF-jPKaMDoGIpMLLT1Q09ABicrXdQH6AZpLERY=w300" class="project" alt="print-screen"/>
<div class="text2">BBB</div>
</a>
</div>
</div>
</div>

Here is a version of it that's totally javascript free, just using CSS. I'm going to edit this soon with a slight javascript addition (this current version requires you to have a fixed size).
.caption {
height: 250px;
width: 355px;
overflow: hidden;
}
.caption-image {
height: 100%;
}
.caption-text {
color: white;
padding: 10px;
background: rgba(0, 0, 0, 0.4);
transition: transform 400ms ease;
}
.caption-image:hover + .caption-text,
.caption-text:hover {
transform: translateY(-100%);
}
<div class="caption">
<img class="caption-image" src="http://faron.eu/wp-content/uploads/2013/05/Cheese.jpg" />
<div class="caption-text">Some words about how cheesy it is to use a picture of cheese for this example!</div>
</div>
<div class="caption">
<img class="caption-image" src="https://top5ofanything.com/uploads/2015/05/Tomatoes.jpg" />
<div class="caption-text">There's nothing witty to say about a tomato, maybe some you say I say stuff. But honstly I can't think of anything...</div>
</div>
Version with JS sizing:
Basically the same idea, but when the page is loading it sets certain styles so the images can be what ever size you like.
var captionSel = document.querySelectorAll('.caption');
for (let i = 0; i < captionSel.length; i++) {
let image = captionSel[i].querySelector(":scope > .caption-image");
let text = captionSel[i].querySelector(":scope > .caption-text");
text.style.width = image.clientWidth - 20 + "px";
captionSel[i].style.height = image.clientHeight + "px";
}
.caption {
overflow: hidden;
}
.caption-text {
color: white;
padding: 10px;
background: rgba(0, 0, 0, 0.4);
transition: transform 400ms ease;
}
.caption-image:hover + .caption-text,
.caption-text:hover {
transform: translateY(-100%);
}
<div class="caption">
<img class="caption-image" src="http://faron.eu/wp-content/uploads/2013/05/Cheese.jpg" />
<div class="caption-text">Some words about how cheesy it is to use a picture of cheese for this example!</div>
</div>
<div class="caption">
<img class="caption-image" src="https://top5ofanything.com/uploads/2015/05/Tomatoes.jpg" />
<div class="caption-text">There's nothing witty to say about a tomato, maybe some you say I say stuff. But honstly I can't think of anything...</div>
</div>

I'll give it to you even better: No javascript at all!
This is possible with pure CSS:
.tumb-wrapper {
position: relative;
overflow: hidden;
}
.text {
text-align: center;
background-color: grey;
width: 100%;
height: 10%;
font-size: 20px;
color: white;
opacity: 0.7;
display: block;
position: absolute;
bottom: -30px;
transition: 300ms;
left: 0;
}
.tumb-wrapper:hover .text {
bottom: 28px;
}
<div class="row">
<div class="col-md-6 col-sm-12">
<div class="tumb-wrapper">
<a href="http://www.bbc.com" target="_blank" class="image">
<img src="https://i.vimeocdn.com/portrait/8070603_300x300" class="project" alt="print-screen"/>
<div class="text">AAA</div>
</a>
</div>
</div>
<div class="col-md-6 col-sm-12">
<div class="tumb-wrapper">
<a href="http://www.cnn.com" target="_blank" class="image">
<img src="https://lh6.ggpht.com/mSKQgjFfPzrjqrG_d33TQZsDecOoVRF-jPKaMDoGIpMLLT1Q09ABicrXdQH6AZpLERY=w300" class="project" alt="print-screen"/>
<div class="text">BBB</div>
</a>
</div>
</div>
</div>
The transition css property animates whatever change you make. This way, when you hover over the .tumb-wrapper div, the .text div will slide up.
You should note however, that ancient IE versions won't be able to use this

I usually do this with only CSS.
Just save the first and second image right next to each other on one file... then you use css to change the position of the background image. To make things nicer i add a css-animation to the movement of the background image.
Example of my code:
<div id="thumb_Wrapper">
<div class="_Thumb">
<img src="images/Thumb.jpg" class="Animate_left">
</div>
</div>
The CSS
#_Container{position:absolute; bottom -60px; right:2px; width:626px; height:100px;}
._Thumb{position:relative; margin-right:4px; width:100px; height:80px; display:block; float:left; background:#EFEFEF; overflow:hidden;}
._Thumb > img{position:absolute; left:0; height:100%; background-size:cover; background-position:center;}
._Thumb > img:hover{left:-18px; cursor:pointer;}
CSS Animation
.Animate_left{transition:left .3s;}
Now all you have to do is swap out the image.
onHover - the image in the thumbnail will smoothly slide to the left; revealing the rest of the image/ showing the other image.
You can set how far to the left(or right) you want the thumb-image to first appear by adjusting the value of 'left' in the ._Thumb class.
You can set how far the image slides on hover by adjusting the img:hover{left:-18px} to what ever you like; instead of 18px.

Related

CSS flip not aligned when parent has zero width

Given two rows of cards, I'm trying to combine the following animations:
Move the first card on the first row over the second card on the second row.
This is done by changing the top and left style properties.
Flip the first card on the first row.
I'm flipping the card based on this w3schools example.
Move the second card on the first row to the left.
The card is moved to the left by giving the div next to it zero width.
Animation 3) seems to conflict with animation 2).
Normally, a 'flip' involves swapping the front facing div with the back facing div.
However, when animation 3) gives the parent div zero width, the front and back are no longer aligned and both sides can be seen.
The following snippet demonstrates that a 'flip' seems to work, while 'move and flip' goes wrong.
Can you help me fix this such that all animations work correctly together?
function flipCard() {
const flipCard = document.querySelector('.top .flip-card')
const rect = flipCard.getBoundingClientRect()
flipCard.classList.add('moving')
flipCard.classList.add('flipped')
return [flipCard, rect]
}
function moveFlipCard() {
const srcSleeve = document.querySelector('.top .sleeve')
srcSleeve.classList.add('closed')
const [srcFlipCard, srcRect] = flipCard()
const targetFlipCard = document.querySelectorAll('.bottom .sleeve')[1]
const targetRect = targetFlipCard.getBoundingClientRect()
const offset = {
top: targetRect.top - srcRect.top,
left: targetRect.left - srcRect.left,
}
srcFlipCard.style.top = offset.top + 'px'
srcFlipCard.style.left = offset.left + 'px'
}
const flipButton = document.getElementById('flipCard')
flipButton.addEventListener('click', flipCard)
const moveFlipButton = document.getElementById('moveFlipCard')
moveFlipButton.addEventListener('click', moveFlipCard)
* {
font-family: sans-serif;
font-size: 24px;
}
.cards {
display: flex;
position: relative;
}
.sleeve {
position: relative;
width: 60px;
height: 76px;
transition: width 1s;
}
.sleeve.closed {
width: 0;
}
.card {
position: relative;
width: 50px;
height: 70px;
border: 3px solid black;
border-radius: 5px;
display: flex;
text-align: center;
align-items: center;
justify-content: center;
font-size: 24px;
margin: 0 2px;
transition: top 1s, left 1s;
}
.card.closed {
background-color: rgb(125, 171, 250);
color: black;
}
.card.open {
background-color: rgb(218, 218, 218);
}
.card.black {
color: black;
}
.card.red {
color: red;
}
/* Based on https://www.w3schools.com/howto/howto_css_flip_card.asp */
.flip-card {
position: relative;
perspective: 1000px;
transition: top 1s, left 1s;
}
.flip-card-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 1s;
transform-style: preserve-3d;
}
.flip-card.flipped .flip-card-inner {
transform: rotateY(180deg);
}
.flip-card-front,
.flip-card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.flip-card-back {
transform: rotateY(180deg);
}
.flip-card.moving {
z-index: 1;
}
<div id="app">
<div class="top cards">
<div class="sleeve">
<div class="flip-card" style="top: 0; left: 0;">
<div class="flip-card-inner">
<div class="flip-card-front">
<div class="card open black">A♣</div>
</div>
<div class="flip-card-back">
<div class="card closed">?</div>
</div>
</div>
</div>
</div>
<div class="sleeve">
<div class="flip-card" style="top: 0; left: 0;">
<div class="flip-card-inner">
<div class="flip-card-front">
<div class="card open black">2♣</div>
</div>
<div class="flip-card-back">
<div class="card closed">?</div>
</div>
</div>
</div>
</div>
</div>
<div class="bottom cards">
<div class="sleeve">
<div class="flip-card">
<div class="flip-card-inner">
<div class="flip-card-front">
<div class="card open red">5♥</div>
</div>
<div class="flip-card-back">
<div class="card closed">?</div>
</div>
</div>
</div>
</div>
<div class="sleeve">
<div class="flip-card">
<div class="flip-card-inner">
<div class="flip-card-front">
<div class="card open red">6♥</div>
</div>
<div class="flip-card-back">
<div class="card closed">?</div>
</div>
</div>
</div>
</div>
</div>
<button id="flipCard">flip</button>
<button id="moveFlipCard">move and flip</button>
</div>
TLDR: To solve this, I explicitly set transform-origin: 30px 0 0. Now the point around which a transformation is applied no longer depends on the size of the bounding box.
I now see where it goes wrong. The problem lies with the transform-origin.
The transform origin is the point around which a transformation is applied.
For animation 2) this corresponds to the point around which the card is rotated 180 degrees over the y-axis (transform: rotateY(180deg)).
The default value of the transform-origin property is 50% 50% 0, where the values correspond to the offset over the x-axis, y-axis and z-axis, respectively.
However, what does 50% mean? 50% of what?
Percentages refer to the size of bounding box
So, what's the bounding box of the flipped div? When I inspect <div class="flip-card-inner"> I see it has a dimensions 60x0:
where 60 corresponds to width: 60px of parent <div class="sleeve">.
So for <div class="flip-card-inner"> the default transform-origin is 30px 0 0. This is what I expect: the card rotates over its y-axis at a point that lies halfway over the x-axis, such that the card is in the same location when flipped.
Now let's see what happens when we apply animation 3), i.e. move the second card on the first row to the left by giving the div next to it zero width:
Now the bounding box is 0x0, because the parent <div class="sleeve closed"> has zero width. Since the bounding box has changed, so has the transform-origin: 50% of 0 is 0, so we get 0 0 0. The card now rotates over its y-axis at a point that lies on the left side of the card. This has the undesired effect that the flipped card does not end up at the same location as where it started.
To solve this, I explicitly set transform-origin: 30px 0 0. Now the point around which a transformation is applied no longer depends on the size of the bounding box.
Working example:
function flipCard() {
const flipCard = document.querySelector('.top .flip-card')
const rect = flipCard.getBoundingClientRect()
flipCard.classList.add('moving')
flipCard.classList.add('flipped')
return [flipCard, rect]
}
function moveFlipCard() {
const srcSleeve = document.querySelector('.top .sleeve')
srcSleeve.classList.add('closed')
const [srcFlipCard, srcRect] = flipCard()
const targetFlipCard = document.querySelectorAll('.bottom .sleeve')[1]
const targetRect = targetFlipCard.getBoundingClientRect()
const offset = {
top: targetRect.top - srcRect.top,
left: targetRect.left - srcRect.left,
}
srcFlipCard.style.top = offset.top + 'px'
srcFlipCard.style.left = offset.left + 'px'
}
const flipButton = document.getElementById('flipCard')
flipButton.addEventListener('click', flipCard)
const moveFlipButton = document.getElementById('moveFlipCard')
moveFlipButton.addEventListener('click', moveFlipCard)
* {
font-family: sans-serif;
font-size: 24px;
}
.cards {
display: flex;
position: relative;
}
.sleeve {
position: relative;
width: 60px;
height: 76px;
transition: width 1s;
}
.sleeve.closed {
width: 0;
}
.card {
position: relative;
width: 50px;
height: 70px;
border: 3px solid black;
border-radius: 5px;
display: flex;
text-align: center;
align-items: center;
justify-content: center;
font-size: 24px;
margin: 0 2px;
transition: top 1s, left 1s;
}
.card.closed {
background-color: rgb(125, 171, 250);
color: black;
}
.card.open {
background-color: rgb(218, 218, 218);
}
.card.black {
color: black;
}
.card.red {
color: red;
}
/* Based on https://www.w3schools.com/howto/howto_css_flip_card.asp */
.flip-card {
position: relative;
perspective: 1000px;
transition: top 1s, left 1s;
}
.flip-card-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 1s;
transform-style: preserve-3d;
}
.flip-card.flipped .flip-card-inner {
transform-origin: 30px 0 0;
transform: rotateY(180deg);
}
.flip-card-front,
.flip-card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.flip-card-back {
transform-origin: 30px 0 0;
transform: rotateY(180deg);
}
.flip-card.moving {
z-index: 1;
}
<div id="app">
<div class="top cards">
<div class="sleeve">
<div class="flip-card" style="top: 0; left: 0;">
<div class="flip-card-inner">
<div class="flip-card-front">
<div class="card open black">A♣</div>
</div>
<div class="flip-card-back">
<div class="card closed">?</div>
</div>
</div>
</div>
</div>
<div class="sleeve">
<div class="flip-card" style="top: 0; left: 0;">
<div class="flip-card-inner">
<div class="flip-card-front">
<div class="card open black">2♣</div>
</div>
<div class="flip-card-back">
<div class="card closed">?</div>
</div>
</div>
</div>
</div>
</div>
<div class="bottom cards">
<div class="sleeve">
<div class="flip-card">
<div class="flip-card-inner">
<div class="flip-card-front">
<div class="card open red">5♥</div>
</div>
<div class="flip-card-back">
<div class="card closed">?</div>
</div>
</div>
</div>
</div>
<div class="sleeve">
<div class="flip-card">
<div class="flip-card-inner">
<div class="flip-card-front">
<div class="card open red">6♥</div>
</div>
<div class="flip-card-back">
<div class="card closed">?</div>
</div>
</div>
</div>
</div>
</div>
<button id="flipCard">flip</button>
<button id="moveFlipCard">move and flip</button>
</div>

Is it possible to reserve the direction of the card-reveal on Materializecss?

I'm looking at the card-reveal component of the materializecss framework shown here: https://codepen.io/JP_juniordeveloperaki/pen/YXRyvZ the official doc is here: http://next.materializecss.com/cards.html
For my application, I have moved the <div class="card-content"> to the top to look like this: https://codepen.io/anon/pen/YaqYOj
So I was wondering whether or not it was possible to make the card-reveal animation go from top to bottom, like the top card-content is a curtain that pulls down to reveal more information.
Thanks
You can achieve this by changing transform property of this element .card .card-reveal {}.
And i add extra class to change the transform property make the top card-content is a curtain that pulls down to reveal more information*
Here is the working code
Note: Also add display: block to .card .card-image img fix the bottom gap in your demo.
$('.card-content').click(()=>{
$('.card-reveal').addClass('card-closing');
});
$('.card-reveal .card-title-custom').click(()=>{
$('.card-reveal').removeClass('card-closing');
});
.main {
width: 450px;
margin: 30px;
}
.card .card-image img {
border-radius: 2px 2px 0 0;
position: relative;
left: 0;
right: 0;
top: 0;
bottom: 0;
width: 100%;
display: block;
}
.card .card-reveal {
padding: 20px;
position: absolute;
background-color: #fff;
width: 100%;
overflow-y: auto;
top: 100%;
height: 100%;
z-index: 1;
display: block !important;
transform: translateY(-200%) !important;
transition: transform .6s;
will-change: opacity, transform;
}
.card .card-reveal.card-closing {
transform: translateY(-100%) !important;
display: block !important;
}
.grey-text.text-darken-4 {
display: block;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-alpha.4/css/materialize.min.css">
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-alpha.4/js/materialize.min.js"></script>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<div class="main">
<div class="card">
<div class="card-content">
<span class="card-title activator grey-text text-darken-4">Card Title<i class="material-icons right">more_vert</i></span>
<p>This is a link</p>
</div>
<div class="card-image waves-effect waves-block waves-light">
<img class="activator-custom" src="http://materializecss.com/images/office.jpg">
</div>
<div class="card-reveal">
<span class="card-title-custom grey-text text-darken-4">Card Title<i class="material-icons right">close</i></span>
<p>Here is some more information about this product that is only revealed once clicked on.</p>
</div>
</div>
</div>
Here is the working codepen

How can I implement this horizontal search result bar?

I essentially have a horizontal div that populates content from omdb API. It dynamically generates a bunch of search results, and displays them all; however the overflow: hidden is active.
I have 2 questions:
I have two custom "buttons" that I made with an empty div and icon. I gave it a bit of a box-shadow to give it the illusion that it's hovering. Is it better practice to use a button element instead, or does it matter?
My main question is this: I want to be able to navigate back and forth between my search results using my arrow buttons. What would be the best way to implement this? The only thing I can think of is using the buttons to adjust the left or right margins of my search results. (ie. pressing the left button would adjust the margin-left of my results with a negative margin, and the right arrow would adjust it with a positive margin)
However, this feels crude and not very accurate. Meaning with a few extra clicks, the content could be pushed out of the view entirely (either by accident or on purpose).
Is there a way to set this up more efficiently?
Here is some code as an example:
const leftArrow = document.querySelector("#left-arrow");
const rightArrow = document.querySelector("#right-arrow");
const marginSelector = document.querySelector("#nav-margin");
var marginValue = -20;
leftArrow.addEventListener('click', () => {
marginSelector.style.marginLeft = marginValue + "px";
marginValue += -20;
});
.scrollbar-container {
width: 800px;
display: flex;
border: 1px #5e9af9 solid;
position: relative;
top: 100px;
overflow: hidden;
margin: auto;
align-items: center;
}
.result-container {
display: inline-block;
margin: 2px;
}
img {
display: inline-block;
vertical-align: middle;
position: relative;
}
.nav-button {
position: absolute;
width: 50px;
height: 50px;
background: rgba(230, 232, 237, .5);
text-align: center;
margin: auto 0;
}
.left-arrow {
left: 1%;
}
.right-arrow {
right: 1%;
}
.margin-start {}
<script src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script>
<div class="scrollbar-container">
<div id="nav-margin" class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div id="left-arrow" class="nav-button left-arrow">
<i class="fas fa-angle-left fa-3x"></i>
</div>
<div id="left-arrow" class="nav-button right-arrow">
<i class="fas fa-angle-right fa-3x"></i>
</div>
</div>
I've written script to move back and forth the search results. You just need to check and adjust the marginLeft value for your marginSelector. I've added transition into the CSS of #nav-margin so that it looks smooth. marginValue is been initialized with 0. max-width of container has been set to 500px for convenience. When you change your max-width do not forget to change it in addEventListener for rightArrow. You can also make the value inside if condition to dynamic so that it actually takes the value from .scrollbar-container.
Let me know if you have any queries.
const leftArrow = document.querySelector("#left-arrow");
const rightArrow = document.querySelector("#right-arrow");
const marginSelector = document.querySelector("#nav-margin");
var marginRightValue = 0;
rightArrow.addEventListener('click', () => {
if(-(marginRightValue) <= (500+20))
marginRightValue += -100;
marginSelector.style.marginLeft = marginRightValue + "px";
});
leftArrow.addEventListener('click', () => {
if(marginRightValue < 0)
marginRightValue += 100;
marginSelector.style.marginLeft = marginRightValue + "px";
});
.scrollbar-container {
max-width: 500px;
display: flex;
border: 1px #5e9af9 solid;
position: relative;
top: 100px;
overflow: hidden;
margin: auto;
align-items: center;
}
#nav-margin{
transition: all 1s;
}
.result-container {
display: inline-block;
margin: 2px;
}
img {
display: inline-block;
vertical-align: middle;
position: relative;
}
.nav-button {
position: absolute;
width: 50px;
height: 50px;
background: rgba(230, 232, 237, .5);
text-align: center;
margin: auto 0;
cursor: pointer;
}
.left-arrow {
left: 1%;
}
.right-arrow {
right: 1%;
}
.margin-start {}
<script src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script>
<div class="scrollbar-container">
<div id="nav-margin" class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div id="left-arrow" class="nav-button left-arrow">
<i class="fas fa-angle-left fa-3x"></i>
</div>
<div id="right-arrow" class="nav-button right-arrow">
<i class="fas fa-angle-right fa-3x"></i>
</div>
</div>
I'm not entirely sure if this would be the best response, but:
Point 1 - I don't think it matters here. A <button> is meant for a form, from a semantics point of view. For more context, read: https://css-tricks.com/use-button-element/
Point 2 - I can already scroll/swipe from left to right (in your code demo when I run the snippet), using my mouse/trackpad. So having extra buttons to do that job seems unnecessary. I would think rather to make a Javascript carousel (or slider) like effect when clicking the right button takes me to the next "slide", or the next chunk of your results. You could then disable buttons when there is no more content on the right (or left), or have them cycle back to the beginning. Effectively you want to think of a fixed width "slide" window (responsive for different viewports) and "slide" accordingly. Does that make sense for your problem?

collapse row on click

I'm working on this code but I have difficulties implementing properly. I wan to place the arrow in front of the question and synchronize the click event with the text.
jsfiddle.net/tx8paL7L/5/
Can you help me to fix the issue?
HTML:
<div class="container faq_wrapper">
<div class="row">
<div class="span10 offset1">
<p>
</p>
<div class="faq-all-actions">
<a class="faq-expand">Expand All</a> | <a class="faq-collapse">Collapse All</a></div>
</div>
</div>
<div class="row">
<div class="span10 offset1">
<div class="question-wrapper">
<div class="arrows">
</div>
<div class="big-q">
Q</div>
<div class="question">
<div class="arrow"></div><h6>Can I try the software before I buy it?</h6></div>
<div class="answer-wrapper">
<div class="big-a">
A</div>
<div class="answer">
Yes! Simply download a free trial and you'll have instant access to all features for 30 days, absolutely free. We don't require your credit card details or any commitment.</div>
</div>
</div>
</div>
</div>
</div>
CSS:
.answer-wrapper {
display: none;
}
.arrow {
margin: 1em;
}
.arrow::before {
position: absolute;
content: '';
width: 0;
height: 0;
border: .5em solid transparent;
border-left-color: gray;
transform-origin: 0 50%;
transition: transform .25s;
}
.arrow.down::before {
transform: rotate(90deg);
transition: transform .25s;
}
JavaScript:
$(document)
.on('click','.row',function(){
$(this).find('.answer-wrapper').slideToggle();
})
.on('click','.faq-expand',function(){
$('.answer-wrapper').slideDown();
})
.on('click','.faq-collapse',function(){
$('.answer-wrapper').slideUp();
})
var arr = document.querySelector('.arrow');
arr.addEventListener('click', function(event) {
event.target.classList.toggle('down');
});
;
Here is a working fiddle with your javascript, the css still needs a bit of work:
JSFiddle
Basically you were using the wrong selectors for your jQuery.
HTML:
<div class="container faq_wrapper">
<div class="row">
<div class="span10 offset1">
<p>
</p>
<div class="faq-all-actions">
<a class="faq-expand">Expand All</a> | <a class="faq-collapse">Collapse All</a></div>
</div>
</div>
<div class="row">
<div class="span10 offset1">
<div class="question-wrapper">
<div class="arrows">
</div>
<div class="big-q">
Q</div>
<div class="question">
<div class="arrow"></div><h6>Can I try the software before I buy it?</h6></div>
<div class="answer-wrapper">
<div class="big-a">
A</div>
<div class="answer">
Yes! Simply download a free trial and you'll have instant access to all features for 30 days, absolutely free. We don't require your credit card details or any commitment.</div>
</div>
</div>
</div>
</div>
</div>
jQuery:
$(document).ready(function() {
.on('click','.row .question-wrapper',function(){
$(this).find('.answer-wrapper').slideToggle();
$('.arrow').toggleClass('down');
})
.on('click','.faq-expand',function(){
$('.answer-wrapper').slideDown();
$('.arrow').addClass('down');
})
.on('click','.faq-collapse',function(){
$('.answer-wrapper').slideUp();
$('.arrow').removeClass('down');
})
});
you've added position:absolute but done nothing to position the arrow .
add the following styles :
.arrow {
position:relative; // you need to add position relative
margin: 1em;
padding-left:10px;
}
.arrow::before {
position: absolute;
left:100%; // define where you would like the arrow to be placed .
content: '';
width: 0;
height: 0;
border: .5em solid transparent;
border-left-color: gray;
transform-origin: 0 50%;
transition: transform .25s;
}
use position relative and left for perfectly positioning your arrow .
FIDDLE HERE
To put arrow in front of the question you can use right 0 like this:
.arrow::before {
position: absolute;
right: 0;
content: '';
width: 0;
height: 0;
border: .5em solid transparent;
border-left-color: gray;
transform-origin: 0 50%;
transition: transform .25s;
}
When you are layout an element on position absolute, you can "fix" the element relative to the parent if you want (top, bottom, right, left).
Add "left: 190px" to ".arrow::before"
.arrow::before {
position: absolute;
content: '';
width: 0;
height: 0;
border: .5em solid transparent;
border-left-color: gray;
transform-origin: 0 50%;
transition: transform .25s;
left: 190px;
}

Slideshow using background images with navigation and captions

I have a div which currently has a static background image, and I need to create a slideshow of background images and text for this div. I would like to fade the background images and the caption text in and out. Does anyone know of a good way to do this using jQuery? My knowledge of JavaScript and jQuery is very limited. I tried to use some ready-made plugins as the Backstretch, Responsiveslides but I could not understand them enough and edit them for my use.
Here is my current code: http://jsfiddle.net/1zdyh3wo/
HTML
<div class="content bg-slider">
<div class="wrapper">
<h1 class="sectionTitle">Image title 1</h1>
<div class="separator white"></div>
<h2 class="sectionDescription">This is the description of the first image. Wanna know more? Click here.</h2>
<div class="nav-wrapper">
<div class="nav-arrows prev"></div>
<div class="nav-dots">
<div class="current"></div>
<div class=""></div>
<div class=""></div>
</div>
<div class="nav-arrows next"></div>
</div>
</div>
CSS:
#import url(http://fonts.googleapis.com/css?family=Montserrat:400,700);
/* -- COMMON -- */
body {
font: 400 14px 'Montserrat', Helvetica, sans-serif;
letter-spacing: 2px;
text-transform: uppercase;
color: white;
}
.separator {
width: 24px;
height: 4px;
}
.separator.white {
background-color: white;
}
.separator.black {
background-color: black;
}
/* -- MENU -- */
/* -- CANVAS -- */
.content {
position: absolute;
z-index: 0;
top: 0;
right: 0;
bottom: 0;
left: 0;
overflow: hidden;
width: 100%;
height: 100%;
}
.wrapper {
position: absolute;
right: 0;
bottom: 100px;
left: 0;
width: 33.333333333%;
margin: 0 auto;
}
.sectionTitle {
font: 700 32px/24px 'Montserrat', Helvetica, sans-serif;
line-height: 24px;
margin-bottom: 24px;
letter-spacing: 4px;
}
.sectionDescription {
font: 400 14px/18px 'Montserrat', Helvetica, sans-serif;
margin-top: 24px;
}
/* -- SLIDER -- */
.bg-slider {
background: url(../img/slides/image1.jpg) no-repeat center center fixed;
background-color: red; /* demo purpose only */
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
/* -- SLIDER - NAVEGATION -- */
.nav-wrapper {
display: inline-block;
min-width: 250px;
margin-top: 24px;
padding: 4px;
}
/* -- SLIDER - NAVEGATION ARROWS -- */
.nav-arrows {
float: left;
width: 20px;
height: 20px;
cursor: pointer;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
border: 4px solid white;
}
.nav-arrows.prev {
border-top: none;
border-right: none;
}
.nav-arrows.next {
border-bottom: none;
border-left: none;
}
/* -- SLIDER - NAVEGATION DOTS -- */
.nav-dots {
margin: 0px 8px;
float: left;
}
.nav-dots div{
float: left;
width: 12px;
height: 12px;
margin: 4px 18px;
cursor: pointer;
border-radius: 50%;
background: rgba(255,255,255,.5);
}
.nav-dots .current:after {
float: left;
width: 12px;
height: 12px;
content: '';
border-radius: 50%;
background: white;
}
Here a visual aid, how I would like the result to be:
Desktop version:
Mobile version:
To keep things really simple:
Make a "wrapper" div for the entire slider
Make an individual "wrapper" div for each individual slide
Put the slider navigation outside of of the individual slides (I put it outside of the slider altogether, but that's your choice based on your desired positioning).
Make a function that will do all the transitions
Here's an example HTML structure, based on yours
<div id="slider">
<div class="content bg-slider active">
<div class="wrapper">
<h1 class="sectionTitle">Image title 1</h1>
<div class="separator white"></div>
<h2 class="sectionDescription">This is the description of the first image. Wanna know more? Click here.</h2>
</div>
</div>
<div class="content bg-slider">
<div class="wrapper">
<h1 class="sectionTitle">Image title 2</h1>
<div class="separator white"></div>
<h2 class="sectionDescription">This is the description of the second image. Wanna know more? Click here.</h2>
</div>
</div>
<div class="content bg-slider">
<div class="wrapper">
<h1 class="sectionTitle">Image title 3</h1>
<div class="separator white"></div>
<h2 class="sectionDescription">This is the description of the third image. Wanna know more? Click here.</h2>
</div>
</div>
</div>
Here's the functional JavaScript, with comments.
$(document).ready(function(){
// Hide all slides, re-show first:
$(".bg-slider").hide()
$(".bg-slider:first-child").show();
// Prev button click
$(".nav-arrows.prev").click(function(){
slidePrev();
})
// Next button click
$(".nav-arrows.next").click(function(){
slideNext();
})
// "Dots" click
$(".nav-dots div").click(function(){
slideTo($(this).index());
})
});
// "Previous" function must conclude if we are at the FIRST slide
function slidePrev() {
if ($("#slider .active").index() == 0) {
slideTo($("#slider .bg-slider").length - 1);
}
else {
slideTo($("#slider .active").index() - 1);
}
}
// "Next" function must conclude if we are at the LAST slide
function slideNext() {
if ($("#slider .active").index() == $("#slider .bg-slider").length - 1) {
slideTo(0);
}
else {
slideTo($("#slider .active").index() + 1);
}
}
// Slide To will be called for every slide change. This makes it easy to change the animation, or do what you want during the transition.
function slideTo(slide) {
$("#slider .active").fadeOut().removeClass("active");
$("#slider .bg-slider").eq(slide).fadeIn().addClass("active");
$(".nav-dots .current").removeClass("current");
$(".nav-dots div").eq(slide).addClass("current");
}
Finally, here's the updated Fiddle to demonstrate: http://jsfiddle.net/1zdyh3wo/1/

Categories

Resources