The following is a guest post by Joseph Markus. Joseph had a particular design he needed to implement for the BFI’s Britain on Film website. Like a true front end developer, Joseph considered the requirements and went through many different options to find the best approach. He’ll take us through that journey here. I don’t know about you but I love this kind of thing.
In July this year BFI’s Britain on Film launched to widespread acclaim. An archive of historical footage like no other, Britain on Film invites viewers to take a journey through British history.
One of the key features the team at Ostmodern had to design and build for this product was a landing page which invited users to explore the archive, discovering content by time, subject and location. A core component of this landing page is an animated module of content suggestions, each depicting a still images of films from the archive.
Here’s a video showing the final result:
The brief for the project made clear that this task needed to be split into manageable chunks and had to account for the following restrictions:
- CMS Managed Images – The people who manage content on the BFI team upload images with predefined dimensions. That image is then allocated to one of the three containers: left, top or right.
- Responsiveness – Not only does the container need to be resizable horizontally, but as it gets narrower it needs to take up less height as well.
- Animations – The images don’t immediately change but fade to the next one.
- Browser Support – It should work as far back as it can and fall back gracefully.
- Semantics – Use HTML and CSS, not Flash or anything crazy like that.
We will be looking into combinations of the above restrictions. As I have spent a reasonable amount of time researching for the best approach to this task, I thought it would be very useful to share my findings, approach and, obviously, the final result.
This is a Sketch wireframe of the layout we need:
We’ll go through a number of techniques. The final one is the version that made it into production.
Attempt #1: CSS Transforms
This one is the first that came to my mind. An image container with a set width/height, position relative and overflow hidden. Two rectangles within, position them absolutely, transform rotate – all magic numbers. See my quick Sketch mock-up:
The biggest issue here is getting the rotation degree right. Setting the correct over-sized width and height of each of the shapes, positioning of the elements outside of the boundaries of the main container. All achievable, but very boring and dirty. If you were going to go this route, perhaps a good way to get it done is export the mockup from like I have above as a flat image and set it as the background image of the page, then start positioning and tweaking the elements in DevTools until you get it right.
There’s a big problem though. Say you put images in these containers (like with
background-image). Those images are also rotated which is not what we want. It’s not impossible to fix. You could use the pseudo elements on them and rotate them in the reverse direction, but believe me, it gets very tricky, especially when you start dealing with media queries.
- Comfortable tech: some rotated and positioned divs
- A lot of calculation and measuring
- Responsive breakpoints are difficult to pull off
This option is clearly a no-go.
Attempt #2: CSS clip-path
clip-path came to mind as one of those “I’ve heard of it, but never used it” things. Clippy, the tool by Bennett Feely, makes it look very easy and straightforward.
This is probably the most clean, straightforward, and most definitely my favourite option.
- Easy to create and modify
- Clean code
- No IE support, which is a requirement for this project
Sadly, the cons knocked it out of the game. Here’s a demo of how it works anyway:
See the Pen LpbzRa by Joe (@jmarkevicius) on CodePen.
Attempt #3: SVG <pattern><image>
I had to do quite a bit of research to figure out what I was doing here and get to the desired result. My SVG exports from Sketch were a bit confusing and seemed to include a lot of junk. I had to experiment quite a bit and I found understanding
preserveAspectRatio pretty key. Here are some resources to help that understanding:
- Jakob Jenkov: SVG Viewport and View Box
- Sara Soueidan: Understanding SVG Coordinate Systems and Transformations (Part 1) — The viewport, viewBox, and preserveAspectRatio
- Joni Trythall: A Look At preserveAspectRatio in SVG
- Giovanni DiFeterici: SVG and the preserveAspectRatio Property
- Wide browser support (IE 9+, Firefox 41+)
- A bit of a disappointment after CSS clip-path
- Firefox has got a bug in versions <40 (bug viewable in example below, or here)
Example of a croppable image as the background in various SVG shapes:
See the Pen SVG Pattern playground by Aleksey (@bonflash) on CodePen.
Attempt #4: SVG <clipPath><polygon> + <image>
This option came about as a workaround for the Firefox bug described in the last attempt. It applies the images through the normal SVG
<image> tag, then applies a
clip-path to them built from the necessary
See the Pen jPgmWG by Joe (@jmarkevicius) on CodePen.
This is the example that made it into production due to its wide browser support.
Throw in some fancy transitions, layer some more elements on top and voilà – Britain on Film landing page on BFI Player is ready to go.
Let me know your thoughts in the comments!
- MDN: viewBox
- Justin McCandless: Making Sense of SVG viewBox's Madness
- CSS-Tricks: Clipping and Masking in CSS
- Steven Bradley: Move And Scale SVG Graphics With The viewBox Attribute
- Tavmjong Bah: Test of SVG ViewPort and ViewBox in HTML
Wow! Well done – site is gorgeous. The hero took a while to load on my mobile device, but it was worth the wait.
One problem with using SVG and image is a bug in IE that it doesn’t load images from a different origin; you can use a foreign object tag inside a conditional comment for IE8, if necessary.
Hotlinking images from W3 Schools? Interesting choice :)
Brilliant reinforcement of exactly the same path I came to use on my own site; glad to see that I was thinking along the same lines! :-D