I'm creating a portfolio site that has a filterable infinite wall gallery underneath a hero image that slides off to the right when you click (and slides back on screen with another click). I'm having trouble though, getting this sliding image to work correctly. The photo gallery will be a headache for another day.
There will be a small right arrow button on the left side. To make this slider more obvious I'd like to animate a slight right-left bounce of the image when you hover over this image, then when you click the arrow (or would probably be better to click anywhere on the pic) it slides off screen to the right, revealing this photo gallery underneath. Then you can slide this image back over the gallery with another arrow button on the right.
I found a solution that's most of the way there, using a label input checkbox with a transition property to get it to show as default and animate off screen with the arrow click, but it slides down, not right. It's a little wonky, and I feel like it could be simplified to some degree.
I also tried changing the input from a checkbox to a button and doing animation keyframes, but the animation only played on refresh, and disappears/reappears instantly with no animation with a button click. I may have just targeted the wrong element though.
This is a very rough ideas as to what I'm going for, just thrown together in XD. Final design will be much more pleasant. I forgot the arrow on the second screen, but there'd be one on the right side of the screen to slide that hero image back over the gallery.
If this could be done in just HTML and CSS that'd be great, but if I need to use js or jQuery to do this properly then that's fine.
This is what I have currently that needs some serious work:
<section>
<div >
<h1>PHOTO VIDEO</h1>
<div >
<ul>
<li ><a href="automotive.html">Automotive</a></li>
<li ><a href="video.html">Video</a></li>
<li ><a href="portraits.html">Portraits</a></li>
<li ><a href="landscapes.html">Landscapes</a></li>
</ul>
</div>
<label >
<img src="images/right-arrow.png">
<input type="checkbox" name="">
<div ></div>
</label>
</div>
</section>
.pv-wrapper {
width: 100%;
height: 750px;
position: relative;
border-left: 100px solid orange;
color: rgba(0, 0, 0, 0.5);
font-size: small;
display: inline-block;
}
.pv-wrapper h1 {
font-size: 50px;
color: white;
text-transform: uppercase;
letter-spacing: 3px;
position: absolute;
bottom: 225px;
left: -40px;
margin-left: -30px;
-webkit-transform: rotate(270deg);
-moz-transform: rotate(270deg);
-ms-transform: rotate(270deg);
-o-transform: rotate(270deg);
transform: rotate(270deg);
-webkit-transform-origin: 0 0;
-moz-transform-origin: 0 0;
-ms-transform-origin: 0 0;
-o-transform-origin: 0 0;
transform-origin: 0 0;
}
.btn-container ul {
display: inline-block;
padding: 50px 0 0 50px;
font-family: 'Poppins-Light';
font-size: 40px;
line-height: 120%;
}
.btn-container ul li a {
text-decoration: none;
color: black;
}
.btn-container ul li a:hover {
color: #68C8E5;
transition: 0.4s ease;
}
.slider {
margin-left: -20px;
}
.arrow {
width: 20px;
margin-top: 90px;
}
.slider > input {
display: none;
}
.slider > input:not(:checked) ~ .photo-slider {
top: 100px !important;
}
.photo-slider {
position: fixed;
height: 750px;
width: 100%;
top: 100%;
left: 100px;
background: url(../images/rs3-bg.jpg);
background-size: cover;
background-position: 75% 50%;
transition: 0.6s;
}
[1]: https://i.stack.imgur.com/nob93.jpg
CodePudding user response:
The reason you need a checkbox rather than a button is because pure CSS doesn't record state. So even though you can make a button play an animation on click, you can't set it as "clicked" so that you can then "unclick" it.
In .slider > input:not(:checked) ~ . photo-slider
you're saying "when this is not clicked, be 100px from the top. .photo-slider
is less specific, so there you're saying "when the above rule doesn't apply, be 100% from the top (off the bottom of the screen". All the other attributes aren't specified in the above rule, so they'll always be applied.
To make it slide off to the right, you just need to play with where and how you list those properties. I don't know exactly how you want to position it within the rest of your page, but I think this should get you most of the way there:
.slider > input:not(:checked) ~ .photo-slider {
left: 0px; /* This will put it hard left when unchecked, you also don't need !important, as this rule is more specific than the one below.*/
}
.photo-slider {
position: fixed;
height: 750px;
width: 100%;
top: 100px;
left: calc(100% - 20px); /* this will leave 20px sticking out from the right side of the screen */
background: url(../images/rs3-bg.jpg);
background-size: cover;
background-position: 75% 50%;
transition: 0.6s;
}
You can probably also change this:
<label >
<img src="images/right-arrow.png">
<input type="checkbox" name="">
<div ></div>
</label>
To this:
<label >
<input type="checkbox" name="">
<div >
<img src="images/right-arrow.png">
</div>
</label>
Which will keep the arrow on top of your hero image. You'll have to figure out the CSS to position it yourself, but then you could do this to change the direction of the arrow:
.slider > input:not(:checked) ~ .photo-slider .arrow {
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
}
As for making it bounce on hover, this explains perfectly. Your CSS rule would be .photo-slider:hover
.
CodePudding user response:
Got it to work thanks to @MonsterBasket! Had to make a couple slight changes but this is what worked, including the bounce on hover:
.slider {
margin-left: -20px;
cursor: pointer;
display: inline-block;
}
.photo-slider {
position: fixed;
animation-duration: 1s;
animation-fill-mode: both;
animation-timing-function: ease-in-out;
animation-iteration-count: 1;
animation-delay: 0.5s;
}
.photo-slider:hover {
animation-name: bounce;
}
@keyframes bounce {
0%, 100%, 20%, 50%, 80% {
transform: translateX(0)
}
40% {
transform: translateX(30px)
}
60% {
transform: translateX(15px)
}
}
.slider > input {
display: none;
}
.slider > input:not(:checked) ~ .photo-slider {
top: 100px;
}
.slider > input:checked ~ .photo-slider {
left: calc(100% - 60px);
top: 100px;
}
.arrow {
width: 60px;
margin-top: 345px;
}
.slider > input:not(:checked) ~ .photo-slider .arrow {
transform: rotate(-360deg);
transition: 1s;
}
.slider > input:checked ~ .photo-slider .arrow {
transform: rotate(-180deg);
transition: 1s;
}
.photo-slider {
position: fixed;
height: 750px;
width: 100%;
top: 100%;
left: 100px;
background: url(../images/rs3-bg.jpg);
background-size: cover;
background-position: 75% 50%;
transition: 0.6s;
}