DEV Community

Stephanie Eckles
Stephanie Eckles

Posted on

Style a Blog Layout with CSS

In this post, we will learn about CSS properties and layout patterns useful for styling content such as for a blog, including

  • how to center website content
  • about special selectors
  • how margin collapsing works
  • how to use Inspector to help create definitions for complex properties like linear-gradient
  • how to make a circular image with one line of CSS

This is the thirteenth post and video in a series on learning web development. Learn more about the series and see the post schedule >

You may want to refer back to the first lesson that created our initial blog HTML, episode 5:

You may watch the following video or follow along with the expanded transcript that follows.

Review the source code >

To begin this lesson, open the starter project you began in episode 1, or review the source files from episode 12.

To begin this lesson, open our project in VSCode.

In the Terminal, type the start command npm run start to run the project.

Open blog-layout.html in VSCode, and organize your screen to be split with the browser. Then update the browser url to include /blog-layout.html.

initial blog layout appearance

Now, this page may seem a little shocking at this point since it is inheriting all of our styles due to linking to our single style.css file. We're no longer benefitting from that, so let's first create a new CSS file called blog-layout.css.

Then in our HTML file, update the stylesheet link in the <head> from style.css to blog-layout.css and save. Now we're back to default browser styles.

<link rel="stylesheet" href="blog-layout.css" />
Enter fullscreen mode Exit fullscreen mode

We'll first create a rule for body:

    body {
        font-family: sans-serif;
        color: #222;
    }
Enter fullscreen mode Exit fullscreen mode

I chose the color value of #222 because an off-black is recommended as a little easier on the eyes when reading long-form content like a blog post.

Next, let's adjust our typographic scale, which means the size assigned to each typography element.

Before that, let's temporarily comment out the image so we can focus on the type.

    <!-- <img src="http://placecorgi.com/200x150" alt="Good corgi doggo" align="left"> -->
Enter fullscreen mode Exit fullscreen mode

layout with no image

For the type, we'll do something similar to what we defined originally in style.css, including a rule to reset the margins. But we'll reduce our rules to cover h1-h3 for this demo.

    h1, h2, h3 {
        margin: 0 0 0.35em;
    }

    h1 {
      font-size: 40px;
    }

    h2 {
      font-size: 28px;
    }

    h3 {
      font-size: 20px;
    }
Enter fullscreen mode Exit fullscreen mode

Looking at our page, it feels like the spacing is a little off around the paragraphs. Let's try adding a margin definition for p:

    p {
        margin: 0 0 1.15em;
    }
Enter fullscreen mode Exit fullscreen mode

That feels a little better, but let's duplicate each paragraph, and then remove some words out of each paragraph to mimic real text a bit more. Then save and let's review.

layout with updated type scale and spacing

It looks nice between paragraphs, but it would be nice to use a bit more space to emphasize the sections created by use of the h2. For this, we could use a class, but that would require remembering to use the class each time we added an h2.

Instead, we can use the adjacent sibling selector which is + to select h2 that follow p and create the following rule:

    p + h2 {
        margin-top: 1.5em;
    }
Enter fullscreen mode Exit fullscreen mode

Save, then with Inspector we can see that there is only margin-top on the second h2 because it is the only one following a p.

margin-top on the h2

Inspector also helps us see a few other interesting things about how the margin-top was applied. First, since we used the relative em unit, the space is equal to 1.5 * 28px, since the font-size of the h2 is set to 28px which on the Computed tab we can see becomes 42px.

But wait - isn't there a margin-bottom on every p? If we inspect the paragraph prior to the h2 we see there is a computed margin-bottom of 18.4px and then if we hover the h2 we see it's margin-top extends to the bottom of the paragraph, not to the bottom of the paragraph's margin.

demo of collapsing margins between the p and h2

This is due to a particular behavior of margins which is called "collapsing". Competing margins collapse into each other with the smaller margin being collapsed into the larger margin.

