How To Build A Tribute Page (freeCodeCamp Challenge)

by kleamerkuri
khalil gibran tribute page freecodecamp challenge

A step-by-step solution to freeCodeCamp’s Tribute Page Challenge. I’ll be using FCC’s codepen tribute page example as a reference. This is purely a CSS and HTML project – keep in mind my solution is one of many!

The final product is this:

See the Pen Tribute Page Challenge (FCC) by Klea Merkuri (@thehelpfultipper) on CodePen.

User story requirements:

  1. #main container in the body
  2. #title with heading for tribute subject
  3. #img-div container with #image for the visual and #img-caption for the caption
  4. the image should be responsive and centered
  5. #tribute-info container with text
  6. #tribute-link anchor that opens to a new page

The tribute subject I chose is Khalil Gibran, the man who inspired me to “not love half-lovers” and “not live a half-life”. If you haven’t heard of him, you’ll know more than your fair share following this challenge!

1. Start with the main container

Add semantic meaning to the page for accessibility and readability by setting a structure. This includes:

  • Header: for the title and visual. I assume here that this will be constant across various non-existent pages.
  • Main: for the textual information about the tribute subject. This is unique information that appears once.
  • Footer: for the external link.
  <div id="main">
    <header>
      <div id="title"></div>
      <figure id="img-div">
        <img src="" alt="" id="image">
        <figcaption></figcaption>
      </figure>
    </header>

    <main id="tribute-info"></main>

    <footer>
      <a href="" id="tribute-link"></a>
    </footer>
  </div> 

Give #main background color, margins on the top and bottom of 30px, and set any font styles you desire – I kept it simple.

Center the contents of #main since we need everything placed in the middle of the page and give it box-sizing to include margins/paddings in the dimensions.

Read: CSS Visual Formatting: Margin, Padding, Borders

#main {
  background-color: #EEEEEE;
  margin: 30px 0;
  font-family: sans-serif; 
  font-weight: 300;
  text-align: center;
  box-sizing: border-box;
}

2. Add a title

Set font size to make the contents of #title larger relative to the parent container (so they adjust in smaller screen sizes) and add space on top of the title using padding.

<div id="title">
    <h1>Khalil Gibran</h1>
    <p>A man of mystical Arabic and English works</p>
</div>
#title {
  font-size: 150%;
  padding-top: 50px;
}

3. Include a responsive image

For the image, I’m using the figure element instead of a div to improve accessibility. Since the reference sample includes a caption for the image, it makes sense to use figure to group the visual aspects – the image and the caption – together.

The image is hosted on the Github repo for this project and served on Github pages using the steps outlined in this helpful article about using local images in Codepen.

    <figure id="img-div">
        <img src="https://thehelpfultipper.github.io/tribute_page_fcc/khalil-gibran-youth.jpeg" alt="Photograph of Khalil Gibran During his youth." id="image">
        <figcaption id="img-caption">Photograph of Khalil Gibran During his youth. Source <a href="https://www.poetryfoundation.org/poets/kahlil-gibran">Poetry Foundation</a>.</figcaption>
    </figure>

Start styling by giving #img-div a white background and margins. Then add more space using padding for the image and caption.

#img-div {
  background-color: white;
  margin: 40px 20px;
  padding: 20px 10px;
}

img {
  margin-bottom: 15px;
  max-width: 100%;
  height: auto;
}

Make the image responsive by setting a max-width at 100% and height to auto. A max-width of 100%, for example, ensures the image will not extend beyond 100% of the parent, yet, it can size down proportionately to the parent as the screen size becomes smaller. This behavior is what makes the image “responsive”.

Note: There are different ways to achieve responsiveness. You could, also, opt for media queries.

4. Insert a life timeline

The timeline with life details will go into the #tribute-info container.

<main id="tribute-info">
    <h3>Here's a time line of Khalil Gibran's life:</h3>
    <ul>
        <li><strong>Year</strong> - Details</li>
        ...
    </ul>
</main>

For the quotation, I’ll be grouping the quote with the caption by way of another figure element.

<figure>
    <p><em>"The English have Shakespeare, the rest of the world has Gibran."</em></p>
    <figcaption><em>-- me, myself, and I</em></figcaption>
</figure>

Additionally, I’ll include a disclaimer citing the source of the timeline details characterized by the small element. This element will make sure to scale down and de-emphasize the content within the <small> tags automatically.

<p><small>*Timeline details courtesy of <a href="https://www.timetoast.com/timelines/gibran-khalil-gibran">mahaz</a></small>.</p>

By this point, you’ve noticed that the text is aligned in the center which is not what we want for #tribute-info content. The reference shows the content is left aligned and has a smaller width. The h3 title though remains center aligned.

So let’s make #tribute-info 60% the width of its parent and center it using margin auto.

#tribute-info {
  width: 60%;
  margin: 0 auto;
}

But notice that when you make the screen smaller, the relative width only remains at 60% of its parent which is far too narrow. On smaller screen sizes, we’d like to increase the width of #tribute-info to at least 90% of its parent. We’re not taking up the entire width here because we want to match the layout of the reference.

Achieve the larger width on smaller screen sizes using a media query. For any screen 750px or less, the width of #tribute-info will resize to 90% of its parent. This way the content isn’t in an overly narrow container.

@media (max-width: 750px) {
  #tribute-info {
    width: 90%;
  }
}

To keep the title in the center yet left-align the rest of the content in #tribute-info, use the CSS not selector as it reduces the amount of code you need to write.

#tribute-info :not(h3) {
  text-align: left;
}

For the list items we need to:

  1. increase the space between the lines of a single item
  2. increase the space between items

Add line-height: 1.5rem to the #tribute-info :not(h3) selector. Then modify some more spacing by setting margins and paddings for the title, disclaimer as well as list items.

h3, ul {
  margin-bottom: 40px;
}

ul li {
  margin: 15px 0;
}

.disclaimer {
  margin-top: 30px;
}

I, also, want to lend more weight to the bolded words so set a higher number for the font weight of the strong element.

ul li strong {
  font-weight: 600;
}

5. Add the link in the footer

The last thing left to do is add the footer content which includes the #tribute-link. Add the target attribute to the link so it opens on another page! Give the footer some padding and a line-height to match the reference like so:

    <footer>
      <h3>If you have time, you should read more about this incredible human being on his <a href="https://en.wikipedia.org/wiki/Kahlil_Gibran" id="tribute-link" target="_blank">Wikipedia entry</a>.</h3>
    </footer>
footer {
  padding: 5px;
  line-height: 1.5rem;
}

Troubleshooting

Now run the tester to see if we passed. If you’re following along, you probably ran into this error: “1. The <img> element should responsively resize, relative to the width of its parent element, without exceeding its original size.”

The program is telling us to “Use the ‘display’ style property with a value of ‘block’ for responsive images”. Currently, our image is responsive, but to pass we need to modify it so we meet the checker’s criteria.

Go back to img and add the following three lines of code:

display: block;
margin-left: auto;
margin-right: auto;

The auto margins on the left and right are necessary to center the image which we turned from its default inline display to a block-level element.

Click for more on inline and block elements.

Now run the test again and, yay, we passed! You can find the full code on Codepen and GitHub.

Don’t forget to check out other projects 🙂

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.

Related Posts