CreatiqueMedia Blog

CM-Post-0004-20220901-Rating-Component-1

CM-Post-0004-20220901-Rating-Component-1

CREATE A RATING CARD COMPONENT - 1

WOW folks!

Man, this was a fun project!

Coding releases endorphins in me or something!

Can y’all feel it?

That high you get when there’s a project for you to tackle where you’re prepped and ready to use your skills to create a work of digital art?

You better say, HELL YEAH, I feel it!

Because coding isn’t something for the faint of heart, it can be tough at first!

As humans, we are like water when it comes to cerebral pressure, we flow only in the direction of least resistance!

When we try to learn something new that we associate with complexity, we tend to have a negative feeling towards it which ultimately leads to giving up!

But, if you force your mind to believe that learning something that may be difficult is fun and exciting, then you train it to develop that essential quality needed for Web Developers.

I don’t care what anyone says, Web Development is ART – PERIOD!

Our canvas is an IDE, our brushes are tools we use such as languages, frameworks, libraries, preprocessros, task runners, etc. 

So, instead of trying to put your “Rocket Science” hat on, don your “Bob Ross” hat and let’s get to painting!

Index

1 - Description

Here is a  really cool rating card component I built using HTML CSS, and JavaScript, but more specifically, jQuery!

The really AWESOME part about this card component is that I didn’t have to use any media queries because the component automatically shrinks to fit the viewport on mobile devices!

Man, I LOVE Flexbox!

I got this card component from Frontend Mentor as a challenge!

If you have not checked out Frontend Mentor yet, you definitely need to because it’s a fantastic tool to help learn web development and to hone in on your skills!

They are a great resource to use to help with offering free challenges that you can submit solutions too!

And by the way, there are many ways to achieve a solution for these challenges, so you don’t have to use the code I provide, but it gives you way to see how others can arrive at a particular way of solving them!

So, check out Frontend Mentor here, there are one of MOST favorite web dev tools to utilize!

Okay, let’s get started!

2 - What We're Building!

Before Submission

After Submission

3 - Style Guide

Here is the styles we will be using that the Frontend Mentor challenge requires:

				
					# Front-end Style Guide
