GrahamTheDev

Posted on

# Bubble Sort...in PURE CSS? [No JS] ๐ฑ

Imagine you are in an interview and you get asked "can you implement bubble sort"...and you answer the interviewer "sure, do you want that in JavaScript or CSS".

What a flex would that be?

Now, I know what you are thinking. "no interviewer will be impressed by you creating an animation that simulates bubble sort". And you would be right!

But what if we could create a functioning bubble sort algorithm...in pure CSS...and add visualisations to it?

Well, you have come to the right place!

## The Demo

Instructions: There are 5 values at the top of the `:root` element:

``````:root{
--val1: 12;
--val2: 16;
--val3: 9;
--val4: 14;
--val5: 7;

``````

These are our unsorted array!

So the above represents: `[12,16,9,14,7]`.

And you can change those values (any value between 0 and 20) and then press "run" in the Codepen UI and it will actually sort them for you!

warning: on mobile the last few animations might not play and just go blank. On PC your fan may spin up!

This is a limitation of using so many calculations that rely on previous calculations...I am not sure if it runs out of memory or what, but I defo pushed the limits of CSS here!

Anyway, with the warnings out of the way, give it a go (you may need to press "rerun" in the bottom right as the animation only plays once)!

## Explanation

Look, this is silly, so I am not going to do a tutorial, but there are a couple of things that are interesting:

### Getting a boolean for v2 > v1

``````--is-1-greater-2-step-1: Min(1, Max(var(--arr1s0) - var(--arr2s0), 0));
``````

Looks complicated, but it isn't, we are performing the following operations:

• subtract the value of position 2 from the value of position 1 in our array. (lets call this "diff1and2" for ease)
• find the maximum of "diff1and2" and 0. We do this as a way of saying "if 1 is bigger than 2, we want a positive value, but if 2 is bigger than 1 we want to return 0". Lets call the result of this "1greaterOrZero".
• then we take "OneGreaterOrZero " and make sure it is not greater than 1 by using `Min`. So if "OneGreaterOrZero" was 6, we would reduce that to 1, but if it was 0 then we would return 0.

Still confused? Here it is in JS effectively:

``````let pos1 = 7;
let pos2 = 15;

let diff1and2 = pos1 - pos2;
//if "diff1and2" is negative the next step will change it to 0;
let OneGreaterOrZero = Math.max(diff1and2, 0);

let result = Math.min(1, OneGreaterOrZero);

console.log(diff1and2, OneGreaterOrZero, result); //always between 0 and 1 as false / true representation.
``````

### swapping array positions

So how do we swap positions in our "array"?

For bubble sort to work we need to be able to swap 2 values if the first value is larger than the second.

We can't do any temp variable magic like we would in JS.

Well, that is what this is for:

``````--arr1s1: calc(var(--is-2-greater-1-step-1) * var(--arr1s0) + var(--is-1-greater-2-step-1) * var(--arr2s0));
--arr2s1: calc(var(--is-1-greater-2-step-1) * var(--arr1s0) + var(--is-2-greater-1-step-1) * var(--arr2s0));
``````

Yet again, looks complicated, is actually reasonably simple in principle.

In our previous "function", we created a boolean to see if 1 was greater than 2. So we have either a 1 or a 0 there.

We can also easily get the inverse of this:

``````--is-2-greater-1-step-1: (1 - var(--is-1-greater-2-step-1));
``````

The beauty of this is that we can now do the following trick:

``````
// in bubble sort, if 1
origArray = [7,2];

// we run our previous functions to get our 2 variables:

oneIsGreater = 1;
twoIsGreater = 0;

// we can now multiply the values together. If [2] is greater than one then we will return the same value. But if [1] is greater than [2] then we will swap the values.

newArray[0] = (twoIsGreater * origArray[0]) + (oneIsGreater * origArray[1]);
newArray[1] = (oneIsGreater * origArray[0]) + (twoIsGreater * origArray[1]);

// which is the same as this:
newArray[0] = 0 * 7 + 1 * 2;  //2
newArray[1] = 1 * 7 + 0 * 2;  //7

``````

Neat trick huh? and if `oneIsGreater` and `twoIsGreater` were swapped then it would just return the original values!

``````origArray = [7,2];
oneIsGreater = 0;
twoIsGreater = 1;

//same "function"
newArray[0] = (twoIsGreater * origArray[0]) + (oneIsGreater * origArray[1]);
newArray[1] = (oneIsGreater * origArray[0]) + (twoIsGreater * origArray[1]);

// which is the same as this:
newArray[0] = 1 * 7 + 0 * 2;  //7
newArray[1] = 0 * 7 + 1 * 2;  //2

``````

And that is effectively all we need to do a bubble sort!

The only reason we have so much CSS is because we cannot do loops in vanilla CSS (yet). So we have to manually write out the swaps for each stage of bubble sort:

• check and if needed swap 1 and 2
• check and if needed swap 2 and 3
• check and if needed swap 3 and 4
• check and if needed swap 4 and 5
• check and if needed swap 1 and 2
• check and if needed swap 2 and 3
• check and if needed swap 3 and 4
• check and if needed swap 1 and 2
• check and if needed swap 2 and 3
• check and if needed swap 1 and 2

## That's all folks!

As I said, not a tutorial. But I did want to introduce some interesting CSS "switches" and "booleans" that may become useful in some strange scenario in the future for you!

I hope you enjoy my silliness.

Now I just have to wait for someone to ask me if I can implement Bubble sort so I can flex on them with my CSS silliness! ๐คฃ๐

Savvas Stephanides

Bogosort next ๐ฅ

Deon Rich

Canvas of babel with pure CSS ๐

GrahamTheDev

Haha, that scares even me! ๐คฃ๐

GrahamTheDev

Haha, I might actually do it. Although I may run into a limitation on the number of iterations etc.

Fun idea though! ๐คฃ๐

Savvas Stephanides

Or, if you're lucky enough, it might all get sorted in the first try. Literally the only sorting algorithm that has the potential to do so ๐๐๐

GrahamTheDev

Anywhere from O(1) to O(infinity) ๐คฃ๐

Tanzim Hossain

๐

hidden_dude

You sir are an evil genius..

Next up we expect to see your implementation of Doom in CSS.

Andrew Bone

๐ if this was a valid reaction I'd have used it rather than heart.

There is a proposal for css var arrays (with CSS random too) so you might have to revisit this someday ๐

GrahamTheDev

Yeah that would probably make this 200 times easier and actually performant...but then it wouldn't be fun anymore! ๐คฃ๐

Tanzim Hossain

What about the time complexity for this?

GrahamTheDev

O(n2) it is just bubble sort! ๐คฃ๐

Tanzim Hossain

๐โค๏ธ

Max F. Findel

This is amazing ๐คฏ I'm impressed that you didn't mess up that very copy&paste-intensive code (if you did, I bet it was hell to debug) ๐

Acid Coder

No way๐

Mangor1no

aint no way bruh...

GrahamTheDev

Waaaay doood! ๐คฃ๐

Albert Wiersch

Wow... that is crazy but also impressive, and all that CSS even passes CSS HTML Validator with no errors!

GrahamTheDev

My CSS is always valid...even the stuff that isn't useful like this! ๐คฃ๐

Deon Rich

Wow thats insane!! Fascinating post!! You can definitley do some cool stuff with CSS if you know what you're doing!

GrahamTheDev

Yeah, but at the same time, it is far less stressful to do it in a proper language! ๐คฃ๐

Lorem Impsu

ow congrats, great post!

GrahamTheDev

๐๐ผ๐

GrahamTheDev

Ooohhh, we are number 9 in the series!

Number 10 should be fun...Conway's game of life...in pure HTML! ๐คฃ๐