Vertically align Slick carousel navigation arrows with slide image and not the text beneath it
Asked Answered
H

6

9

I need to vertically align the navigation arrows with the slide image no matter what the window width is. Currently, it's putting it at 50% of the entire slide. I'm hoping to be able to do this with CSS, but seems like it may need to be done with JavaScript. If that's the case, jQuery is okay and it just needs to support modern browsers (IE 11+).

The tricky part about this is that it needs to be at 50% of the image and not the entire container, since the text beneath the image can have various heights.

What it's currently doing:

enter image description here

What I need it to do: (note the nav arrows are vertically centered with the image and should be no matter what window width)

enter image description here

Here's a JSFiddle: https://jsfiddle.net/thebluehorse/2wuq3feb/5/

<div class="container">
  <div class="list clearfix">
    <div class="slide">
      <img src="http://placehold.it/800x350">

      <ul>
        <li>Ut in integer pulvinar maiores, mi sapien litora nunc ut, neque netus in ac. Et nullam, donec sapien laoreet, ullamcorper vestibulum et sed at arcu, erat scelerisque vehicula justo nam malesuada vehicula, per nibh nibh elit justo. Tempus omnis, mattis taciti cras a.</li>
      </ul>
    </div>

    <div class="slide">
      <img src="http://placehold.it/800x350">
      <ul>
        <li>Lorem ipsum dolor sit amet, et hymenaeos elit orci, rutrum dolor magna pellentesque ante euismod magna, sodales turpis quos class condimentum. Integer in vel etiam. Etiam pellentesque nibh phasellus sed, eget ipsum enim sed in et at, non ligula quis egestas sed quis. Lectus vitae, lobortis vestibulum maecenas auctor lorem eros, luctus vitae aliquam aliquam ipsum ligula nascetur, habitasse eu lectus imperdiet leo. Ut est fusce class conubia nunc felis, proin aliquam vitae nunc accumsan orci. A eu erat in.</li>
        <li>Ut in integer pulvinar maiores, mi sapien litora nunc ut, neque netus in ac. Et nullam, donec sapien laoreet, ullamcorper vestibulum et sed at arcu, erat scelerisque vehicula justo nam malesuada vehicula, per nibh nibh elit justo. Tempus omnis, mattis taciti cras a.</li>
      </ul>
    </div>

<div class="slide">
      <img src="http://placehold.it/800x350">
      <ul>
        <li>Ut in integer pulvinar maiores, mi sapien litora nunc ut, neque netus in ac. Et nullam, donec sapien laoreet, ullamcorper vestibulum et sed at arcu, erat scelerisque vehicula justo nam malesuada vehicula, per nibh nibh elit justo. Tempus omnis, mattis taciti cras a.</li>
      </ul>
    </div>
  </div>
</div>

<style>
.container {
  position: relative;
  width: 80%;
  margin: auto;
}

.slide {
  float: left;
  height: 100%;
  min-height: 1px;
}

img {
  width: 100%;
  display: block;
}

.clearfix:after {
  content: "";
  display: table;
  clear: both;
}

body {
  background-color: #aaa;
}
</style>

<script>
$('.list').slick({
  dots: true,
  infinite: true,
  speed: 300,
  slidesToShow: 1,
  adaptiveHeight: true
});
</script>
Hark answered 19/2, 2016 at 17:0 Comment(0)
L
4

Well, what about using 2 carousels? One for the images, with arrows on, and another for flowing content without arrows. It's the cleanest solution I could think of: https://jsfiddle.net/mq9avx5g/2/

It makes use of slick's asNavFor to make both carousels act as one:

$('#list_above').slick({
  infinite: true,
  speed: 300,
  slidesToShow: 1,
  adaptiveHeight: true,
  dots: false,
  asNavFor: '#list_below',
});

$('#list_below').slick({
    dots: true,
  arrows: false,
  slidesToShow: 1,
  asNavFor: '#list_above',
  adaptiveHeight: true,
});
Leavenworth answered 27/2, 2016 at 4:51 Comment(0)
M
2

You can set following way arrow key in middle of the image using JQuery.

$(window).on('load resize', function () {
 changepos();
});

function changepos() {
  var toppos = ($('.slick-active').find("img").height()/2);
  $('.slick-arrow').css('top',toppos+'px');
}

$('.list').slick({
  dots: true,
  infinite: true,
  speed: 300,
  slidesToShow: 1,
  adaptiveHeight: true
}).on('afterChange',function(event){
  var toppos = ($('.slick-active').find("img").height()/2);
  $('.slick-arrow').css('top',toppos+'px');
}).trigger('afterChange');

Working Fiddle

Matelda answered 22/2, 2016 at 7:12 Comment(0)
C
0

override the css rule which position the two arrow in this way:

body .slick-next, body .slick-prev{
  top: 40%;
}

Result: jsfiddle

Cowart answered 19/2, 2016 at 17:3 Comment(2)
Try changing slides and note how the arrow moves further down the page due to the additional content. :(Hark
If the image height never changes, you can use a fixed size ( top: 145px;) to solve the issueCowart
C
0

I have updated the JS fiddle with the solution to always keep arrows middle align with the image even if the images on each slides are of different height.

function fixVerticalArrows(){
    var h = ($('.slick-active').find("img").height()/2);
    $('.slick-arrow').css('top',h+'px');
}
$(document).ready(function(){
  $('.list').slick({
    dots: true,
    infinite: true,
    speed: 300,
    slidesToShow: 1,
    adaptiveHeight: true
  }).on('afterChange',function(event){
    fixVerticalArrows();
  }).trigger('afterChange');
  $(window).resize(function(){
    fixVerticalArrows();
  })
});

Working JSFiddle here

Cassel answered 21/2, 2016 at 19:17 Comment(2)
Thanks Nadeem. One issue I noticed is if the window resizes (or orientation changes), the arrows are not in the correct place. Any ideas how to fix?Hark
I have updated the jsfiddle with the fix, on window resize we are calling the fix function to re calculate.Cassel
M
0

All you need to do is override the top:%50 property on .slick-prev and .slick-next.

.slick-prev {
  top:100px;
}
.slick-next {
  top:100px;
}

See fiddle.

Marva answered 22/2, 2016 at 17:51 Comment(0)
R
0
$('.list').slick({
    dots: true,
    infinite: true,
    speed: 300,
    slidesToShow: 1,
    adaptiveHeight: true
}).on('setPosition',function(event){
    var img = $(event.currentTarget).find('.slick-active img');
    var toppos = img.height()/2;
    toppos-=$(event.currentTarget).find('.slick-arrow').height()/2;
    $(event.currentTarget).find('.slick-arrow').css('top',toppos + 'px');
}).trigger('afterChange');
Richards answered 16/1, 2023 at 14:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.