## Layout
The designs were created to the following widths:
- Mobile: 375px
- Desktop: 1440px
## Colors
### Primary
- Orange: hsl(25, 97%, 53%)
### Neutral
- White: hsl(0, 0%, 100%)
- Light Grey: hsl(217, 12%, 63%)
- Medium Grey: hsl(216, 12%, 54%)
- Dark Blue: hsl(213, 19%, 18%)
- Very Dark Blue: hsl(216, 12%, 8%)
## Typography
### Body Copy
- Font size (paragraph): 15px
### Font
- Family: [Overpass](https://fonts.google.com/specimen/Overpass)
- Weights: 400, 700

				
			

4 - Project Folder Structure

5 - Fontawesome

Here, like always, I use the BEM method to structure my classes. Then, I use IDs for my JavaScript and jQuery usage. For icons, I am using FontAwesome. I have a kit I use and as you can see, I have it in the <head> section as:

				
					
				
			

I use FontAwesome for the star and number icons for the numbered button rating section. 

 

If you do not have FontAwesome yet, or you have never used it, it is a great API for icons, to use in your projects.

 

To follow along with this post, you can leave my FontAwesome kit code in the <head> section or you can use your own FontAwesome kit. However, if you don’t use a FontAwesome kit and you decide to use the following CDN:

 

 

Just know that I was having issues with the star icon displaying, so I opted to use the kit instead and BAM, it worked!

 

So, if you want to get your own FontAwesome kit, go here:

 

 

Then, click the “Start for free” button.

 

Next, you will see a page that asks you for your email so you can receive your new FontAwesome kit.

 

And, that’s about it.

 

Just follow the instructions in the email to get setup!

6 - HTML

There’s not much to explain here folks, it’s just the markup, but pay attention to the way I named my BEM classes and my IDs for our script. I try to come up with very detailed classes, though sometimes long, but it makes my CSS more easy to follow and to help reduce redundancy and an out of control stylesheet.

 

Here is the code:

				
					<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- displays site properly based on user's device -->
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    
    <link rel="icon" type="image/star-icon" href="/images/favicon.ico" />
    <link rel="stylesheet" href="./css/main.css" />
    
    <title>
      CreatiqueMedia | Ron The Web Dev | Post 0004-20220829 | Frontend Mentor |
      Card Component 3 | Interactive Rating Component
    </title>
  </head>
  <body>
    <form action="" class="form--container" id="form">
      <section class="form--container--sec--1">
        <button class="form--container--sec--1--btn" disabled>
          <i
            class="fas fa-star fa-solid fa-lg form--container--sec--1--icon" id="sec-1-icon"
            ic=""
          ></i>
        </button>
        <h1 class="form--container--sec--1--heading">How did we do?</h1>
        <p class="form--container--sec--1--text">
          Please let us know how we did with your support request. All feedback
          is appreciated to help us improve our offering!
        </p>
        <!-- Rating state start -->
        <section class="form--container--sec--2">
          <button
            type="button"
            class="form--container--sec--2--btn--1"
            id="rating-btn-1"
          >
            <i class="fa-solid fa-1 form--container--sec--2--icon" id="btn-1-icon"></i>
          </button>
          <button
            type="button"
            class="form--container--sec--2--btn--1"
            id="rating-btn-2"
          >
            <i class="fa-solid fa-2 form--container--sec--2--icon" id="btn-2-icon"></i>
          </button>
          <button
            type="button"
            class="form--container--sec--2--btn--1"
            id="rating-btn-3"
          >
            <i class="fa-solid fa-3 form--container--sec--2--icon" id="btn-3-icon"></i>
          </button>
          <button
            type="button"
            class="form--container--sec--2--btn--1"
            id="rating-btn-4"
          >
            <i class="fa-solid fa-4 form--container--sec--2--icon" id="btn-4-icon"></i>
          </button>
          <button
            type="button"
            class="form--container--sec--2--btn--1"
            id="rating-btn-5"
          >
            <i class="fa-solid fa-5 form--container--sec--2--icon" id="btn-5-icon"></i>
          </button>
        </section>
        <!-- Rating state end -->
        <section class="form--container--sec--3">
          <button 
            type="button"
            class="form--container--sec--3--btn--1"
            id="form-submit-btn"
          >
            submit
          </button>
        </section>
      </section>
    </form>
    <!-- Start Thank You Message Section -->
    <section class="form--thank--you--container" id="thank-you">
      <img
        class="form--thank--you--container--img lazyload"
        src="./assets/illustration-thank-you.svg"
        alt="Thank You"
      />
      <input
        class="form--thank--you--container--input"
        type="text"
        id="input-box"
      />
      <h1 class="form--thank--you--container--heading">Thank you!</h1>
      <p class="form--thank--you--container--text">
        We appreciate you taking the time to give a rating. If you ever need
        more support, don't hesitate to get in touch!
      </p>
    </section>
    <!-- End Thank You Message Section -->
    <footer>
      <div class="attribution">
        Challenge by
        <a href="https://www.frontendmentor.io?ref=challenge" target="_blank"
          >Frontend Mentor</a
        >.<br />Coded by
        <a href="https://CreatiqueMedia.com"
          >CreatiqueMedia LLC | Ron The Web Dev</a
        >.
      </div>
    </footer>
    
    <script src="./js/main.js"></script>
  <script defer src="https://blog.creatiquemedia.com/wp-content/uploads/siteground-optimizer-assets/siteground-optimizer-combined-js-65e196c97a41448968b7bec7b697db1b.js"></script></body>
</html>

				
			

7 - CSS

Now, here’s the FUN part!

 

I really loved working on this project because it was a bit of a brain teaser for me trying to dial in the background gradient on the form component.

 

But, I got it all figured out and it looks great!

 

I don’t typically cover much CSS in detail because that’s what this site is for:

 

 

However, there are a few thing I want to mention.

 

So, I actually structure my CSS in the flow of the website. In other words, I try to structure my stylesheet to follow the order of the classes in my markup. Some Web Devs may do it differently, but this seems to work well for me because that’s just how my brain works. If you have a nice system that works for you, AWESOME!

 

Keep using it!

 

Okay, as I stated, I am not going to go through my CSS with a fine toothed comb! 

 

However, I want to talk about the following in the /* Section 1 */ portion of the stylesheet here:

				
					.form--container--sec--1--btn {
  border-radius: 50%;
  height: 56px;
  width: 56px;
  background-color: var(--VeryDarkBlue);
  margin: 0 0 24px 12px;
  background: rgba(0,0,0,0.2);
  border: none;
}
				
			

If you notice the star icon at the top of the component, you will realize that it is fully colored with no opacity. This icon is enclosed in the markup within a <button> tag and this button has an opacity of “0.5”.

Well, this opacity property will affect the icon enclosed within it and this is not what we want. So, to prevent this effect, we need to use rgba instead, like this:

				
					 background: rgba(0, 0, 0, 0.2);
				
			

Using “rgba” to create opacity means the very end value is what determines the opacity, but notice how the rgba is “0.2” and not “0.5” as it once was!

 

Interesting right?

 

My thoughts exactly, but the CSS gods out there probably can explain that better than I can, I just know that this works and looks good!

 

The reason why this occurs is because the “opacity” property sets the opacity value for an element and all of its children, while the “rgba” property sets the opacity value only for a single declaration.

 

So, if you need to use opacity for a background, but you don’t want opacity to effect any child element, then use rgba instead on the parent element to ensure that child’s opacity is not affected!

 

Next, I want to talk about the following:

				
					.form--container--sec--2--btn--1:hover {
  background-color: var(--PrimaryColor);
  opacity: 1;
}
.form--container--sec--2--btn--1:hover > .form--container--sec--2--icon {
  color: var(--White);
}
.form--container--sec--2--btn--1:focus > .form--container--sec--2--icon {
  color: var(--White);
}
				
			

Pseudo classes are GREAT!

 

That’s what “:hover” and “:focus” are.

 

So, we want the numbered rating buttons to turn orange when we hover over them, so that’s why we are using the “:hover” pseudo class. But, the “:focus” pseudo class is cool because if you want something like a button that by default fades when the cursor moves away from it, to STAY highlighted, then use the :focus pseudo class. Now, how we implement this, is to use the “>” symbol as in the above examples.

 

Without using this code, the submit button will not highlight on hover, but most importantly the FontAwesome numbered rating icons will not highlight either. So, to make both highlight on hover, but to make it STAY highlighted when the cursor moves away from it, then we need to use the “:focus” pseudo class!

 

Here is the code:

				
					/* Style Guide */
/*
 # Front-end Style Guide
## Layout
The designs were created to the following widths:
- Mobile: 375px
- Desktop: 1440px
## Colors
### Primary
- Orange: hsl(25, 97%, 53%)
### Neutral
- White: hsl(0, 0%, 100%)
- Light Grey: hsl(217, 12%, 63%)
- Medium Grey: hsl(216, 12%, 54%)
- Dark Blue: hsl(213, 19%, 18%)
- Very Dark Blue: hsl(216, 12%, 8%)
## Typography
### Body Copy
- Font size (paragraph): 15px
### Font
- Family: [Overpass](https://fonts.google.com/specimen/Overpass)
- Weights: 400, 700
*/
/* JavaScript/jQuery Usage */
.highlight-btn {
  background-color: var(--LightGrey) !important;
  opacity: 1 !important;
}
.path-btn-icon {
  color: var(--White);
}
/* Universal Styles Go Here */
:root {
  --PrimaryColor: hsl(25, 97%, 53%);
  --White: hsl(0, 0%, 100%);
  --LightGrey: hsl(217, 12%, 63%);
  --MediumGrey: hsl(216, 12%, 54%);
  --DarkBlue: hsl(213, 19%, 18%);
  --VeryDarkBlue: hsl(216, 12%, 8%);
  --ParagraphFont: 15px;
  --FontFamily: "Overpass", sans-serif;
}
*,
::before,
::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: var(--FontFamily);
  font-size: var(--ParagraphFont);
}
body {
  background-color: var(--VeryDarkBlue);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100vw;
  height: 100vh;
}
/* Specific Styles Go Here */
.form--container {
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: var(--DarkBlue);
  border-radius: 24px;
  color: var(--White);
  width: 25%;
  padding: 24px;
  min-width: 375px;
  line-height: 2;
  background: linear-gradient(180deg, rgb(42 45 56), rgb(25 29 39));
}
/* Section 1 */
.form--container--sec--1--icon {
  color: var(--PrimaryColor);
  opacity: 1;
}
.form--container--sec--1--btn {
  border-radius: 50%;
  height: 56px;
  width: 56px;
  background-color: var(--VeryDarkBlue);
  margin: 0 0 24px 12px;
  background: rgba(0, 0, 0, 0.2);
  border: none;
}
.form--container--sec--1--heading {
  font-size: 24px;
  margin: 0 0 24px 12px;
}
.form--container--sec--1--text {
  color: var(--LightGrey);
  margin: 0 0 24px 12px;
}
/* Section 2 */
.form--container--sec--2 {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
}
.form--container--sec--2--btn--1 {
  border-radius: 50%;
  height: 56px;
  max-width: 100%;
  background-color: var(--VeryDarkBlue);
  opacity: 0.5;
  border: none;
  cursor: pointer;
  margin: 0 32px 0 0;
  padding: 24px;
  margin: auto;
}
.form--container--sec--2--btn--1:hover {
  background-color: var(--PrimaryColor);
  opacity: 1;
}
.form--container--sec--2--btn--1:hover > .form--container--sec--2--icon {
  color: var(--White);
}
.form--container--sec--2--btn--1:focus > .form--container--sec--2--icon {
  color: var(--White);
}
.form--container--sec--2--icon {
  color: var(--LightGrey);
}
/* Section 3 */
.form--container--sec--3 {
  margin: 24px 0 0 0;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  flex-direction: column;
}
.form--container--sec--3--btn--1 {
  background-color: var(--PrimaryColor);
  color: var(--White);
  text-transform: uppercase;
  border-radius: 24px;
  border: none;
  font-weight: 700;
  letter-spacing: 2px;
  margin: 0 auto 0 auto;
  max-width: 100%;
  padding: 4% 40% 4% 40%;
  cursor: pointer;
}
.form--container--sec--3--btn--1:hover {
  background-color: var(--White);
  color: var(--PrimaryColor);
}
/* Thank You Message Section */
.form--thank--you--container {
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: var(--DarkBlue);
  border-radius: 24px;
  color: var(--White);
  width: 25%;
  min-width: 375px;
  line-height: 2;
  padding: 2%;
  background: linear-gradient(180deg, rgb(42 45 56), rgb(25 29 39));
}
.form--thank--you--container--input {
  background-color: var(--VeryDarkBlue);
  border-radius: 24px;
  border: none;
  padding: 2%;
  margin: 24px 0 24px 0;
  opacity: 0.5;
}
.form--thank--you--container--heading {
  text-align: center;
  font-size: 24px;
}
.form--thank--you--container--text {
  color: var(--LightGrey);
  margin: 0 0 24px 12px;
  text-align: center;
}
.form--thank--you--container--input {
  color: var(--PrimaryColor);
  text-align: center;
}
/* Footer Section */
.attribution {
  font-size: 11px;
  text-align: center;
  color: var(--White);
  margin: 24px 0 0 0;
}
.attribution a {
  color: hsl(228, 45%, 44%);
}

				
			

