Moving From Flash To HTML, CSS, And JavaScript

Back in the 2000s, it was commonplace to see websites that were built using Flash. By viewing the source of a website, you’d often see very little HTML and an embedded SWF file. This meant a few things. First, the browser didn’t natively support Flash, so you had to download the Flash plugin. Browsers found it difficult to go into the SWF to read content. Amongst other things, this had a detrimental affect on SEO and accessibility.

In 2007, the iPhone was released. It didn’t support Flash. In 2015, Google moved all its YouTube videos to HTML5. In July 2017, Adobe officially announced it would stop working on Flash by 2020. People used Flash because it could do things that HTML, CSS, and JavaScript couldn’t do at the time. It’s incredible to see how far web standards have come (and what’s coming).

We can do a lot today that was previously only possible with Flash. Not only that, but we can do it in a way that’s far more accessible and performant. I’ll go over some of the groundbreaking things Flash could do and how we can go about doing them today.

Disclaimer: I love Flash, and it will always have a place in my heart, but for me at least, its time has passed. Just in case you’re wondering: there are still so many interfaces and engines running in Flash, especially for games, and this article addresses some of the issues that are very relevant there.


One of the great things Flash heralded was video, offering basic support as early as 2002. It wasn’t until 2009 that the <video> tag was introduced in Chrome, Safari, and Firefox. Furthermore, Internet Explorer (IE) 8 didn’t support the <video> tag, and it wasn’t until 2011, when IE 9 was released, that it got support.

Flash would use the <object> tag, like so:

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase=",0,16,0" width="320" height="400">
  <param name="movie" value="filename.swf">
  <param name="quality" value="high">
  <param name="play" value="true">
  <param name="LOOP" value="false">
  <embed src="video-filename.swf" width="320" height="400" play="true" loop="false" quality="high" pluginspage="" type="application/x-shockwave-flash"></embed>

Not the nicest of code, but it did work.

Now, we can simply write <video src="filename.mp4" />, although it is important to be aware of different video formats across browsers, the most popular being MP4, Ogg and WebM. Taking things a step further, it’s possible not only to support the <video> tag, but also offer fallbacks and helpful alternatives:

<video width="320" height="400">
<source src="filename.mp4" type="video/mp4" />
<source src="filename.webm" type="video/webm" />
<source src="filename.ogv" type="video/ogg" />

<!-- Flash fallback -->
<object type="application/x-shockwave-flash" data="flash-player.swf?videoUrl=filename.mp4" width="320" height="400">
  <param name="movie" value="flash-player.swf?videoUrl=filename.mp4" />
  <param name="allowfullscreen" value="true" />
  <param name="wmode" value="transparent" />
  <param name="flashvars" value="controlbar=over&image=placeholder.jpg&file=flash-player.swf?videoUrl=filename.mp4" />

  <!-- Text Fallback -->
  <p>No video support found. Please download the video below, or upgrade your browser:</p>

  <li><a href="linktomovie.mp4">MP4 format</a></li>
  <li><a href="linktomovie.ogv">Ogg format</a></li>
  <li><a href="linktomovie.webm">WebM format</a></li>

Video Background

Because YouTube makes use of the <video> tag and has an API, it’s possible to create a full-screen background video. Take the following YouTube video link code, for example:

Using the different parameters it’s possible to change the way the video behaves.

controls=0 Hides the controls.
showinfo=0 Hides extra information.
rel=0 Hides related content.
autoplay=1 Auto plays the video when the site is loaded.
loop=1 Loops the video.
mute=1 Mutes the sound.

For a full list, check the IFrame Player API.

Using CSS, we can set the video to be fixed in position and to fill the screen.

