Reputation: 857
Using slick
, I'm trying to achieve a slider that looks like this:
In the above, the center slide is the default selected when slick
initiates. Then, when an arrow is clicked, the slick-current
class will shift onto a new div and css translate can be used to scale the image.
Here is my current code:
$(function(){
$("#downloadNow__slick").slick({
slidesToShow: 3,
// initialSlide: 2,
centerMode: true,
centerPadding: "53px",
arrows: true,
dots: false,
infinite: true,
cssEase: 'linear',
});
});
.downloadNow {
background: grey;
padding: 60px 0px;
&__wrapper {
position: relative;
}
.downloadNowCard{
background: white;
padding: 100px;
}
.slider {
max-width: 1110px;
margin: 0 auto;
}
.slick-track {
padding-top: 53px;
padding-bottom: 53px;
}
.slick-slide {
text-align: center;
transition: transform 0.3s ease-in-out;
}
.slick-slide.slick-current {
transform: scale(1.35);
position: relative;
z-index: 1;
}
.slick-slide img {
width: 100%;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js" integrity="sha512-XtmMtDEcNz2j7ekrtHvOVR4iwwaD6o/FUJe6+Zq+HgcCsk3kj4uSQQR8weQ2QVj1o0Pk6PwYLohm206ZzNfubg==" crossorigin="anonymous"></script>
<section class="downloadNow">
<div class="downloadNow__wrapper">
<div class="downloadNow__slides" id="downloadNow__slick">
<div class="downloadNowCard">Card 1</div>
<div class="downloadNowCard">Card 2</div>
<div class="downloadNowCard">Card 3</div>
</div>
</div>
</section>
Current issues:
flex
on wrapper not playing nicely)initialSlide: 2
, the slider breaks. I'm trying to get the center slide as the active slide with this.Upvotes: 4
Views: 8705
Reputation: 1872
For a smooth 3D Effect you need to play with shadows, by increasing/decreasing the shadow you get a visual illusion of a popping out/in box, for the animation effects play with css transition
use only transform
for better performance.
You don't need external libraries to achieve this, the example below is a pure HTML
/CSS
/Javascript
slider.
Edit: add some explanatory comments to the example.
// Button click events
const buttons = document.querySelectorAll('b')
buttons.forEach((button, i) =>
button.onclick = () => slide(i)
)
// Slide function
function slide(right) {
// Get the SLider elements
const container = document.querySelector('div');
const slider = document.querySelector('ul');
const items = document.querySelectorAll('li');
const featured = document.querySelector('.featured');
// Get the featured item
const featuredIndex = [...items].indexOf(featured);
// Set the move if not right then left
const move = right ? 1 : -1;
// Check the slider limits
// if right and index 0: do nothing
// if left and last item: do nothing
if((!right && !featuredIndex)
|| (right && featuredIndex === items.length -1))
return;
// Get the next item element
const nextIndex = featuredIndex + move;
const nextItem = items[nextIndex]
// Remove "featured" class from last item
featured.classList.remove("featured");
// Add "featured" class the next item
nextItem.classList.add("featured");
// Get the container size
const { width: containerSize } = container.getBoundingClientRect();
// Get the next item size and position
const itemSize = containerSize / 3; // Display only 3 items
const itemPosition = itemSize * (nextIndex + 1); // Current position
// Compute the slider next position
const position = containerSize - itemPosition - itemSize;
// Move the slider on its X axis using css transform and transitionX
slider.style.transform = `translateX(${position}px)`
}
body{
background: #ddd;
}
/* Some csss reboot */
ul, li{
margin: 0;
padding: 0;
list-style-type: none;
}
/* Container */
div {
position: relative;
width: 100%;
overflow-x: hidden;
transform: transitionX(0);
}
/* Preview/Next Buttons */
b {
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 0.5em;
width: 20px;
height: 20x;
line-height: 20px;
font-size: 1.2em;
color: #666;
cursor: pointer;
transform: translateY(-50%) scale(1);
transition: transform .1s ease-out;
}
b:last-child {
left: unset;
right: 0.5em;
}
/* Button animation on hover */
b:hover{
transform: translateY(-50%) scale(1.3);
}
/* Slider */
ul {
position: relative;
padding: 2em 0;
display: flex;
width: 100%;
height: 150px;
transform: translateX(0);
transition: transform .3s ease-out;
}
/* Items */
li {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
font-size: 4em;
font-weight: 500;
font-family: arial;
color: #555;
min-width: calc(100% / 3);
background: #fff;
border-radius: .5em;
/* Animation */
transform: translateX(10%) scale(0.5);
box-shadow: 0 2px 2px 0 rgb(0 0 0 / 14%), 0 3px 1px -2px rgb(0 0 0 / 12%), 0 1px 5px 0 rgb(0 0 0 / 20%);
transition: all .3s ease-out;
}
/* Featured Item */
.featured {
z-index: 1;
/* Animation */
transform: scale(1);
box-shadow: 0 16px 24px 2px rgb(0 0 0 / 14%), 0 6px 30px 5px rgb(0 0 0 / 12%), 0 8px 10px -7px rgb(0 0 0 / 20%)
}
.featured + li {
/* Offset the next element under the selected element */
transform: scale(.5) translateX(-25%) !important;
}
<div> <!-- Container -->
<ul> <!-- Slider -->
<li>1</li> <!-- Ithems -->
<li class="featured">2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ul>
<b>ᐸ</b> <!-- Preview button -->
<b>ᐳ</b> <!-- Next button -->
</div>
Upvotes: 2
Reputation: 22880
It took me some time to figure it out because of some strange behavior of the slick slider.
To begin with, the slick slider didn't work with newer versions of jQuery. After a lot of trial and error (and searching through older answers here on SO), I figured out it works only with the older version of jQuery for some strange reason. This is the main reason it didn't work for you too. I used older version of jQuery than you did and it still didn't work. It works with v1.12.3 (it might also work with some newer versions of jQuery, but I didn't test which is the latest compatible version).
To achieve a 3D effect, you can use box-shadow: 0.1vw 0.8vw 1vw rgba(0, 0, 0, 0.35);
. With the current values (i.e. 0.1vw 0.8vw 1vw
), you get a blurry shadow at the bottom and a little bit on the right side. The first value (i.e. 0.1vw
) defines a horizontal offset. The second value (i.e. 0.8vw
) defines a vertical offset. The third value (i.e. 1vw
) defines blur radius so that the shadow is "smooth" (try to remove 1vw
and you'll get the point).
Also, I managed to solve all your issues:
z-index: 100;
to push them to the front).$(document).on('ready', function() {
$('.slider').slick({
dots: true,
centerMode: true,
infinite: true,
centerPadding: '60px',
slidesToShow: 3,
speed: 400
});
});
html {
height: 100%;
overflow-x: hidden;
}
body {
background: #F8F8F8;
height: 100%;
margin: 0;
}
.slider {
width: 90%;
left: 5%;
}
h3 {
background: #fff;
color: #202020;
font-size: 3.5vw;
line-height: 23vh;
margin: 6.5vw;
margin: 6.5vw;
padding: 1vw;
position: relative;
text-align: center;
box-shadow: 0.1vw 0.8vw 1vw rgba(0, 0, 0, 0.35);
}
.slick-center {
transition: 0.2s ease-in-out;
-webkit-transform: scale(1.3);
-moz-transform: scale(1.3);
transform: scale(1.3);
}
.slick-center h3 {
font-size: 4vw;
}
.slick-prev,
.slick-next {
z-index: 100 !important;
}
.slick-prev:before {
transition: 0.2s ease-in-out;
color: #303030 !important;
font-size: 2vw !important;
margin-right: -10vw;
}
.slick-next:before {
transition: 0.2s ease-in-out;
color: #303030 !important;
font-size: 2vw !important;
margin-left: -10vw;
}
.slick-dots li button:before {
transition: 0.2s ease-in-out;
font-size: 0.7vw !important;
}
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title>Document</title>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.12.3/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.js'></script>
<link href='https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css' rel='stylesheet' />
<link href='https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css' rel='stylesheet' />
</head>
<body>
<div class='slider'>
<div>
<h3>1</h3>
</div>
<div>
<h3>2</h3>
</div>
<div>
<h3>3</h3>
</div>
<div>
<h3>4</h3>
</div>
<div>
<h3>5</h3>
</div>
<div>
<h3>6</h3>
</div>
</div>
</body>
</html>
Upvotes: 2