Building Pricing Tables with HTML + CSS
With CSS Grid, Variables, and Hovers
Hello ๐ - this TinyApp is called SuperPricey. It's an example of a simple pricing table, displaying pricing plans for the random-est stuff.
Meet SuperPricey ๐ค
Check out SuperPricey in the sandbox below. It's a website running on just HTML and CSS.
Structure Required ๐
HTML is a markup language, and it provides structure to our page. As we start breaking this TinyApp down, let's start with getting the skeleton together.
Our <body>
tag starts out with an <h1>
for our title, and a <p>
tag for a subtitle on the page. There aren't any CSS classes on either of these tags, so they're simply inheriting styles that are applied to the full body of the page.
<h1>SuperPricey</h1>
<p>Pay money for the randomest stuff.</p>
The next piece is where we start to see some more complex nesting. The nesting starts with a <div>
element.
<div class="plans-container">
There's a class called "plans-container" on this div, so already, without even looking at the CSS, we can infer that this div contains all of the plans within it.
Sure enough, the next child of this div is the whole plan. Here's the HTML for the "free" plan.
<div class="plan plan--free">
<p class="plan-title">Free</p>
<p class="plan-price">
<span class="plan-price-text">$0</span>
<span>/mo</span>
</p>
<div class="button">Sign Up</div>
<div>
<p>Includes:</p>
<ul>
<li>Used socks</li>
<li>Sweet potatoes</li>
<li>Unpaid utility bills</li>
</ul>
</div>
</div>
There seems to be a whole lot going on here, but we can break it down. If we read the tags from top to bottom, here's how it's structured.
- Create a div with a class of
plan
. Add another class ofplan--free
to indicate this is the free class (and will need appropriately different styles). This div is the parent, holding the rest of the code within it. - Add the title of the plan.
- Add the price of the plan, where text for the plan's price is in a separate
span
. - Add a "Sign Up" button
- Create a
div
that contains the structure for listing out plan features. - Add an
h4
tag that has the title of the features text. In the free plan's case, it says, "includes". - Create an unordered list
ul
and its children as list itemsli
, listing the plan's features.
Great. Nothing too crazy, right? Let's dive into the CSS.
Let's get Griddy ๐บ
CSS Grid is a newer technology and an addition to CSS that makes it really easy to compose UIs and move elements around while keeping everything organized. It's outside the scope of this article to deep dive into the nitty-gritty's of CSS Grid, but check out the links in Further Reading if you're interested.
For the purposes of SuperPricey, CSS Grid helps us lay out each of the plans horizontally, organized in columns. Everything we do to make this happen is within these few lines of code.
.plans-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 0.8em;
}
Yes, that small snippet gets each of the plans to arrange themselves nicely, with an elegant gap between them too. This code can look a little magical, so it's time to demystify it.
Firstly, let's recognize that this is the plans-container
class that we're looking at. There are three divs nested directly beneath this div, and each of them has a class of plan
. That means that the div with plans-container
is the one responsible for organizing its direct children.
Inside the class itself, we start with display: grid
. This simply tells CSS that the contents of this div should be displayed and laid out with CSS Grid.
The next line is the one that sets up our columns. grid-template-columns
says, "here's the template you should use to lay out the child content." In our case, we're creating three columns, each one 1fr
wide. fr
stands for fraction unit. An fr
will fill the space, as widely as it can go. In summary, this line says, "set up three columns, and get the child contents to fill up the fully available space."
Finally, the gap
property adds a little space between each of the columns. Adding ever so little space gives the grid a cleaner look.
Making things look awesome ๐
The rest of this article will be focused on the additional styling that polishes it up.
Starting with the font, I decided to use a different font than the standard serif or sans-serif. I picked up Source Sans Pro from Google Fonts. Google Fonts allows us to import a font directly into our CSS, using the import statement.
@import url("https://fonts.googleapis.com/css2?family=Source+Sans+Pro&display=swap");
Next, we'll define some colors using CSS variables. Relatively new to CSS, variables allow us to define values of CSS and use them elsewhere in the stylesheet. We use the :root
to make these variables accessible by classes across the rest of the stylesheet.
:root {
--white: #fff;
--gray: #f5f5f5;
--green: #c5ffe4b2;
--purple: #c5ceffb2;
--yellow: #ffdf9bb2;
--dark: #333;
}
From there, we can define the styles of the application's body in general. You'll notice that we define fonts and colors using CSS variables.
body {
background: var(--gray);
color: var(--dark);
font-family: "Source Sans Pro", sans-serif;
}
To access a variable, we use the var()
keyword, and pass in the name of the variable to use, as if it was an argument.
The next area that we use some of these color variables is for each of the plans. Each plan in our HTML has a class="plan plan--[plan-name]"
where the "[plan-name]" part is the name of whatever plan is being described. The reason we add a plan--free
for example, is to give us a hook in the css to change color appropriately. We can change the css like so:
.plan--free {
background: var(--green);
}
.plan--pro {
background: var(--purple);
}
.plan--custom {
background: var(--yellow);
}
With variables and that class correctly applied, this code is quite expressive and lets us know exactly what's going on.
There are other small touches of CSS that you can check out in the styles.css file from the sandbox, but there's one last detail I'll focus on. That's the "sign up" button.
The button itself is pretty simple. It has some padding around the words so that it's not too crowded; it has a generous border-radius so that it's nice and rounded. It has centered text, a grey background, and cursor turns into a pointer when you hover over it.
.button {
padding: 0.7em;
border-radius: 2.5em;
text-align: center;
cursor: pointer;
background: var(--gray);
}
What's interesting about it is that it's hoverable. This may look tricky, but CSS make it very simple. It boils down to these lines:
.button:hover {
background-color: var(--dark);
color: var(--white);
}
:hover
is considered a pseudo-class in CSS. From MDN:
"A CSS pseudo-class is a keyword added to a selector that specifies a special state of the selected element(s)."
In this case, button:hover
is describing what happens when the element with this css class is hovered over. Here, the background-color changes to dark and the text color is changed to white. Hovering over these elements in the Sandbox should show how that works.
Now SuperPricey is ready. Let the random stuff be sold! See you next time!
~ Saalik