8 - JavaScript/jQuery

Now here is the really, really, and REALLY fun part!

 

JavaScript, or more appropriately, jQuery!

 

Here is the code:

				
					/* Hide Thank You Message */
$(".form--thank--you--container").hide();
$("#validation-msg").hide();
$("[id*=rating-btn-]").click(function () {
  switch (this.id) {
    case "rating-btn-1":
      $("#input-box").val("You selected 1 out of 5");
      $("#rating-btn-1").addClass("highlight-btn");
      $(
        "#rating-btn-2, #rating-btn-3, #rating-btn-4, #rating-btn-5"
      ).removeClass("highlight-btn");
      $(
        "#rating-btn-2, #rating-btn-3, #rating-btn-4, #rating-btn-5"
      ).removeClass("highlight-icon");
      $("#form-submit-btn").click(function () {
        $("#form").hide();
        $("#thank-you").show();
      });
      break;
    case "rating-btn-2":
      $("#input-box").val("You selected 2 out of 5");
      $("#rating-btn-2").addClass("highlight-btn");
      $(
        "#rating-btn-1, #rating-btn-3, #rating-btn-4, #rating-btn-5"
      ).removeClass("highlight-btn");
      $(
        "#rating-btn-1, #rating-btn-3, #rating-btn-4, #rating-btn-5"
      ).removeClass("highlight-icon");
      $("#form-submit-btn").click(function () {
        $("#form").hide();
        $("#thank-you").show();
      });
      break;
    case "rating-btn-3":
      $("#input-box").val("You selected 3 out of 5");
      $("#rating-btn-3").addClass("highlight-btn");
      $(
        "#rating-btn-1, #rating-btn-2, #rating-btn-4, #rating-btn-5"
      ).removeClass("highlight-btn");
      $(
        "#rating-btn-1, #rating-btn-2, #rating-btn-4, #rating-btn-5"
      ).removeClass("highlight-icon");
      $("#form-submit-btn").click(function () {
        $("#form").hide();
        $("#thank-you").show();
      });
      break;
    case "rating-btn-4":
      $("#input-box").val("You selected 4 out of 5");
      $("#rating-btn-4").addClass("highlight-btn");
      $(
        "#rating-btn-1, #rating-btn-2, #rating-btn-3, #rating-btn-5"
      ).removeClass("highlight-btn");
      $(
        "#rating-btn-1, #rating-btn-2, #rating-btn-3, #rating-btn-5"
      ).removeClass("highlight-icon");
      $("#form-submit-btn").click(function () {
        $("#form").hide();
        $("#thank-you").show();
      });
      break;
    case "rating-btn-5":
      $("#input-box").val("You selected 5 out of 5");
      $("#rating-btn-5").addClass("highlight-btn");
      $(
        "#rating-btn-1, #rating-btn-2, #rating-btn-3, #rating-btn-4"
      ).removeClass("highlight-btn");
      $(
        "#rating-btn-1, #rating-btn-2, #rating-btn-3, #rating-btn-4"
      ).removeClass("highlight-icon");
      $("#form-submit-btn").click(function () {
        $("#form").hide();
        $("#thank-you").show();
      });
      break;
  }
});

				
			

