Creative web: building dynamic websites for work and play

Alistair Shepherd
Developer — Series Eight

Introduction

A lot of the web is boring

But first, some admin... 😨

  • Slides at accud.io/sotb
  • Content warning: Animated demos and videos
  • Visual effects, will do my best to explain
  • Not much code, linked blog post have demos and code samples

Vanilla Parallax

'Live' colour theming with Custom Properties

Generative SVG Dividers

Background

an illustration of a layered landscape by the video game Firewatch. It's split into 3 sections: the left is a light blue morning colour scheme with rain; centre is a light orange mid-day colour scheme that's clear; the right is a dark orange evening colour scheme with snow
Screenshot of website with title 'Alistair Shepherd - full stack web developer in Edinburgh and the Scottish Highlands'. On the right is a website navigation sidebar and the background has a video of a mountain stream

2019–2020
A new personal site

I used the skills and tools available to me...

...by asking my talented artist sister for help!

Orange monotone illustration of a landscape. Trees are in the foreground, a loch and forest is in a valley and in the background a mountain range is visible.

What I mean by "modern CSS"

Simple Parallax with CSS and a wee bit of JavaScript

What is Parallax?

Addressing the "Parallaxed Elephant in the room"

.container {
	overflow-y: scroll;
	perspective: 100px;
	perspective-origin: 0 0;
}

.layer-1 {
	transform: translateZ(-100px) scale(2);
	transform-origin: 0 0;
}

CSS Custom Properties

html {
	--colour-primary: #f00;
	--size-lg: 2rem;
}

h1 {
	color: var(--colour-primary);
	font-size: var(--size-lg);
}
document.documentElement.style.setProperty('--size-lg', '4rem');

Parallax with JavaScript

const scrollEl = document.documentElement

let scrollPos
function animation() {
  // check the scroll position has changed
  if (scrollPos !== scrollEl.scrollTop) {
    // reset the seen scroll position
    scrollPos = scrollEl.scrollTop
    // update css property --scrollPos with scroll position in pixels
    scrollEl.style.setProperty('--scrollPos', scrollPos + 'px')
  }
  window.requestAnimationFrame(animation)
}
window.requestAnimationFrame(animation)
/* parallax */
.layer {
	transform: translateY(calc(
		var(--scrollPos, 0px) * var(--offset, 0)
	));
}

/* disable accessibly */
@media (prefers-reduced-motion: reduce) {
	.layer {
		transform: translateY(0);
	}
}
<div class="landscape"
	role="img" aria-label="Equivalent to an img alt attribute">
	<div class="layer" style="--offset:0.04">...</div>
	<div class="layer" style="--offset:0.08">...</div>
	<div class="layer" style="--offset:0.1">...</div>
	<div class="layer" style="--offset:0.14">...</div>
	<div class="layer" style="--offset:0.17">...</div>
	<div class="layer" style="--offset:0.2">...</div>
	<div class="layer" style="--offset:0.25">...</div>
	<div class="layer" style="--offset:0.6">...</div>
	<div class="layer" style="--offset:0.8">...</div>
	<div class="layer" style="--offset:1">...</div>
</div>

✨ Next Steps ✨

Colour themes with time-syncing 'live' mode

an illustration of a layered landscape by the video game Firewatch. It's split into 3 sections: the left is a light blue morning colour scheme with rain; centre is a light orange mid-day colour scheme that's clear; the right is a dark orange evening colour scheme with snow

Colour theming with CSS Custom Properties

html {
	--c0: #f5e5e5;
	--c1: #fed4d5;
	--c2: #dcbed9;
	--c3: #c8aed9;
	/* etc */
}

body {
	background: var(--c0);
	color: var(--c10);
}

Animated or 'live' colour themes

{
	"at": 0,
	"name": "night",
	"colours": {
		"c0": "#bed8f8"
		// etc
	}
}
{
	"at": 6,
	"name": "sunrise",
	"colours": {
		"c0": "#f5e5e5"
		// etc
	}
}
{
	"at": 12,
	"name": "day",
	"colours": {
		"c0": "#feebe2"
		// etc
	}
}
{
	"at": 18,
	"name": "sunset",
	"colours": {
		"c0": "#ffc348"
		// etc
	}
}

How do we animate
custom properties?

  • CSS animations
  • Transitioning custom properties
  • Houdini @property

Custom implementation

  1. An animation running in a loop;
  2. Get the progress through the day;
  3. Work out the next and previous 'states' and the progress between them;
  4. With the progress between the states, 'interpolate' between the two states for each colour;
  5. Update the theme custom properties;

Colour formats and spaces

* {
	--colour-hex: #fc813a;
	--colour-rgb: rgb(252, 129, 58);
	--colour-hsl: hsl(22, 97%, 61%);
	--colour-lab: lab(67%, 42, 58);
	--colour-lch: lch(67%, 71, 54);
}
RGB
LAB
HSL
LCH

✨ Next Steps ✨

SVG generative mountain ridge dividers

Generating unique dividers with code

Terrain Generation with Midpoint displacement

✨ Next Steps ✨

Wrapping up

You've all got homework! 😱

Look for web inspiration everywhere

Building cool websites is easier than ever

Go make (deleted)boring(end deleted)
fun websites!