How we went from 0 to 100 in 4 months with the website of the most iconic luxury sports car in the world

Peter Schmiz
Wunderman ThompsonBudapest
14 min readDec 21, 2017

As a front-end developer, I have built many sites in my life. Some of them were simple, easy to build, interesting, but others just made me think, holy shit, this is not going to work and this will be an epic failure.

Cut to me building the Aston Martin site, one of the biggest challenges we have faced in the last couple of years.

Shot from the design styleguide

The designs were very detailed, every little part of it had a meaning and function. When I enquired with the lead designer about it I got an answer which was at the same time frightening and motivating:

“You have to feel it and when you feel it, you will know how to develop it”

To me, good front-end development is all about details. It is not enough to be a kick-ass developer, you should be passionate about bringing to life those little things the designer has spent hours dreaming of. At the end of the day, that is what makes people fall in love with a design — the Aston Martin website being the perfect example of that.

“ The quality of the front-end is what makes an award-winning site.”

So, goals, targets and expectations were set — and the bar was pretty high. We just had to deliver it. Piece of cake…. or maybe not?

The production line

To build an outstanding website you need to use the right tools, combine them efficiently, and follow the proper processes. Our assembly line consists of Yarn, Gulp, PostCSS, Webpack, Pug with Express.js.

By leveraging the power of having live and hot reloading, file watching, fast linting, perfect IDE integration (with Webstorm), the development was executed really fast. We combined agile methodology with agile tools like JIRA with Confluence and Bitbucket to keep the team always up-to-date with everything that was happening, all the time. All communication was via comments in JIRA.

Our very international team was formed by developers and QA from Poland, UI designers, UX designers and project managers from the UK, project managers from France and front-end developers from Hungary. We somehow managed to get everyone on board pretty quickly and from there the assembly line started to roll.

The chassis

We approached the project in a very modular, component based way. There are only four page templates and the editors can create and compose the pages as they please.

From the front-end point of view, this approach meant that we also had to handle and create everything as a component and we had to group components. You could ask: Why don’t you use React or Vue for that? The answer is simple: We wanted to build something from scratch, with minimum dependency and have full control over the code. Plus, it was a great exercise for us and a way to improve our Javascript knowledge.

For the HTML generation (which was later used by the backend team) we used Pug. With it, we were able to generate components and modules quickly, use them flexibly and in the case of changes apply them instantly.

Below is an example of a simple content module which we used in many places. The following Gist shows how it is used (combined with the video player component)

And this piece of code renders on the page as follows (the video player part is not visible in the Pug file)

Content module A with video player

During the development phase, we created more than 40 components. Most of them have different variants, the customisation and setup is up to the editor in the CMS.

Pug was also helpful to the backend team, because it allowed them to update or recreate the CSHTML templates based on our files easily (it is not difficult to understand and use Pug).

Express (which was used during the development as the static, local solution) was configured to use and compile Pug files real-time during development. Combined with live reload, it was an optimal solution to build layouts in a fast, iterative way.

BrowserSync was used to run and check the site simultaneously in multiple browsers and on multiple devices (sometimes on multiple machines with different OSs).

The paintwork

Just before we started the project I read up on PostCSS and checked what it is and what the pros and cons are (which is funny considering the fact that PostCSS first commit on GitHub is from 7th September 2013).

We used to use and always loved SCSS, the mixins, the nesting, the variables, the Bourbon mixin library, but PostCSS looked very promising, with lot of utilities, plugins and, besides all that, we could customise it as we wanted. Ah, it is super-fast as well!

Because we were used to using Sass-like markup we chose to have multiple plugins like PreCSS and cssnext or PostCSS Responsive Type.

To ensure that our CSS would still be following guidelines and rules we also set and used Stylelint with a strict configuration (e.g. unit checks, property order, naming conventions etc). Also, we used Webstorm as an IDE, because it is a great support for Stylelint and also because it provides other plugins too.

Error reporting and IDE highlight with Stylelint

At the beginning of the project CSS Grid was considered for some brief moments the preferred approach and using Flexbox as a fall back. But, in the end, we decided to go only with Flexbox in order to simplify the development (fortunately the browser matrix we used could support Flexbox). Although we had some minor issues, especially with Internet Explorer 10, we were able to solve all of them with the help of Flexbugs.

There were many cases where the possibility of re-ordering the visual elements was a huge help. Here is an example: In the desktop version, we have a so-called “Brand Page”, which is composed of three vertical sections sitting side-by-side. Once you click on one of the header blocks, the corresponding content module appears right below them.

On mobile, the same logic applies, but the header blocks are not sitting side-by-side anymore, but above each other, and the active content appears right below the active header block. Without Flexbox you either have to duplicate the content blocks or manipulate the DOM with Javascript, and neither of those options was good for us.

