How I made a Background Color Flipper app in vanilla javascript
Tags: javascript, beginners, programming, tutorial
Published: 2022-01-27 01:28:54

In this blog i will talk about how I built a Color Flipper in javascript. Lets get started.

Im going to be using Code Sandbox as my editor, you can use any editor of your choice.

Lets start with the code sandbox vanilla javascript template. First lets write down our html markup for out home home page

`index.html`

```jsx
<!DOCTYPE html>
<html>
  <head>
    <title>Collor Filpper</title>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="src/styles.css" />
  </head>

  <body>
    <nav>
      <div class="nav-center">
        <h4>Color Filpper</h4>
        <ul class="nav-links">
          <li><a href="index.html">Simple</a></li>
          <li><a href="hex-color.html">Hex Color</a></li>
        </ul>
      </div>
    </nav>
    <main>
      <div class="container">
        <h2>background color : <span class="color">#f1f5f8</span></h2>
        <button class="button button-hero">Click Me</button>
      </div>
    </main>
// index.js is the js file
    <script src="src/index.js"></script>
  </body>
</html>
```

We are going to have two pages 

- a) for generating random background colors from a list provided
- b) for generating random hex background colors

Above in `index.html` we have a nav and a main section and we have defined classes that we will use shortly to style our app.

Lets make a page for the hex-color page as well , I’m going to call it `hex-html.html`

This is similar to our home page only we link a diff javascript file to this page 

`hex-color.html`

```jsx
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Color Flipper | Hex Color</title>
    <link rel="stylesheet" href="src/styles.css" />
  </head>
  <body>
    <nav>
      <div class="nav-center">
        <h4>Color Filpper</h4>
        <ul class="nav-links">
          <li><a href="index.html">Simple</a></li>
          <li><a href="">Hex Color</a></li>
        </ul>
      </div>
    </nav>
    <main>
      <div class="container">
        <h2>background color : <span class="color">#f1f5f8</span></h2>
        <button class="button button-hero">Click Me</button>
      </div>
    </main>

// hex.js is the js file
    <script src="src/hex-color.js"></script>
  </body>
</html>
```

After we are done with the mark up lets quickly write down our css

`styles.css`