demo of equal margins collapsing

The takeaway here is that if you have set equal margins on two bordering elements, like 16px, the space will not be double the value at 32px, but rather collapse to be 16px total.

You can refresh the page to clear the element.style.

With our window half-width, we're missing the whole picture we have with our layout, so let's extend both VSCode and the browser back to full-width and then move beyond typography.

Open blog-layout.html in VSCode, and let's review our structure. Our primary containing elements are header, main, and footer. Let's go ahead and remove the <hr> we added in the HTML lesson since we'll replace it with CSS.

full-width layout

With the browser window full-width, it's clear that our layout is aligned to the screen left, which make sense as all the containing elements are block elements and we learned previously that that's their default behavior. But you have likely noticed from viewing other websites that there is generally:

  1. A max-width set for the main content area; and
  2. The main content area is centered in the browser window

Switch back to our CSS file, and let's add a new rule:

    header, main, footer {
        max-width: 800px;
        margin-left: auto;
        margin-right: auto;
    }
Enter fullscreen mode Exit fullscreen mode

Save, and you'll see our content now appears more centered.

If we Inspect, you can see that's the result of adding the auto margins. The auto keyword is unique to margin and tells the browser to compute the value of extra space. We've used it on both sides, so it's effectively pushed our containers to the center.

auto margins highlighted

Using Inspector, you can toggle off the margin-right definition and then see how the remaining margin-left: auto rule has caused the containers to slide all the way to the right side.

margin-left highlighted

However, if we test toggling off the max-width rule, there is no extra space left around each element which eliminates the centering behavior.

This is looking good, but we want our header to stand out more, so let's add a rule:

    header {
        background-color: rebeccapurple;
        color: #fff;
        padding: 24px;
    }
Enter fullscreen mode Exit fullscreen mode

header background

Save, and you may agree that's not quite the effect we were going for. It would be nice if the background-color stretched across the window. But we placed our max-width rule on the header directly, so it's limiting the width of the background as well.

It's time to introduce a utility class to handle the width and centering, so let's change that rule to use the selector for a class: .container and save.

    /* header, main, footer { */
    .container {
        max-width: 800px;
        margin-left: auto;
        margin-right: auto;
        padding: 24px;
    }
Enter fullscreen mode Exit fullscreen mode

Let's also move the padding rule from header into the .container class. Unlike margin, padding does not collapse since it's inside the element it's defined on. This will help create visual space between our elements.

Then in our HTML, we'll make 3 adjustments. First, wrap the content of header and footer with a div and include the container class.

<!-- inside `header` and `footer` -->
<div class="container">
  <!-- content -->
</div>
Enter fullscreen mode Exit fullscreen mode

Inside main we already have the child element of article so we can add the container class to that, then save and review.

<main>
  <article class="container">
Enter fullscreen mode Exit fullscreen mode

That's more like it!

But there's still a bit of leftover space. Using Inspector to explore, we find that margin on body is the culprit, so on the body rule let's add the definition margin: 0 and save.

header background with children in .container

Now let's add a new rule to the footer:

    footer {
        border-top: 2px solid rebeccapurple;
    }
Enter fullscreen mode Exit fullscreen mode

Save - and hold on, that did more than we wanted it to!

footer border doubled in blockquote

There's now also a border within our blockquote which also contains a footer element.

We could create a utility class to apply a border, but for purposes of this lesson, let's use the child combinator selector which is the > and means to select only elements that are a direct child of the qualifying selector. We'll modify our selector to body > footer and save. Now the footer that is nested within blockquote is unaffected by this rule.

Speaking of our blockquote, let's give him some styling love, too.

It can be helpful to use the element.style section to try out new styles before you commit to them in your stylesheet, and also to take advantage of the helpers provided by the browser, so let's select the blockquote and try it.