Flexbox order example based on our Brands page

In terms of performance, we always tested and checked to see if the parts of the page were causing a slowdown or bottleneck. One of these checks were done on the CSS files to see if we used and applied the proper solutions.

One of the tuning-properties we used was the will-change. If it is used correctly and with caution it can really improve your performance, especially in cases where the transitioned/ animated attribute would cause a repaint/reflow.

The other tool we used for checks was Chrome’s Developer Tool, Layers section. It makes it super easy to spot and inspect the slow parts of your page. It not only warns you about the issues, but also gives you hints or probable causes.

The pinkish rectangles on the right side show a possible slow region (touch handlers are added to the header navigation elements)

The other section in Developer Tools you should use every time you build a site is the Performance part.

Run the profiler regularly and look for FPS drops or time-consuming actions, code parts. Once you have learned how to use it and what to look for, it becomes your best friend.

It got even better with the introduction of the CPU throttle: You can test how your site would perform on slower computers or mobiles. In my case, this was very useful, because my development machine is a Macbook Pro with a fast CPU, which cannot be taken for granted when you develop. So, we continuously tested the site with different throttle settings.

Homepage performance with different throttle settings: from 6 fps up to 61 fps

We were really keen to find solutions and techniques which are either modern or clever somehow. I won’t list them all here — maybe some of them are well-known or you might know a better approach. But I will take the opportunity to talk about some of them.

The footer reveal animation is a clever and old idea, but still very useful. We combined it with the repeating-linear-gradient CSS function to achieve the needed background (I even animated it, but it was too much, after a while you get dizzy watching it).

Another solution which I categorise as a clever solution is the menu hover effects in the overlay.

Overlay menu and the fade out effect without Javascript

It’s a small, simple, pure CSS solution that allows us to highlight the items the user is hovering and fade out the other ones. The trick is to fade out all the elements while hovering on the parent element and then fade in just the one element you are actually hovering.

Menu hover and how it works

Throughout the development we tried to follow best practices as well as advice from our partners. One of them came from our Head of Art:

Check out, read and apply the Material motion from Google’s Material Design.

So, we did. One example is the overlay transition times, which are screen size aware: on smaller screens, we decreased the transition times. Since then, we have been using this media query based transition timing solution more and more.

Another transition timing challenge was the menu items fade and slide down: we didn’t want to generate endless variations of possible menu elements (we have a CMS behind the site, so we cannot predict the number of the items on the menu). So, the actual delays are calculated with Javascript and applied as inline style and also added as a stylesheet (in the case of the pseudo elements, which are animated as well).

Every single element has to move with perfectly alignment and timing, no matter how many elements we have. To prevent big delays (if we have more than 10 menu items) the items which are not on screen when the overlay is shown or hidden, the timings are set to 0. (they won’t be seen anyway).

While progressing with the build and adding more and more components we faced an issue with the font sizes: on really big screens the initial font sizes were too small and on small screens they were too big. We first tried with multiple media queries, defined multiple ranges, but none of them worked as we wanted.

Solution: responsive font size and fluid typography.

Not a new thing, there is a good article in Smashing Magazine about it and we added the responsive type PostCSS plugin and fine-tuned all of our components.

In the following video, you can check how this works during resize: as you can see, the values are constantly changing (thanks to the calc), but at a given point the minimum or maximum size is set. We not only applied this to the font size and the line height, but also to the margin bottom value.

We also wanted the whole site to scale proportionally. The initial approach used a limited, maximum sized page layout and fixed sized modules (e.g. the images had fixed height, only the width varied).

On big screens, the site looked tiny, with lots of huge spaces around the content, and we were afraid that we were losing the beauty of the artwork.

So, we modified and re-built all of our components to scale and so that they would keep the given aspect ratios. We came across this very useful CSS-Tricks article and did the development accordingly, plus, we had to make sure that it would go along with Flexbox. The solution was really simple: make the content wrapper positioning absolute and stretch it with the top, right, bottom and left properties (so you don’t need to know or care about the actual height).

To have a guide or reference system while building the site we implemented a visual grid system helper. On the live site, the hotkey is turned off, but if you apply the debug class to the body tag you can make it visible again.

The debug PostCSS file which generates the visual helper if the body tag has a debug class.

A pseudo element is applied after the body tag and the colouring was done using a repeating linear gradient. The width of each column (solved with colour- stops) is calculated based on the screen width, so it is always responsive and follows the real grid used on the site. By applying the pointer-events “none” to the element, we made it possible to use and debug the site while the visual guide is turned on.

Part of the styleguide with proper guides regarding the grid layout and sizing

We used a 12-column grid system on desktop sizes and we switched to a 4-column grid on mobile (still, most of the blocks consume all four columns, so it is almost the same as if we used a single, one columned layout).

Actual build with the grid helper turned on

