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;
}