Add background and then if we begin to type linear-gradient the browser not only autocompletes but provides a default value. For things like gradients, developing in the browser is extra useful because the syntax is tricker than your average definition.

browser's auto linear-gradient

Instead of the pure black the browser defaulted to, let's update to a softer value that's a tint of rebeccapurple. To figure out that value, let's Inspect header and open the color picker, and slide the picker icon at roughly a 45 degree angle toward the top left until it's on a really light purple. Click on the generated hex value and copy it. Don't worry about reverting the header value since we're focusing on the blockquote right now.

Return to the blockquote and update the value of black in the linear-gradient to the value you copied. The value I selected is #eddbff.

using Inspector to choose purple tint

We can now copy the background definition, and move it to our stylesheet, where we'll add a few more properties to complete the rule:

    blockquote {
        background: linear-gradient(45deg, #eddbff, transparent);
        color: rebeccapurple;
        margin-left: 0;
        margin-right: 0;
        padding: 1em;
        border-radius: 4px;
    }
Enter fullscreen mode Exit fullscreen mode

final blockquote appearance

We're almost done, but we need to deal with our image, so let's uncomment that to add it back in. Let's also update the src url to drop the x150 which was added in error in the HTML lesson.

default image placement

The main issue here is the lack of space between the img and the surrounding content. Now, we want a rule that won't affect every img we may add to the site, just left-aligned images in our articles.

We also committed an error in our HTML lesson - which was done purely because we hadn't learned CSS yet! That error was using the align attribute which is actually what is called "deprecated". Deprecation means it used to be a valid attribute but is no longer recommended and support for it could be dropped in future browser versions, so we shouldn't rely on it.

Instead let's create a utility class:

    .img--align-left {
      float: left; /* replaces the style previously inherited by the browser */
      margin: 0 16px 16px 0;
    }
Enter fullscreen mode Exit fullscreen mode

Then on the img HTML, remove the align attribute and replace it with class="img--align-left".

<img src="http://placecorgi.com/200" alt="Good corgi doggo" class="img--align-left" />
Enter fullscreen mode Exit fullscreen mode

Save, and it's looking better with the margin added to give it some breathing room.

Let's add one more property for visual flair and use border-radius: 50% and save. You can see that the image now appears as a circle! 50% is a special value that can produce a circle, but only on square elements. If the element is not square, it will begin to have a more oval appearance.

circular image with border-radius

Our use of the placecorgi service is returning a 200px square image, which mimics an image that you may add into your blog from a CMS such as WordPress where you could also define precise dimensions, therefore ensuring a square base image. We'll explore a different method of ensuring visually consistent image sizes in our capstone project.

Finally, let's update our margin to actually use a negative value instead of 0 for the margin-left, so the definition becomes 0 16px 16px -20px and save. This allows it to tuck into the space created by the padding defined by .container but not extend out beyond the boundary of the article.

image with negative margin-left

Here's the final result on CodePen:

Next up in Episode 14: Styling a Card Layout

Top comments (4)

Collapse
 
lucassimpsonfkse profile image
LucasSimpsonFKSE • Edited

This tutorial is fantastic. I like the way how you explained what is CSS and how to use it. I am a programmer and I have used a lot HTML and CSS. I suggest you to create your own website using one of consulting wordpress theme. There you should post many more tutorials about CSS, HTML, and javascript. I am sure that you will be able to have a lot of success and a lot of happy users that will find you as a mentor for them. I have learned a lot of good things from your tutorial, even if I have used CSS before. Good luck and I wish I will see a website created by you with a bunch of tutorials.

Collapse
 
sanjayk08380402 profile image
sanjay kumar
Collapse
 
sanjayk08380402 profile image
sanjay kumar

Useful, since I always do CSS reset at first and then build all the rules myself
style tag in html in hindi

Collapse
 
madza profile image
Madza

Useful, since I always do CSS reset at first and then build all the rules myself ๐Ÿ˜‰