.video {
  background: #000;
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: -1;
  pointer-events: none;

And with the use of media queries, we can set the video to be centered and can help keep the correct aspect ratio.

@media (min-aspect-ratio: 16/9) {
  .video {
    height: 300%;
    top: -100%;

@media (max-aspect-ratio: 16/9) {
  .video {
    width: 300%;
    left: -100%;

Here’s the example put together, with Mr. Smashing Magazine himself presenting a talk:

See the Pen Video Background Demo Using YouTube by Simon Owen (@s10wen) on CodePen.

Interaction And Gaming

Another thing Flash excelled at was interaction and gaming. The popular website Miniclip was founded in 2001 and hosted a wide range of Flash games. In 2008, it was valued at over £900 million and is still going today.


JUST A REFLEKTOR is an interactive music video that rivals and even surpasses the capabilities of Flash. With the use of various web technologies, it’s now possible to interact with the video using a mobile device, as well as at one point using your webcam so that you actually appeared in the music video yourself!

Just A Reflektor
The website Just A Reflektor makes great use of modern web technologies to create an interactive music video.

Cube Slam

There’s some fantastic web-based Chrome experiments online today, such as Cube Slam. Cube Slam is a game that makes use of WebRTC (an open web technology), letting you video chat and play a game within the browser. Although Flash was heavily used for video chat, it came with a number of drawbacks compared to WebRTC: It relied on the Flash plugin, it required a media server, and it had various security implications and poor performance.

Cube Slam
Cube Slam is a web based Chrome Experiment that allows video chat whilst playing a game.

HTML5 Game Engines

There are a number of HTML5 and JavaScript game engines. This next example makes use of canvas and WebGL. WebGL (Web Graphics Library) is an API built in JavaScript that allows interactive 2D and 3D graphics within the <canvas> tag.

As mentioned in Good Boy Digital’s own post regarding the project (the creators of the example):

"Star Wars Arcade really pushes the boundaries of what’s possible with HTML5 and WebGL technologies. This allows for the creation of a single build that works seamlessly on both desktop and mobile browsers without having to download an app; the advantage of this being able to offer an ‘app like’ experience on all devices so anyone can enjoy it, instantly. No passwords, no App Stores, just hit the URL and play!"

goodboy digital, Star Wars Arcade Case Study

I especially love this bit: “Just hit the URL and play!” One of my earliest “Wow” memories of the web was having my own website in 1999 and being able to type that URL into any computer connected to the web and view it. It seemed absolutely incredible to me that this was actually possible (and continues to amaze me to this day!).

Browser Support

One of the advantages of building something—especially a game, due to the extra complexity—in Flash that is still relevant today is browser support. Browser support is generally pretty good these days, and Can I Use can help us to quickly find out about the state of browser support for a particular specification. However, there are still discrepancies that could cause issues. So, if you’re OK with only supporting browsers that are installed with the Flash plugin you’re working with, then you’re likely not to encounter any cross-browser issues.


Flash was originally designed as an animation tool. As such, it had various limitations with typography.

Flash had a pixel-grid system. If typography was laid on the grid at X:100.3 :100.7 and, thus, out of alignment to the pixel grid, it would look blurred.

As a result, I found that pixel fonts were useful because they sat on the grid and remained crisp. Another limitation here would be if you used an 8-pixel font but set it to 10 pixels, it would go out of alignment with the grid and, again, be blurred.

Thankfully, today in HTML and CSS, we have a host of tools to help us. We can set fonts as an absolute unit in px (pixels) or, more common these days, use ems and rems to aid with responsive web design (I’ll be covering more on this later).

Another issue with Flash and typography was fonts. If a font wasn’t available on the device, a fallback font would be provided. To circumvent this in Flash, you could embed the font in the .swf file. By doing this, though, you added to the file size and, thus, the time that the SWF would take to download and appear.

That being said, what was possible with Flash was Scalable Inman Flash Replacement (sIFR). sIFR allowed HTML text to be replaced with Flash. Before this, in order to use custom fonts, we used images. However, using images didn’t allow for selectable text, and it meant you had to create images manually. Moving on from sIFR, developers came up with Cufón. Cufón avoided the use of Flash by using an SVG and VML version of a font. It was faster than sIFR and didn’t require the Flash plugin; but, again, with this technique, it wasn’t possible to select text.

Today, we have the CSS @font-face rule and a host of standard web fonts available:

In Chrome and Firefox (and, hopefully soon, Safari), we have font-display in CSS. If you’re using a custom font, by default the browser will wait to get the custom font. If it can’t get the custom font, it will use a backup font (the speed varies among browsers, but it is usually 3 seconds). This is known as a flash of invisible text (or FOIT). To improve this scenario, we can use the following:

@font-face {
  font-display: swap;

By using swap, we’ll see the text immediately using the backup font. When the custom font is loaded, the browser will swap the backup for it. This way, the user gets to read the content as soon as it’s available.


One of the things that Flash did very well was tweening. Tweening is used to animate elements. In Flash, you could create an element in a keyframe, duplicate that keyframe along the timeline, and then add a tween.

With HTML and CSS, we can apply the same animation using @keyframes, transform and animation.

<div class="box"></div>
.box {
  width: 100px;
  height: 100px;
  background-color: #333;

@keyframes move {
  from {
    transform: translateX(0);

  to {
    transform: translateX(200px);

div {
  animation-duration: 3s;
  animation-name: move;
  animation-iteration-count: infinite;
  animation-direction: alternate;

See the Pen CSS Animation Example by Simon Owen (@s10wen) on CodePen.

With Chrome Developer Tools, we can inspect and adjust the animation by going to Chrome Dev Tools ? Cmd + Shift + P ? Animation.

Chrome Developer Tool’s 'Performance' tab.
An example showing Chrome Developer Tool’s 'Performance' tab.

It’s also possible to debug potential performance issues that may arise when dealing with animation. In Chrome Developer Tools, there’s a “Performance” tab. By clicking this, then the “Record” circle icon, we can see a range of useful information. This technique greatly helped me when I built Mind’s Annual Report 2012-13, particularly the section of the website that has a map with animated circles showing the locations of Mind shops. Initially, the map section was loaded at the start, which caused repaint issues. Using the “Performance” tab, I was able to identify and update this, so the map only started animating when it was in view.

Vector Graphics

The web has benefitted and still does benefit enormously from careful consideration of file size. Back in the early 2000s, the web was mostly viewed on desktop computers, with slow dial-up modems. A simple image could take seconds or even minutes to load. To help with this, Flash made heavy use of vector graphics. Using vector graphics, where appropriate, instead of JPEG or GIF images, significantly reduced file size and thus load more quickly over the web.

Over the past few years, and particularly thanks to Sara Soueidan, scalable vector graphics (SVGs) have become more and more widespread on the web. SVG is an XML-based markup that enables us to create vector graphics for the web. It works extremely well with animation and I’ve had the pleasure of building some websites that make use of this: the Mind report website (previously mentioned) and How Clean Is England? which Sara mentioned on Twitter! Thanks Sara!

Mind’s Annual Report website made use of SVGs and animation to create a fun way to display their statistics for the year.
The How Clean Is England? website was heavily based on illustration. SVGs and CSS animations helped to make the illustrations look crisp and keep file sizes to a minimum.

Responsive Web Design

One of the main pitfalls of building a website in Flash today is the lack of media queries. Today, mobile and tablet usage has surpassed that of desktop. In order to create the best experience, we must create a website that is accessible on all of these devices. On many devices, Flash will simply not load at all, and even if it did, it would most likely breach the viewport’s width or would scale and be unusable.

Using media queries, we can create a layout that responds to the content. Here’s an example:

<div class="someContent">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est excepturi enim id ratione blanditiis voluptate dolore necessitatibus culpa maxime eius assumenda eveniet dolores odit sunt repellat, rerum amet delectus vel.</p>
.someContent {
  color: green;
@media screen and (min-width: 400px) {
  .someContent {
    color: yellow;
@media screen and (min-width: 600px) {
  .someContent {
    color: red;

See the Pen Simple Media Query Example by Simon Owen (@s10wen) on CodePen.

ActionScript vs. JavaScript

ActionScript is used in Flash and, thus, has the same pitfall of SWF files mentioned earlier, in that it requires the Flash plugin. JavaScript, on the other hand, is readily available in all modern browsers.

Let’s look at an example of setting a variable in both and their differences:

var x:Number = 42;
var x = 42;

With ActionScript, we declare that the variable is a number. If the variable is assigned anything else, it will get an error. JavaScript is loosely typed, which means we could assign the variable as something else, such as a string:

var x = '42';

In JavaScript, if we wanted to check that it is a number, we could use typeof(x);, and this would output “number”. Another option would be to create a function and use isNaN to detect whether it is “not a number”:

function isNumber(value) {
  if (isNaN(value)) {
    return value + ' is not a number.';
  return value + ' is a number.';

console.log(isNumber(42)); // "42 is a number."
console.log(isNumber('forty two')); // "forty two is not a number."


With HTML, CSS, and JavaScript (and many other coding languages), Git and GitHub make collaboration extremely easy. For example, if I wanted to edit the HTML of Smashing Magazine’s “Author Template,” via GitHub, I could click the “Fork” button. This would create a version of the files (also known as the repository) under my own name. I could then make any amendments I like and submit a pull request. This would give the owner at Smashing Magazine the ability to review my pull request and accept or reject it. Once accepted, the code would go in the main repository.

There are a number of great reasons for working in this way: You always have a backup of your work; you can revert to previous versions of your work, and collaboration becomes very easy. Someone could be working on one section of the website, or on the CSS or JavaScript, and when each team member has finished, you could review the changes and pull them in as required.

If we tried the same with Flash, it would be a lot more difficult having to save and send an .fla file each time. If multiple people were to work on the same .fla, things could get very confusing. With HTML, CSS and JavaScript, it’s’ possible to do a “diff” on the code, which allows us to compare and review the code. We can even select certain code chunks, bring them in, or comment on them for further review and work.


Flash was one of the reasons I started building websites. It pioneered in a lot of areas, and this led to people creating amazing things with it. Over the years, it’s pushed the web forward a great deal. Adobe’s official announcement of dropping support of Flash, though, does raise concerns. It would be a massive shame if millions of websites using Flash were lost. There’s a petition to open source Flash and Shockwave. I do hope we don’t lose it forever. We’ve had some great — and weird — times. I’ll leave you with this classic example of the “weird” to which I refer:

Here are the lyrics, if you’d like to sing along.

Smashing Editorial (ra, hj, al, il)

Leave a Reply

Your email address will not be published. Required fields are marked *