```jsx
/*
Fonts
*/
@import url("https://fonts.googleapis.com/css?family=Open+Sans|Roboto:400,700&display=swap");

/*
 root variables (it is a good practice to define root values, so it is eay to change them if we need to )
*/

:root {
  /* dark shades of primary color*/
  --primary-1: hsl(205, 86%, 17%);
  --primary-2: hsl(205, 77%, 27%);
  --primary-3: hsl(205, 72%, 37%);
  --primary-4: hsl(205, 63%, 48%);
  /* primary/main color */
  --primary-5: hsl(205, 78%, 60%);
  /* lighter shades of primary color */
  --primary-6: hsl(205, 89%, 70%);
  --primary-7: hsl(205, 90%, 76%);
  --primary-8: hsl(205, 86%, 81%);
  --primary-9: hsl(205, 90%, 88%);
  --primary-10: hsl(205, 100%, 96%);
  /* darkest grey - used for headings */
  --grey-1: hsl(209, 61%, 16%);
  --grey-2: hsl(211, 39%, 23%);
  --grey-3: hsl(209, 34%, 30%);
  --grey-4: hsl(209, 28%, 39%);
  /* grey used for paragraphs */
  --grey-5: hsl(210, 22%, 49%);
  --grey-6: hsl(209, 23%, 60%);
  --grey-7: hsl(211, 27%, 70%);
  --grey-8: hsl(210, 31%, 80%);
  --grey-9: hsl(212, 33%, 89%);
  --grey-10: hsl(210, 36%, 96%);
  --white: #fff;
  --red-dark: hsl(360, 67%, 44%);
  --red-light: hsl(360, 71%, 66%);
  --green-dark: hsl(125, 67%, 44%);
  --green-light: hsl(125, 71%, 66%);
  --black: #222;
  --fontFamily-primary: "Roboto", sans-serif;
  --fontFamily-secondary: "Open Sans", sans-serif;
  --transition: all 0.3s linear;
  --spacing: 0.1rem;
  --radius: 0.25rem;
  --light-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
  --dark-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
  --max-width: 1170px;
  --fixed-width: 620px;
}
/*
=============== 
Global Styles
===============
*/

*,
::after,
::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  font-family: var(--fontFamily-secondary);
  background: var(--grey-10);
  color: var(--grey-1);
  line-height: 1.5;
  font-size: 0.875rem; //14px
}
ul {
  list-style-type: none;
}
a {
  text-decoration: none;
}
h1,
h2,
h3,
h4 {
  letter-spacing: var(--spacing);
  text-transform: capitalize;
  line-height: 1.25;
  margin-bottom: 0.75rem;  // 12px
  font-family: var(--fontFamily-primary);
}
h1 {
  font-size: 3rem; 
}
h2 {
  font-size: 2rem;
}
h3 {
  font-size: 1.25rem;
}
h4 {
  font-size: 0.875rem;
}
p {
  margin-bottom: 1.25rem;
  color: var(--grey-5);
}

/*  global classes */

/* section */
.section {
  padding: 5rem 0;
}

.section-center {
  width: 90vw;
  margin: 0 auto;
  max-width: 1170px;
}
@media screen and (min-width: 992px) {
  .section-center {
    width: 95vw;
  }
}

main {
  min-height: 100vh;
  display: grid;
  place-items: center;
}

/*
Nav
*/

nav {
  background: var(--white);
  height: 3rem;
  display: grid; //using grid to center content
  align-items: center; 
  box-shadow: var(--dark-shadow);
}
.nav-center {
  width: 90vw;
  max-width: var(--fixed-width);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.nav-center h4 {
  margin-bottom: 0;
  color: var(--primary-5);
}
.nav-links {
  display: flex;
}
nav a {
  text-transform: capitalize;
  font-weight: 700;
  font-size: 1rem;
  color: var(--primary-1);
  letter-spacing: var(--spacing);
  margin-right: 1rem;
}
nav a:hover {
  color: var(--primary-5);
}
/*
=============== 
Container
===============
*/
main {
  min-height: calc(100vh - 3rem);
  display: grid;
  place-items: center;
}
.container {
  text-align: center;
}
.container h2 {
  color: var(--white);
  padding: 1rem;
  border-radius: var(--radius);
  background: var(--black);
  margin-bottom: 2.5rem;
}
.color {
  color: var(--primary-5);
}
.button-hero {
border: 2px solid var(--black);
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
  border-radius: var(--radius);
  font-size: 1rem;
  padding: 0.75rem 1.25rem;
  font-family: var(--fontFamily-primary);
  text-transform: uppercase;
  background: transparent;
  color: var(--black);
  letter-spacing: var(--spacing);
  display: inline-block;
  font-weight: 700;
  transition: var(--transition);
  
}
.button-hero:hover {
  color: var(--white);
  background: var(--black);
}
```

Above we have 

- first imported our font , you can do that from google font, the font I have choose is Roboto
- then we define our root styles , its a good practice to define root styles so its easy to change them later if we need to
- then we defined some global styles and then styled our nav and container

Now lets write the javascript for the background colors generated from a list of given colors 

given list of colors `"green", "red", "rgba(133,122,200)", "#f15025", "orange", "blue"`

`index.js`

```jsx
// list of colors
const colors = ["green", "red", "rgba(133,122,200)", "#f15025", "orange", "blue"];
const button = document.querySelector("button"); //referencing to class button
const color = document.querySelector(".color"); //referencing to color button

// adding a click event listener to the button
button.addEventListener("click", () => {
  const randomNumber = getRandomNumber();
  console.log(randomNumber);

  document.body.style.backgroundColor = colors[randomNumber];
  color.textContent = colors[randomNumber];
});

// will return a random number from the colors array
const getRandomNumber = () => Math.floor(Math.random() * colors.length);
```

