Skip to main content
1 of 7

FizzBuzz... with style (js, jquery, html, css)

I discovered the FizzBuzz test while looking up something else on stackoverflow, so I decided to try it and see what I would come up with. I'm kind of new to jquery and js, so I'm looking for a critique on my code. What can I do better? Changes? Simplifications?

My priorities on this were -

  1. Maintainability & readability
  2. A page that was responsive to browser resizing & different screen sizes
  3. Presenting it in a nice format without overdoing it. I came up with a simple, 4 column static version in about 45 minutes, but then refactored and styled it quite a bit.

I put the entire thing on CodePen so you can see it (resize it!) ...

http://codepen.io/AlessiaNyx/full/reQeER/

One additional note. I used the defer attribute in my script tag and put it in the head.

    <script src="fizzbuzz.js" charset="utf-8" defer="defer"></script>

Is that acceptable? Is there a better way?

Here's a copy of the code (I'm leaving out the html, head tags, etc.).

JAVASCRIPT:

var fizzContainer = $("div.number-container");

var divisor1 = 3,
divisor2 = 5,
maxFizz = 100,
word1 = "Fizz",
word2 = "Buzz",
windowWidth = window.innerWidth,
minNumOfColumns = 1,
maxNumOfColumns = 12,
widthPerColumn = 150,
columns,
linesPerColumn,
columnSizingParameters = {};

calculateHeading(windowWidth);
calculateColumns();

$(window).resize(function(){
   windowWidth = window.innerWidth;
   calculateHeading(windowWidth);

   $(".number-container").replaceWith("<div class='number-container'></div>");
   calculateColumns();
});

function calculateHeading(windowSize) {
   if(windowSize <= 500) {
      $("h1").attr("class", "transition xSmallHeading");
   } else if (windowSize <= 700) {
      $("h1").attr("class", "transition smallHeading");
   } else if (windowSize <= 1000) {
      $("h1").attr("class", "transition mediumHeading");
   } else if (windowSize >= 1000) {
      $("h1").attr("class", "transition largeHeading");
   }
}

function calculateColumns() {
    var columnIt = minNumOfColumns;
    for (columnIt; columnIt <= maxNumOfColumns; columnIt++) {
        columnSizingParameters[columnIt] = columnIt * widthPerColumn;
    }

    for (var i = 1; i <= maxNumOfColumns; i++) {
        if ((windowWidth >= columnSizingParameters[i]) && (windowWidth <= columnSizingParameters[i + 1])) {
            columns = i;
        }
    }
    linesPerColumn = Math.ceil(maxFizz / columns);
    createNumbers();
}

function createNumbers() {
    var i = 1;

    for (var c = 1; c <= columns; c++) {
        var col = $('<div></div').appendTo(".number-container");
        col.addClass('column');

        for (var a = 1; a <= linesPerColumn && i <= maxFizz; a++, i++) {
            if ((i % divisor1 === 0) && (i % divisor2 === 0)) {
                createContentLine(word1 + word2, "double-match", col, i, true);
                continue;
            } else if (i % divisor1 === 0) {
                createContentLine(word1, "match-1", col, i, true);
                continue;
            } else if (i % divisor2 === 0) {
                createContentLine(word2, "match-2", col, i, true);
                continue;
            } else {
                createContentLine(i, "num", col, i, false);
                continue;
            }
        }
    }
}

function createContentLine(toPrint, cssClass, col, i, appendNumToWord) {
    var contentLine = $("<p>" + toPrint + "</p>").appendTo(col);
    contentLine.addClass(cssClass);

    if (appendNumToWord) {
        var appendedNumber = $("<span></span").appendTo(contentLine);
        appendedNumber.text(" • " + i).addClass("num");
    }
}

HTML:

    <div class="container">

        <h1>The fizzbuzz test...in Javascript!</h1>

        <div class="number-container">

        </div>
    </div>

CSS:

* {
   padding: 0px;
   margin: 0px;
   box-sizing: border-box;
}

.container {
   width: auto;
   height: 100%;
   display: block;

}

h1 {
   display: block;
   background-color: black;
   color: white;
   width: 100%;
   font-family: 'Berkshire Swash', cursive;
}

.transition {
   transition: 500ms;
}

/* Screen width Less than 500px */
.xSmallHeading {
   font-size: 25px;
   line-height: 25px;
   padding: 15px;
}
/* Less than 700px */
.smallHeading {
   font-size: 32px;
   line-height: 32px;
   padding: 20px;
}

/* Less than 1000px */
.mediumHeading {
   font-size: 40px;
   line-height: 40px;
   padding: 30px;
   margin-bottom: 10px;
}

/* Greater than 1000px */
.largeHeading {
   font-size: 50px;
   line-height: 50px;
   padding: 40px;
   margin-bottom: 20px;
}

.number-container {
   display: flex;
   margin-top: 20px;
   margin-bottom: 20px;
   text-align: center;
   line-height: 30px;
   width: 100%;
   height: calc(100% - 150px);
}

.column {
   flex-grow: 1;
   display: inline-block;
   border-right: 1px solid lightblue;
}

.column:last-of-type {
   border-right: none;
}

.num {
   color: #585858;
   font-weight: bold;
   font-style: normal;
   font-family: sans-serif;
   font-size: 12px;
}

.double-match {
   font-weight: 600;
   font-size: 20px;
   color: #3f89d6;
   font-family: 'Crimson Text', serif;
}

.match-1, .match-2 {
   font-family: 'Josefin Slab', serif;
   font-weight: 700;
   font-size: 18px;
}

.match-1 {
   color: #7ac962;
}

.match-2 {
   color: #ba62d4
}

thanks in advance!