From the get go you can see that I am using the following code to start out with: 

				
					$("#thank-you").hide();
				
			

Since we have a “thank you” section in our markup that should only display after the submit button is clicked, then we need to hide it on page load. 

To do this, we use the above code. 

Then, I use the below attribute selector to grab all of the IDs that match!

Those IDs have the following 5 rating button IDs:

  • #rating-btn-1
  • #rating-btn-2
  • #rating-btn-3
  • #rating-btn-4
  • #rating-btn-5
The attribute selector (*=) finds all IDs that contain the following: “rating-btn-“. I leave off the number so the match can grab all of the IDs that have “rating-btn-” in the name. Then, this allows me to use the “this” keyword within a “switch” statement and within the “case” statement, I can add code as a do action, if the match criteria is met!

Here is that code:

				
					$("[id*=rating-btn-]")
				
			

The next code simply turns on and off the “display: none” declaration by using the “.addClass” and “removeClass” methods!

Here’s the code for that: 

				
					$("#rating-btn-1").addClass("highlight-btn");
      $(
        "#rating-btn-2, #rating-btn-3, #rating-btn-4, #rating-btn-5"
      ).removeClass("highlight-btn");
      $(
        "#rating-btn-2, #rating-btn-3, #rating-btn-4, #rating-btn-5"
      ).removeClass("highlight-icon");
				
			

