A Quick Foray Into CSS Art

Mark O'Keeffe
6 min readMar 1, 2019

Recently, having placed the idea on the back-burner for a long time, I finally decided to delve into the emerging world of CSS art. Whilst it would utilise the many features that are offered by CSS3, their application would be somewhat different from the day-to-day usage of building modern and innovative user interfaces. The result of my foray into this world is shown below (and can be seen at this URL: www.markbokeeffe.com/peeping-tom).

Some Background

I have been working with CSS for many years: first of all as a Web Developer and then later as a Front-End Developer. As front-end technologies have evolved, so too has the role of CSS. In the earlier years, CSS tended to be used mainly for layouts and minor visual enhancements. Designs were often implemented mostly through the use of .jpg or .png image files, either as HTML img elements or as CSS background-image values. CSS sprites were popular and were widely used to create artistic back-drops to pages or elements on a screen. The result was that a standard static website could be enormously large in terms of file size, due to a large extent to the number of image files that were used to implement the design.

The reliance on image files subsided slightly with the burst in popularity of jQuery around 2010 and 2011, when it largely replaced Adobe Flash as the primary tool for web animations, due to Flash’s incompatibility with Apple’s iPhone. jQuery, at that time, opened up a whole world of opportunities for developers to create impressive visual effects and layouts on a screen. It enabled the developer to manage and alter styles directly in the DOM in a simple and effective manner. In conjunction with CSS, jQuery helped to lay the ground-work for a new era in UX design. jQuery could have a significant overhead however: site performance could be compromised if it was used too heavily on a screen. However, when a suite of exciting new features was released inside CSS3 a number of years ago (including animations, gradients, transforms and shadows), much of what was previously implemented via jQuery could now be implemented via CSS. CSS became a powerful tool in its own right and complex designs and effects could be implemented solely through this language. The impact on site performance was very positive and the role of JavaScript in front-end development would instead go on to focus mainly on the management of data and the creation of DOM elements — and less so on the styling of the DOM.

Where CSS Becomes A Paint Brush

On the back of the stronger power of CSS in creating visual designs and effects, a new genre of art has sprung up which demonstrates its capabilities. I have been very impressed by many of the CSS implementations that I have seen online and for some time, I have thought that it was something that I would like to try. In my spare time, I very much enjoy portraiture (see my website at www.markokeeffe.ie for examples of my work) and I have wondered if I could achieve a visualisation of part of the human face, purely through CSS.

Eventually, I got around to trying this and decided to create a picture of the human eye via CSS3, without the use of any image files, JavaScript or any other technology. I decided not to focus on code tidiness or structure, but instead to completely focus on leveraging the features of CSS3 to create the visual effects that I wanted to use. That was the top priority. For this particular challenge, swollen CSS files would be an acceptable overhead.

Creating The Effect Of The Human Eye Via CSS

The human eye is full of interesting details. Although no twos eyes are visually the same — they come in different shapes and sizes — they generally do share a set of common attributes. CSS3 provides the tools to replicate many of these attributes — particularly border-radius, box-shadow, transform, opacity and gradient.

The iris was created as a div with equidistant height and width. With a border-radius of 50%, a simple circle was created. Within this, the pupil was similarly created, with of course smaller dimensions. And inside of the pupil, two much smaller divs were created as the pupil white spots — one with less opacity, as the minor spot.

The iris was the perfect candidate for the radial-gradient function, as I set the colours to transition from a deep blue on the outer edge, via bright purple and then on to green. For the multitude of dark narrow axes that cross a pupil, I created a painstaking list of divs, each of which had low opacity but enough visibility to create a realistic portrayal of the iris. I spaced these lines in a purposely irregular manner, in order for them to appear more natural. The CSS transform property was relied upon heavily here, in order to appropriately rotate the lines around the iris. These lines ensured that the CSS files would swell significantly. However, as mentioned above, for this challenge, I was content to accept such swollen CSS. Finally, I placed the iris inside another slightly larger div with border-radius: 50%, in order to place a slight, faint shadow around it.

The eye-ball, in order to take its final shape, required full manipulation of the four border-radius values of the div (they ended up as 343% 91% 136% 34%). This then was placed within an eye-frame div, which provided for the lower eye-lid and socket depth. Its border-radius mirrored that of the eye-ball div, but by themselves, that was not enough to solve the problem of the overall eye shape. In order to force a more likely shape on the eye-ball, I was required to create a pseudo-element on the eye-frame div, by use of :after. This enabled me to place an absolutely positioned element with greater z-index over the top right of the eye, in order to cover an unnaturally shaped upper right portion of the eye-ball div. I also added a transform of three degrees on the div in order to make it less ‘comic-book’ style.

For the sclera of the eye (the white substance surrounding the iris), I gave it a background-color value of off-white, and added some box-shadow values in order to give it the depth that it required. I layered another div over the upper area of this, with very low opacity in order to create a shadow effect that would be cast by the upper socket. Finally, in order to replicate the caruncle (the small pink / red corner that is present in the human eye), I placed one more div — pinkish in colour — in the left corner of the sclera, with a strong box-shadow effect in order to create the effect of its fluid texture.

The upper and lower eye lashes were created as sets of long lists. In a similar manner to the iris axes, transform was used heavily in order to create the desired effects.

For the skin and upper cheek, a number of layered divs were added with box-shadow and linear-gradient, again to create an impression of some depth.

A simple eye was no good on its own. It needed some context. The natural solution seemed to be to place it within a peep-hole, and a wooden fence provided a good opportunity for this. Suddenly, the eye became that of a ‘Peeping Tom’ and a subtle animation of the iris would only enhance that. This was achieved through a straight-forward @keyframes rule. And with that, the job was done.

Having finally attempted to get properly artistic with CSS, I am pleased with the outcome. Whilst I have been able to leverage many of the nicer features of the technology, I have seen how its limitations need to be overcome through some creativity. However, the capabilities of the technology are a pleasure to take advantage of and determining that I use CSS exclusively and with no image files or JavaScript was a nice challenge. I look forward to creating some more visuals in the future.

--

--