Colours were also carefully selected and used throughout the site. Every model has its own colour, set in the CMS by the editors. Components use this base colour with small changes: either darker by 10 percent or lighter. The exact colour is calculated with JavaScript from the hex value received from the CMS.

The engine

A nice, elegant car with shiny racing green paint is worth nothing without a powerful engine. Stronger is better, but also efficiency should be taken into consideration when building a car. The same goes for the website development. In web development, I consider the Javascript the engine.

We didn’t use any framework, but used plain JavaScript, written by the specification of EcmaScript 2015 (ES6). With the usage of ES6 modules we were able to create a modular, well-defined and structured solution.

Since ES6 modules (and some of the other features we used) are not fully supported natively by every major browser, we used Babel as transpiler.
(We are very, very close to using ES6 Javascript without transpilers).

The whole application bundle is 582kB (transpiled back into ES5), with Gzip compression it is 182kB. We used Lodash as a utility library, and with proper import usage we managed to save a lot of space.

For many solutions, we were considering using a library, because our target wasn’t to re-create already existing solutions, but find the best ones (from many points of view).

One of the parts where we needed to look for solutions was the Collection overlay or menu where the models are listed. If the user hovers over one of the menu items, the model image belonging to it fades in and the background colour changes to the colour of the model.

Many variations were developed: only showing a part of it, masking it, moving the mask, zooming out etc. The goal of the animations was to have a seamless transition between the collection menu and the model page.

We used canvas to animate the models. While creating the effect, we realised that while the overlay is full screen and has no scrollbars, the model page has lots of content and a scrollbar. So, we had to calculate the scrollbar width, take it into consideration while re-creating the background cover effect in canvas, and match the zoom values for the transition.

As for the animation, it switches from the canvas and it overlays some elements on the header (which is the hero element of the model page). This way we were able to match things that were absolutely needed in the layout perfectly.

Collection overlay to model page transition: background images should match perfectly

To achieve proper frame-rates, the canvas should be handled with caution. We applied many canvas optimisation techniques. We used buffer canvas, optimised the drawings, batched transformations, calculations and used requestAnimationFrame to handle our render loop.

But this wasn’t the only time we used canvas: we created a model carousel, where users can check different variations of a model. We only used static, rendered assets and created a very realistic animation from it. By setting up “easy-to-understand create rules” for the asset production, any editor can now upload and create such animation.

Four different parts / layers were used to create the canvas based animation

The animation is made by the composition of different parts: we have a chassis, two wheels and a shadow. We needed to handle them separately, so that we could then make the wheels roll. To set the exact location, the center-point of the wheel we marked with a one by one pixel green dot.

The canvas based final solution captured from the site

For an even more realistic result, the car moves slightly during acceleration and braking.

The extras and the tuning kit

All of the solutions we came up with during the development had one goal: to create something beautiful.

Every detail is important, has a meaning, and the modules are in sync. Harmony or nothing.

One of the fine-tunes we applied to the build was the parallax scrolling. Very subtle, almost unnoticeable, just a little wax and polish. As I mentioned above we used libraries, if we found an appropriate one. Unfortunately, we did not find a parallax animation library which worked as we wanted, so we took the best ideas from popular solutions and tried to combine them.

In the early stages we checked Google’s article about performant parallax scrolling, but our structure and already built components made it impossible to apply it in the time we had left.

So, we created a Javascript based solution, which is not the best, but still performs well. Using throttling, viewport check and CSS transform we still managed to make it work and give the proper look and feel.

The effect works in multiple ways: texts are moved or images/videos are translated. Every item has a parallax factor to define the movement size and direction. The transform value is calculated from the scroll position, the element’s Y offset and only applied if the item is in the viewport (some extra padding is added to cover edge cases).

Images and videos are scaled up to always cover the container edges

In case of images and background videos, the media is translated inside a container, which is set to hide the overflow. The media inside had to be scaled up with CSS, so during the transform the lower or upper part is still covering the whole container. The movement is very small and subtle, not more than 20px for the whole transform. If you watch closely, you can notice it (the purpose of the small movement was to help the overall look and feel).

Another idea of the team was the rich accordion module. This is a hidden content part of a page. It is only revealed when the user scrolls the page and it enters the viewport. Again, event throttling, will-change property and viewport activated manipulation gave enough performance.

Revealing, rich accordion module

I would be happy continue and list all the details of the modules, how we created the gallery module, the slider component, the enquire module, but this article is already too long. We know that there is still room for improvement, there are flaws and maybe we still can find some more elegant solutions. At POSSIBLE, we are proud to deliver a complex, challenging and visually appealing site, for a great brand, in just 4 months.

Maybe later I will try to write in greater detail and depth about the interesting components. But for now, I just would like to say thanks for reading. And keep coding!

--

--