DEV Community

Cover image for Tutorial: How to build a tiered price component in HTML & CSS
Tiiny Host
Tiiny Host

Posted on

Tutorial: How to build a tiered price component in HTML & CSS

A few weeks ago tiiny.host (a simple way to share your web project) launched a deal but presented it in a creative way:

A few asked how it was made so I wanted to break it down for others.

The original was created with react & bootstrap so I re-created it in pure HTML & CSS to breakdown it's components. Feel free to use the component yourself if you like it :)

P.s. We also do have a lifetime deal going on if you're interested: https://tiiny.host


The container is a simple, rounded rectangle with a white background featuring two child divs:

<div class="container">
  <div class="price-tiers-container">

    <!-- Prices tiers go here -->

  </div>
  <div class="features-container">

    <!-- Prices tiers go here -->

  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Letโ€™s look at the price tiers first. These contained three further divs wrapped by the price-tiers-container class.

In order to make the divs extend out of itโ€™s parent container class we needed to apply the position: absolute for price-tiers-container. We also ensured it had a fixed width and used a flex layout to divide the space amongst the three price tiers.

The final class looked like this:

.price-tiers-container {
    display: flex;
    position: absolute;
    width: 530px;
}
Enter fullscreen mode Exit fullscreen mode

Within this we have three price-tier divs with these styles:

.price-tier {
    flex: 3;

    display: flex;
    flex-direction: column;
    justify-content: space-between;

    background: white;
    border: solid 2px #c1c1c1;
    border-radius: 8px;
    margin-top: 10px;
    margin-left: 10px;
    padding: 12px;
}
Enter fullscreen mode Exit fullscreen mode

Each price-tier is given a default equal width by setting flex of 3 (but the active one is flex: 4). We also use flex to align items within the price-tier div and space the items evenly using justify-content: space-between. Finally we apply some individual border, padding etc styles.

Within each price tier we just have three divs:

.title {
    color: grey;
}

.price {
    font-size: 1.5rem;
}

.price-period {
    font-size: 0.7rem;
}

.label {
    font-size: 0.8rem;
}

<div class="price-tier">
  <div class="title">
    Stage 2
  </div>
  <div class="price">
    <b>$99</b><span class="price-period"> / onetime</span>
  </div>
  <div class="label">Coming soon</div>
</div>
Enter fullscreen mode Exit fullscreen mode

With the active price tier, the set up is slightly different:

.active {
    border-color: blue;
    flex: 4 **!important**;
    height: 150px;
}

<div class="price-tier active">
  <div class="p-title">
    Stage 1
  </div>
  <div class="price">
    <b>$59</b><span class="price-period"> / onetime</span>
  </div>
  <div class="progress-bar">
    3/50 sold
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

The active price-tier swaps out the label for a progress-bar and applies the active class as well. To make it more prominent we assign it a fixed height, override the default border-color and increase the flex to 4.

Additionally, we grey out the content in the non-active price-tiers like so:

.price-tier > div {
    opacity: 0.4;
}

.active > div {
    opacity: 1;
}
Enter fullscreen mode Exit fullscreen mode

Finally in order to make the progress bar in the active price tier we use a css-gradient trick:

.p-progress-bar {
    background: linear-gradient(90deg, #2BC147 0%, #2BC147 15%, #575757 15%, #575757 100%);
    color: white;
    border-radius: 8px;
    width: 100%;
    font-size: 0.7rem;
}
Enter fullscreen mode Exit fullscreen mode

We set the background to 90 degree but set the green (#2BC147) at 0% and 15% and the the grey (#575757) at 15% and 100%. This gives the illusion of a progress bar. If we need to increase the progress then we just modify 15% to the new progress level.

Finally, we complete the features-container:

.features-container {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    padding: 168px 12px 12px 12px;
    align-content: space-evenly;
}

.feature::before {
    content: 'โœ… ';
}

.feature {
    margin: 3px;
    font-size: 0.8rem;
}

<div class="features-container">
  <div class="feature">This feature</div>
  <div class="feature">And this</div>
  <div class="feature">Great at this</div>
  <div class="feature">Plus this feature</div>
</div>
Enter fullscreen mode Exit fullscreen mode

Here, we use a flex layout again and set align-content: space-evenly to evenly space the list of features within the container.

We apply large top padding of 168px to leave space for the pricing-tier-container. This is because it has position: absolute meaning it takes no space in parent div. In order for it to not overlap we reserve artificial space for it.

We apply a ::before selector to each feature and set the content to a tick emoji (you can use anything) to add ticks to each item.

And thatโ€™s it! Hope that was helpful, let me know if you have any questions in the comments.

Full HTML & CSS CodePen link: https://codepen.io/rabbitsfoot8/pen/MWeeMQv

Top comments (0)