CSS can be overwhelming at times and 80% of the web developers out there find CSS to be very complicated at times.
Well, guess what? It ain’t that much of a complication once you get a hold of the basics and that’s exactly what we’re gonna do today.
Note: This project is a challenge from Frontend Mentor. The built project’s source code is stored in a github repository.
This is what the final build looks like.
Let’s get started
The first thing that we’re gonna roll at is to create an empty index.html
file and set up its <head>
tag with some metadata such as the
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
This meta tag is as much necessary for a responsive web design as food for us. Next, we’re going to create two folders called images
and css
and fill up the former one with these images from the repository.
Normalize.css
Normalize.css is an NPM module that provides a CSS file that, quite literally,
"makes browsers render all elements more consistently and in line with modern standards. It precisely targets only the styles that need normalizing".
Either you can download the CSS file from our repository or install the module yourself, however, the latter would require an LTS version of node.js installed on your device.
To get started, initialize an empty node.js project using
npm init -y
This will initialize a default node.js project and you can find a package.json file in the project’s root directory. Now run the command
npm install normalize.css
This will create a node_modules folder in the root folder of your project and you can find the normalize.css file somewhere in this folder.
Root Styles
Create a new root-style.css file in the CSS directory and paste these CSS rules into it
Firstly, we’re using Red Hat Display font from Google Fonts, then we’re creating a whole lot of colour shades and storing them in their respective CSS custom properties/variables.
This allows us to create a colour scheme and use the semantic CSS variables rather than using the raw colour names.
Naming Convention
Then we’re going for some text configuration which is just some font weights and sizes but, the fun part is where we declare the general sizing properties. After a ton of research and consistent scaling difficulty across many different applications, our team figured out the naming convention (smaller, small, normal, large, larger) to be the best working naming convention up-to-date.
It is as such because you can store whatever you want in the smaller variable and then keep on increasing it as much as you desire without the constant thought of what would happen if you have to increase all these sizes. The same won’t be the case with a variable named --sizing-1rem
.
Styled Components
Before jumping into the world of HTML, we’re writing the CSS of some elements that we’re gonna use, this would give us the ability to have better-looking default HTML elements and we won’t waste our time styling these components later on.
One thing worth noticing here is the box-shadow, the reason why would be because we’re using CSS variables inside the box-shadow property. Let me break it down for you
box-shadow: 0 var(--size-smaller) var(--size-normal) var(--alt-shadow-color);
The syntax of the box-shadow property goes like
box-shadow: x y blur spread colour
Here,
- x — The x-offset of the box-shadow, 0 means the shadow won’t get tilted on either of the x-axes.
- y — The y-offset of the box-shadow, we’re using a variable to indicate this size.
- blur — The blur radius of the shadow, we’re blurring the shadow so it gets a nice spread of the colour and notes that this blur is slightly more than the y-offset which means that the blurred shadow will cover up about the whole button.
- spread — Think of it as a number of how thick the shadow should be (Which it actually is but, slightly different), we’re ignoring it cuz the default spread radius works best in most use cases.
- ** colour** — Very obvious, let’s just quit here.
Modular CSS
Most web applications use module bundlers and/or package managers to bundle up their static assets such as CSS and images. That’s a perfect way to choose for a large application but, for this challenge, we’re just gonna import other CSS files into a single file that’s embedded within the HTML.
/* style.css */
@import "normalize.css";
@import "root-style.css"
This will make the server return a single CSS file that already has 2 other CSS files within it, decreasing the HTTP requests from the browser by 2.
Semantic HTML Markup
We’re using HTML5’s semantic elements to ensure a better user experience and SEO management.
Note that we’re using our styled component classes as default HTML elements and using undefined (for now) CSS classes for layout management. Styled components without a layout design
If you’re following correctly, this is what your browser would display right now.
To fix this, let’s start adding some layout rules in our style.css file. The first element to style is the .viewport
which is just a wrapper for the <body>
element.
Following are the styles for the .viewport
class
.viewport {
width: 100vw;
height: 100vh;
display: grid;
place-items: center;
padding: var(--size-larger);
background: var(--background-color) url("../images/pattern-background-mobile.svg") center top no-repeat;
background-size: contain;
}
@media (min-width: 768px) {
.viewport {
background: var(--background-color) url("../images/pattern-background-desktop.svg") center top no- repeat;
background-size: contain;
}
}
This alone makes the build looks very much better than before
Now, let’s add the styles for the <article>
element, the container for all this summary content.
article {
max-width: 375px;
border-radius: var(--size-normal);
background: var(--tertiary-color);
box-shadow: 0 var(--size-largest) var(--size-largest)
var(--shadow-color);
}
.article__cover {
height: 12rem;
background: url("../images/illustration-hero.svg" center center no-repeat;
background-size: cover;
border-radius: var(--size-normal) var(--size-normal) 0 0;
}
.article__content {
padding: var(--size-larger);
}
.article__content > * {
margin: 0;
text-align: center;
margin-top: var(--size-larger);
}
.article__content > *:first-child {
margin: 0;
}
@media (min-width: 768px) {
.article__content > *:first-child {
margin-top: var(--size-larger);
}
}
These styles fix the maximum width of the article, set its background, shadow, and also the cover image of the article. The result looks like this. Life is getting better and better.
Next up we just need to set up the card that displays the total cost and the buttons at the very bottom, this would do it
.card {
background: var(--color-on-background);
padding: var(--size-normal);
border-radius: var(--size-small);
display: flex;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
}
.w-25 {
width: 25%;
}
.w-50 {
width: 50%;
}
.icon#music {
background: url("../images/icon-music.svg") center center no-repeat;
background-size: contain;
}
.col-text {
display: flex;
align-items: start;
flex-direction: column;
gap: var(--size-smallest);
}
.col-buttons {
display: flex;
flex-direction: column;
gap: var(--size-smaller);
}
After this, the build is finished and the final product looks pretty aesthetic (in my opinion). But what actually matters is the fact that I found my build to be one of (if not) the most accurate to the actual challenge at Frontend Mentor.
If you have any questions, please ask in the comment section down below and don’t forget to like it if you read it through. Peace out 👌. Stay tuned for more cuz we, at Devshot, are gonna
take you to the moon 🌕
Top comments (0)