- `document.body.style.backgroundColor` : we use the DOM `style` property. The `style` property returns a CSSStyleDeclaration object, which represents an element's style attribute. The style property is used to get or set a specific style of an element using different CSS properties.

- `textContent` : The textContent property sets or returns the text content of the specified node, **and all its descendants**. If you *set* the textContent property, any child nodes are removed and replaced by a single Text node containing the specified string

`examples`

```jsx
<div id="div">This is <span>some</span> text!</div>

let text = document.getElementById('div').textContent;
// The text variable is now: 'This is some text!'
```

- `Math.floor()` : The **`Math.floor()`** function returns the largest integer less than or equal to a given number.

`examples`

```jsx
console.log(Math.floor(5.95));
// expected output: 5

console.log(Math.floor(5.05));
// expected output: 5

console.log(Math.floor(5));
// expected output: 5

console.log(Math.floor(-5.05));
// expected output: -6
```

- `Math.random()` : The **`Math.random()`** function returns a floating-point, pseudo-random number in the range 0 to less than 1 (inclusive of 0, but not 1) with approximately uniform distribution over that range — which you can then scale to your desired range. The implementation selects the initial seed to the random number generation algorithm; it cannot be chosen or reset by the user

  `examples`

```jsx
const getRandomInt = (max) => Math.floor(Math.random() * max);

console.log(getRandomInt(3));
// expected output: 0, 1 or 2

console.log(getRandomInt(1));
// expected output: 0

console.log(Math.random());
// expected output: a number from 0 to <1

/* 
Getting a random number between 0 (inclusive) and 1 (exclusive)
*/

const getRandom = () => Math.random();

/* 
Getting a random number between two values
This example returns a random number between the specified values. 
The returned value is no lower than (and may possibly equal) min, 
and is less than (and not equal) max.
*/

const getRandomArbitrary = (min, max) => Math.random() * (max - min) + min;

/* 
Getting a random integer between two values
This example returns a random integer between the specified values. The value is no lower than min (or the next integer greater than min if min isn't an integer), and is less than (but not equal to) max.
*/

const getRandomInt = (min, max) => {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min) + min); //The maximum is exclusive and the minimum is inclusive
}

/*
Getting a random integer between two values, inclusive
While the getRandomInt() function above is inclusive at the minimum, 
it's exclusive at the maximum. What if you need the results to be inclusive 
at both the minimum and the maximum? 
*/

const getRandomIntInclusive = (min, max) => {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1) + min); //The maximum is inclusive and the minimum is inclusive
}
```

- `.length` : The `length` property returns the length of a string.

Now lets write the javascript for the hex values 

`src/hex.js`

```jsx
// hex values range 
const hex = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F"];
const button = document.querySelector("button"); //referencing to class button
const color = document.querySelector(".color"); //referencing to color button

// adding a click event listener to the button
button.addEventListener("click", () => {
  let hexValue = "#"; // hex values start from 
// using a for loop to generate a random hex value
  for (let i = 0; i < 6; i++) { //hex values have 6 numbers from the gange
    hexValue += hex[generateRandom()]; 
  }
  console.log(hexValue);
  color.textContent = hexValue;
  document.body.style.backgroundColor = hexValue;
});

const generateRandom = () => Math.floor(Math.random() * hex.length); // will return a random number 
```

- hex value range :  the hex code for colors ranges from 0 to 9 and A to F , you can read more about it [here](https://www.theproblemsite.com/reference/mathematics/codes/hexadecimal-code](https://www.theproblemsite.com/reference/mathematics/codes/hexadecimal-code)) .
- We use a for loop to run 6 times to generate a random number between the hex array and increments it and adds it to #, after that we set the background to the random generated hex value.

- Link to [codesandbox](https://codesandbox.io/s/github/VedanthB/Color-Filpper-vanilla-javascript)

If this blog helped you learn something new please drop a like.