DEV Community

Cover image for Bubble Sort...in PURE CSS? [No JS] ๐Ÿ˜ฑ
GrahamTheDev
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;

Enter fullscreen mode Exit fullscreen mode

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));
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

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)); 
Enter fullscreen mode Exit fullscreen mode

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));
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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! ๐Ÿคฃ๐Ÿ’—

Top comments (24)

Collapse
 
savvasstephnds profile image
Savvas Stephanides

Bogosort next ๐Ÿ”ฅ

Collapse
 
zippcodder profile image
Deon Rich

Canvas of babel with pure CSS ๐Ÿ˜‚

Collapse
 
grahamthedev profile image
GrahamTheDev

Haha, that scares even me! ๐Ÿคฃ๐Ÿ’—

Collapse
 
grahamthedev profile image
GrahamTheDev

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

Fun idea though! ๐Ÿคฃ๐Ÿ’—

Collapse
 
savvasstephnds profile image
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 ๐Ÿ˜…๐Ÿ˜…๐Ÿ˜…

Thread Thread
 
grahamthedev profile image
GrahamTheDev

Anywhere from O(1) to O(infinity) ๐Ÿคฃ๐Ÿ’—

Thread Thread
 
tanzimhossain2 profile image
Tanzim Hossain

๐Ÿ˜

Collapse
 
aminmansuri profile image
hidden_dude

You sir are an evil genius..

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

Collapse
 
link2twenty profile image
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 ๐Ÿ˜‰

Collapse
 
grahamthedev profile image
GrahamTheDev

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

Collapse
 
tanzimhossain2 profile image
Tanzim Hossain

What about the time complexity for this?

Collapse
 
grahamthedev profile image
GrahamTheDev

O(n2) it is just bubble sort! ๐Ÿคฃ๐Ÿ’—

Collapse
 
tanzimhossain2 profile image
Tanzim Hossain

๐Ÿ‘Œโค๏ธ

Collapse
 
maxfindel profile image
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) ๐Ÿ˜†

Collapse
 
tylim88 profile image
Acid Coder

No way๐Ÿ’€

Collapse
 
mangor1no profile image
Mangor1no

aint no way bruh...

Collapse
 
grahamthedev profile image
GrahamTheDev

Waaaay doood! ๐Ÿคฃ๐Ÿ’—

Collapse
 
commonsenseal profile image
Albert Wiersch

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

Collapse
 
grahamthedev profile image
GrahamTheDev

My CSS is always valid...even the stuff that isn't useful like this! ๐Ÿคฃ๐Ÿ’—

Collapse
 
zippcodder profile image
Deon Rich

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

Collapse
 
grahamthedev profile image
GrahamTheDev

Yeah, but at the same time, it is far less stressful to do it in a proper language! ๐Ÿคฃ๐Ÿ’—

Collapse
 
loremimpsu profile image
Lorem Impsu

ow congrats, great post!

Collapse
 
grahamthedev profile image
GrahamTheDev

๐Ÿ™๐Ÿผ๐Ÿ’—

Collapse
 
grahamthedev profile image
GrahamTheDev

Ooohhh, we are number 9 in the series!

Number 10 should be fun...Conway's game of life...in pure HTML! ๐Ÿคฃ๐Ÿ’—