Web Development by Solarise

The Solarise.dev Blog

Impossible Isometrics – An experiment with CSS and isometric viewpoints

Blog archive Robin Metcalfe 28th August 2015

Taking inspiration from the marvellous mobile game “Monument Valley”, I created an interactive Escher-esque structure complete with animations and interactions using only CSS (and a sprinkling of HTML to contain the structure of the paths) – No Javascript was used in the production of this thing.

Monument Valley takes you on an adventure through a series of convoluted and geometrically baffling landscapes. It very effectively contorts and distorts your understanding of the physical layout of each section to offer a series of continually shifting paths. I wanted to try and recreate that using only basic web technologies.

Monument Valley

The demo will load in the space below. If nothing is showing, give it a few seconds, or click here.

Use the buttons on the left to control the animation.

See the Pen Impossible Isometrics by Robin Metcalfe (@solarisedesign) on CodePen.

See the Pen Impossible Isometrics by Robin Metcalfe (@solarisedesign) on CodePen.

Technical notes

I encountered some fascinating challenges while building this.

Firstly, defining the isometric layout was achieved with use of the CSS3 transform functionality, to apply a mixture of skew and translate effects, with a bit of scale thrown in to fit everything into the scene.

@include transform-origin(0px 0px);
@include transform(rotateZ(45deg) scale(0.75))

Furthermore, the very nature of the scene, and the “impossible” nature of the isometric layout means that there is inevitably going to be issues with path blocks being both behind and in front of others.

There are some workarounds (e.g. additional classes given to specific path elements) to allow for situations where, say, a block occludes another portion of the path, yet the z-index ordering of the blocks means the rear block shows over the front block. For example, at one point on the path, I’ve defined a “triangle” shape so that the “rectangular” background would not overlap.

I don’t believe that my solution is particularly elegant though – I believe that there are cleaner approaches to developing an isometric viewpoint in CSS. One issue I encountered was when I realised I needed to apply fudge factors to various elements in order to align them more neatly – i.e. adjusting the position of elements manually, rather than having everything align properly based on initial positioning. Further improvements could include more detailed mathematical calculations to properly define the scene and implement a framework that more elegantly defines the view. An end-goal for this animation would be to allow the path to be adjusted fully within the HTML, without the need for additional CSS modifications.

Clouds

I’d intentionally set myself the challenge of building the scene without using any image assets whatsoever, and allowing only a single HTML element per unique entity within the scene. So, to make it harder on myself, I decided that each individual cloud-bank would be an entity, and I would have to somehow generate an animated row of clouds using only a single element (you can see within the HTML code, elements with the class ‘cloud’)

To achieve this, I decided to make use of CSS’s ability to embed content within elements. And specifically, making use of glyphs to generate rounded graphics.

I searched through the list of glyphs available, and eventually found two, under Miscellaneous Symbols for the playing card symbols hearts (♥) and clubs (♣)

When converted into the appropriate CSS glyph notation these characters could then be repeated, styled and have animated transforms applied to create the cloud effect.

Buttons

The buttons for the animation make use of CSS’s ability to target elements siblings, and combined with the :checked pseudo-class of a checkbox element, can be used to set specific attributes on an element based on whether the button is “selected” or not

This is known as the checkbox hack, and I also had to make sure that I added a <label> element, otherwise it wouldn’t work in Firefox.

// e.g. from the SCSS source
// When <input type='checkbox' class='sunmoon' /> is checked
.sunmoon:checked ~ #world #sunmoon {
  @include transform(rotateZ(180deg) translateY(-2 * $block));

}
// When it's *not* checked...
.sunmoon:not(:checked) ~ #world #sunmoon {
  @include transform(rotateZ(0deg) translateY(0px));
}

(The sun and the moon are generated from a single HTML element too. I won’t explain how that’s done here, but take a look through the code if you’re interested)

Some thoughts on the limits of CSS

Take a look at any website on the internet. With the exception of those that are heavily Flash-based (or utilise a similar embedded technology), the chances are that you’ll be looking at a combination of HTML and CSS to achieve the look-and-feel of the site.

CSS is what makes the web look good. It defines the rules and parameters which bind the style-less elements of HTML together (without CSS, websites would look no more impressive than the first website ever made)

A lot of sites will use CSS for styling fonts, changing background colours etc. But there are some other extremely interesting ways in which CSS can be applied – and especially if you consider that it’s historically a tool for applying styles to content, the range of things you can achieve by using CSS alone are astonishing.

Especially with the recent improvements introduced by CSS version 3, features such as animations and transitions mean that it’s now possible to implement fairly complex movement and interaction within the visual styles of a website.

The fact that something like this can be done without the use of Javascript (essentially, CSS is not a “language”, traditionally not being something used to “do things”, rather to “style things”) is testament to the power of styling rules within modern browsers.

Future development

Further (optimistic) improvements may include:

  • 3D Rotation – this is something present within the Monument Valley game itself, where e.g. a tower, and its associated path will rotate through 90 degrees to realign with another part of the scene. In the current implementation, using skew and translate transformations, I fear this is beyond scope. With a different model for implementing the isometric view/3D transformations, I believe this would be achievable.
  • Active character animation – for an added challenge, how could I represent a character within the scene, and have them walk along a defined path – given that the path itself can be dynamically altered in HTML? I suspect this may be possible using only CSS, with some modification to the CSS code with SCSS variables, but I also suspect the solution to this will be extremely complex

I have a feeling those extra features may be a long way off…

Author Image

About the author

Robin is the dedicated developer behind Solarise.dev. With years of experience in web development, he's committed to delivering high-quality solutions and ensuring websites run smoothly. Always eager to learn and adapt to the ever-changing digital landscape, Robin believes in the power of collaboration and sharing knowledge. Outside of coding, he enjoys diving into tech news and exploring new tools in the industry.

If you'd like to get in touch to discuss a project, or if you'd just like to ask a question, fill in the form below.

Get in touch

Send me a message and I'll get back to you as soon as possible. Ask me about anything - web development, project proposals or just say hi!

Please enable JavaScript in your browser to complete this form.

Solarise.dev Services

Maintenance Retainers

Min 3 hours per month, no contract

Project Planning

Get in touch to discuss your project details

Consultancy

Face-to-face chats. Solve your problems!