Style a Slick Carousel Slideshow in Drupal 8

On a recent project, I was given the task of styling a slideshow in Drupal 8. The site builder on my team had already laid the groundwork by creating the content types and views. Let's take a look at the user interface for a Hot Topics view:

 

 
 


Notice how the format for this view is set to Slick Carousel. This module, as well as Slick Views, were enabled in the theme.

Now, let's dive into the markup (provided by Google Chrome Inspector Tool) :
 

 


I identified the main container as #slick-views-hot-topics-block-1-2-slider. It holds all the major components of the slideshow that I need to manipulate for styling. Notice that the .slide__content area consists of .slide__media (holds images) and .slide__caption (holds image caption text). Ultimately, I would like my slide content area to look like the following: 
 
 
 
First, I'll be sure to set the container #slick-views-hot-topics-block-1-2-slider to:
 
#slick-views-hot-topics-block-1-2-slider {
    position: relative;
    display: block;
}

The position of relative will be important in the future when styling the slideshow control arrows. Displaying the container block will ensure that it takes up 100% width of its parent.


Same concept for the .slide__content area:
.slide__content {
    display: block;
}

Next, I want the .slide__media and .slide__caption areas to be positioned side by side:
 

.slide__media {
    float: left;
    width: 50%;
}

.slide__caption {
    float: left;
    width: 50%;
    background: #0b172e;
    color: $white; 
}

Including padding will add clean spacing to the .slide__caption area, text and call to action button.
 

The image in .slide__media should be set to:
 
.slide__media img {
    display: block;
    max-width: 100%;
    height: 100%;
}

This will ensure that the image always fills up its parent's area.
 

Let's jump back into the markup (provided by Google Chrome Inspector Tool):

 
 

Notice that below our slide content area are PREVIOUS and NEXT control buttons for our slideshow. They were added through the User Interface:

 

See the unstyled buttons below:

 
 

Remember when I positioned the container relative:

#slick-views-hot-topics-block-1-2-slider {
    position: relative;
    display: block;
}

 

This is important because I'm going to position the PREVIOUS and NEXT buttons absolute. This will place them within the bounds of the container yet on top of the .slide__content area. See the desired effect below:

 
 
The PREVIOUS and NEXT buttons both share the class .slick-arrow so I will take advantage by adding properties I want applied to both buttons to this class. It helps with reducing repetitive code.
.slick-arrow {
    position: absolute;
    top: 35%;
}

.slick-next {
    right: 0;
}

Now I am going to prepare to replace the PREVIOUS and NEXT buttons with arrows.

.slick-arrow {
    position: absolute;
    top: 35%;
    background: transparent;
    height: 80px;
    color: transparent;
}

 

The result:
 
 

Here comes the magic. I am going to add the arrows using the css content property.

.slick-prev:before {
    content: "\f104";
    font-family: FontAwesome;
    padding: 0 10px;
    color: $yellow;
    position: absolute;
    font-size: 50px;
    top: 0%;
    left: 20%;
}

.slick-next:before {
    content: "\f105";
    font-family: FontAwesome;
    padding: 0 10px;
    color: $yellow;
    position: absolute;
    font-size: 50px;
    top: 0%;
    right: 20%;
}

Font Awesome is a web font containing all the icons from the Twitter Bootstrap framework. I can add icons :before or :after an html element by declaring the corresponding css content value ("\f104"):
 

 

Since the icons are fonts, I can increase the size by changing the font-size property (font-size: 50px;). By positioning the icons absolute, I will ensure that the arrows always remain within the bounds of the PREVIOUS and NEXT button areas. Now the slideshow looks like this:

 

 

Finally, I remove the border from the buttons and voila!

.slick-arrow {
    position: absolute;
    top: 35%;
    background: transparent;
    height: 80px;
    color: transparent;
    border: none;
}