If you look at the stylesheet (main.css), you will find at the very top, a section titled, “/* JavaScript/jQuery Usage */”.

This code looks like the following:

				
					/* JavaScript/jQuery Usage */
.highlight-btn {
  background-color: var(--LightGrey) !important;
  opacity: 1 !important;
}
				
			

What this code does is assign the “.highlight-btn” class to every other numbered button icon element, but leaves off the currently selected numbered button. In other words, it keeps the currently selected button highlighted, but keeps the other non-selected buttons highlight effect OFF! Then, using “opacity: 1” reverses the effect of the opacity effecting the button itself. I could have used rgba here as well, but I wanted to show that you could use opacity like this here.  

If you want to use “rgba”, then use the following declaration for this as in the following example:

				
					background: rgba(0, 0, 0, 1)
				
			

The next code creates the “thank you” message and hides the initial form from view and displays the “thank you” component:

				
					$("#input-box").val("You selected 1 out of 5");
      $("#form-submit-btn").click(function () {
        $("#form").hide();
        $("#thank-you").show();
      });
				
			

And that’s it for all the code folks!

9 - Github Repo and Live Website

10 - Conclusion

Hey folks!

Thanks for stopping by to check out this post! 

We appreciate your readership and will keep trying to post educational material for your web dev craving to thrive on!

If you are interested in having a website, web app, or anything built related to web development for your business or personal need, please contact us today at:

OR

Call use at: 405-831-3048

Leave a Comment

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