Skip to main content

Adding a footer block

We know, this is not the final chapter, but we will still work together on creating the footer at the end of the page.

Footer

The essentials

The markup

Locate the {% block content %} tag inside the base.twig file and add the provided markup to include it on every page.

/views/layouts/base.twig
{# ... #}
<div data-module-scroll="main">
{# ... #}

<main>
{% block content %}{% endblock %}
</main>

<footer class="c-footer">

</footer>
</div>
{# ... #}

Let's begin by incorporating essential footer elements, such as the big logo and credits.

/views/layouts/base.twig
<footer class="c-footer">
<div class="c-container">
<div class="c-footer_inner">
{% include "@snippets/logo.twig" with {
classes: 'c-footer_logo'
} only %}
</div>
</div>

<div class="c-footer_copy">
{% for copyright in site.copyrights %}
<div class="c-footer_copy_item">
{{ copyright }}
</div>
{% endfor %}
</div>
</footer>

The styles

Add these styles

/assets/styles/components/_footer.scss
.c-footer_logo {
overflow: visible;
}

.c-footer_copy {
@include -container;
padding-top: var(--grid-gutter);
padding-bottom: var(--grid-gutter);
display: grid;
gap: var(--grid-gutter);

@media (min-width: $from-small) {
grid-template-columns: 1fr 1fr 1fr;
}

@media (max-width: $to-small) {
grid-template-columns: 1fr;
}
}

.c-footer_copy_item {
a:hover {
text-decoration: underline;
}

@media (min-width: $from-small) {
&:last-child {
text-align: right;
}
}

@media (max-width: $to-small) {
text-align: center;
}
}

The marquee

Now, let's address the marquee. The concept is simple : we'll arrange the images in a horizontal line and create an infinite translation effect.

The markup

/views/layouts/base.twig
<footer class="c-footer">
<div class="c-footer_marquee">
<div class="c-footer_marquee_inner">
<div class="c-footer_marquee_list">
{% for item in marquee %}
<div class="c-footer_marquee_item">
{% include "@snippets/image.twig" with {
src: item.img.src,
width: item.img.width,
height: item.img.height
} only %}
</div>
{% endfor %}
</div>
</div>
</div>

<div class="c-container">
<div class="c-footer_inner">
{% include "@snippets/logo.twig" with {
classes: 'c-footer_logo'
} only %}
</div>
</div>

<div class="c-footer_copy">
{% for copyright in site.copyrights %}
<div class="c-footer_copy_item">
{{ copyright }}
</div>
{% endfor %}
</div>
</footer>

The styles

To achieve the marquee effect, it's important to ensure that the list's content is larger than viewport's width.

/assets/styles/components/_footer.scss
.c-footer_marquee {
@include -margin-medium-bottom;
overflow: hidden;
position: relative;
z-index: -1;
}

.c-footer_marquee_list {
display: inline-flex;
white-space: nowrap;
animation: marquee 20s linear infinite;
}

.c-footer_marquee_item {
width: 20vw;
margin-right: var(--grid-gutter);
}

The progress animation

The markup

To observe the entire footer and apply a CSS --progress variable, let's begin by adding the necessary locomotive-scroll attributes.

data-scroll-repeat

Simply declaring this attribute will enable the repeat behavior for in-view detection of the element. This will add and remove the class in-view from the element.

caution

To address a bug with locomotive-scroll where the element would not be considered "in-view" when scrolling to the very bottom, make sure to add the attribute data-scroll-offset="0%,99%" to the respective element.

/views/layouts/base.twig
<footer 
class="c-footer"
data-scroll
data-scroll-repeat
data-scroll-offset="0%,99%"
data-scroll-css-progress
>
{# ... #}
</footer>

The styles

To improve performance, let's only animate our marquee when it's in-view.

/assets/styles/components/_footer.scss
.c-footer_marquee {
@include -margin-medium-bottom;
overflow: hidden;
position: relative;
z-index: -1;
}

.c-footer_marquee_list {
display: inline-flex;
white-space: nowrap;
animation: marquee 20s linear infinite;
animation-play-state: paused;

// Only animate when in view
.c-footer.is-inview & {
animation-play-state: running;
}
}

.c-footer_marquee_item {
width: 20vw;
margin-right: var(--grid-gutter);
}

Here we'll be adding an opacity attribute based on the progress variable.

/assets/styles/components/_footer.scss
.c-footer_marquee {
@include -margin-medium-bottom;
overflow: hidden;
position: relative;
z-index: -1;
opacity: calc(min(0.7, var(--progress)) / 0.7);
}

Finally we'll replicate the effect that we did on our header logo, but in reverse!

/assets/styles/components/_footer.scss
.c-footer_logo {
overflow: visible;
transform: scaleY(calc(1.5 - var(--progress)*0.5));
transform-origin: center bottom;
}