Building About Page Styles for React Portfolio
In the next few guides, we are going to knock out a few of the remaining style and content related items we need to complete our portfolio.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

We're gonna start with the About and Contact pages, so in this guide, we're going to build out all of the styles and the content for our About page and then in the next guide, we'll finish off the Content page.

This should be a lot of review for you because we've really covered most of these concepts. We're not gonna be talking about state or really even working with the main components that make up React. We're instead gonna be focusing primarily on styles, such as implementing CSS Grid and being able to work with the file system, so let's get started.

My end goal for this is by the end of this guide, I wanna have an About page that has a big image that takes up half of the screen on the left-hand side. And then on the right-hand side, I want that to be where a bio goes and I want the bio to be centered in that white space.

So I want you to imagine that you are working for a development company or you are just building out your own application. You've been handed this task, you've been told exactly what you are supposed to go build, and then I want you to pause the video right now, and I want you to go do it. You have already learned each one of the skills needed in order to implement this.

So, in review, I want you to have an image that takes up exactly 50% of the width and 100% of the height on the left-hand side here, and then I want you to have content that is centered on the right-hand side. Feel free to pause the video now and I'm going to start showing my own personal solution for implementing this.

So, I'm going to start by creating a dedicated layout file. So, I'm gonna open up main here and I'm gonna create a new file here called import and called layouts, then I'm gonna copy layouts before hitting save, and I'm going to add that to our style directory. And this is where I'm gonna place all of the styles for our layout, this is going to work both for our About page and our Contact page.

So, I'll close out of main, and now let's see what type of styles we want. I'm gonna create a class here called content-page-wrapper, and I want the width for this to be 100% of the view width 'cause I want it to go all the way from one side of the screen to the other side, and because we want that split layout, this is a perfect situation for using grid.

So, I'm gonna say display: grid and then grid-template-columns is gonna be 1fr and 1fr, and we're not gonna use any grid gap. Now, we also, because we want the height going all the way from top to bottom, I wanna have the height at 100 view height. Now, I'm gonna warn you this isn't gonna work, but I want you to first see why it won't work because this is a very common bug that I've seen students run into when they're implementing a front-end. So, we're gonna keep it like this and then we'll fix it in a little bit.

layouts.scss

.content-page-wrapper {
  width: 100vw;
  display: grid;
  grid-template-columns: 1fr 1fr;
  height: 100vh;
}

So, first, let's save this, and let's add our content-page-wrapper to the About page. Right now, we just have a plain functional component and I'm going to add parens here so that our div is now going to be our div for the entire page and we're gonna have our grid here. So, I'll say div className is going to be content-page-wrapper and I'll get rid of this About text, and now we can add in our two columns, so we're gonna have the one on the left for our image and the one on the right for our content. So, let's just add those now.

I'm gonna give a div and let's duplicate that. The first one, I'm going to have a very creative name of left-column, and then for the next one, we'll have that one called right-column, as you might have guessed. And now, for this right-column, I'm just gonna add some placeholder text. Obviously, this is your portfolio so this is where your bio and your list of skills and experiences, all of those kinds of things, that is where that's going to go.

So, for right now though, I'm just going to pull in some Lorem Ipsum text. So, I have that just off-screen, so grab that, paste it in, and you can feel free to just put some placeholder content there for now, and come back later and add your own bio information.

about.js

import React from "react";

export default function() {
  return (
    <div className="content-page-wrapper">
      <div className="left-column"></div>
      <div className="right-column">
        Maecenas faucibus mollis interdum. Integer posuere erat a ante venenatis
        dapibus posuere velit aliquet. Sed posuere consectetur est at lobortis.
        Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.
        Aenean lacinia bibendum nulla sed consectetur. Maecenas sed diam eget
        risus varius blandit sit amet non magna. Morbi leo risus, porta ac
        consectetur ac, vestibulum at eros. Donec id elit non mi porta gravida
        at eget metus. Donec sed odio dui. Cras mattis consectetur purus sit
        amet fermentum. Etiam porta sem malesuada magna mollis euismod. Nulla
        vitae elit libero, a pharetra augue. Aenean eu leo quam. Pellentesque
        ornare sem lacinia quam venenatis vestibulum. Duis mollis, est non
        commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec
        elit. Praesent commodo cursus magna, vel scelerisque nisl consectetur
        et. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent
        commodo cursus magna, vel scelerisque nisl consectetur et. Nullam quis
        risus eget urna mollis ornare vel eu leo. Morbi leo risus, porta ac
        consectetur ac, vestibulum at eros. Vestibulum id ligula porta felis
        euismod semper.
      </div>
    </div>
  );
}

So, let's test this out, let's go to Google Chrome. And you can see this is working nicely.

large

We have on the left-hand side, we have what will be our image, and then on the right-hand side, we have all of our content. So, so far, so good, let's keep going. So, the next thing that we need to do is we need to be able to pull in an image. Now, I already added a personal image of mine and you can use whatever you want, I'm just doing a headshot photo. And so, I added it like we did with our auth page.

So, if you go into the root of your project and go to static, assets, images, I added a directory here called bio and I added my own image.

large

So, make sure, and the one I have right now is 6.48 megabytes, I will go into Photoshop and shrink it down, for right now, I'm not gonna worry about it. So, that is the image that we're gonna wanna pull in and if you remember, and you can also reference the auth component, I'm going to import it the same type of way that we would import a library.

So, I can say import and I'm just gonna call this profilePicture from and let's go a step back, we need to go a step back, another step back, and now we're in the root of our project. We can go to static/assets/images, there we go, slash bio, and then this is called just headshot.jpg.

about.js

import React from "react";
import profilePicture from "../../../static/assets/images/bio/headshot.jpg";

export default function() {
  return (

Okay, so now that we have our profile picture, we can actually use it and we can treat it like a regular image. So our left-column here is going to have some in-line styles. Everything that we're covering here, if you're thinking I'm going a little faster than normal, it's because I want this course really to be all about React, and whenever we run into something that we've already implemented, and we spent quite a bit of time walking through, then I treat the next few times more as just reinforcement learning.

So if you want, if this is fuzzy at all, we spent quite a bit of time on how all of this works, when we talked about styling the auth component, so definitely reference those. So now that we have that, we can apply those in-line styles. So for our left-column here, in addition to the className, I'm going to add a style prop here, or just a style rule, this is a, technically it's called in React a HTML attribute.

And so here make sure you use the double curly braces and we're going to apply three roles. The first one is gonna be the background, and if you remember back with the auth component, this is a little bit tricky because of how we have to work with strings. So I'm going to give double parenthesis here, say url with a paren and then I'm going to give a plus sign, so we're concatenating these strings together.

Now I'll say I want to include the profilePicture as the URL and then from there, I want to add another string where I close off the parens and I'm gonna say no-repeat and that's all we need to do for the background. And now let's add the backgroundSize and that is gonna be cover and let's see what else? We also want the backgroundPosition, there we go, backgroundPosition is going to be center.

about.js

return (
  <div className="content-page-wrapper">
    <div
      className="left-column"
      style={{
        background: "url(" + profilePicture + ") no-repeat",
        backgroundSize: "cover",
        backgroundPosition: "center"
      }}
    />

Okay, I believe this is all right but let's go, and let's test this out. Okay, there we go, perfect, so this is working perfectly.

large

We have the image, it is centered, it is working perfectly as a background image and now let's take this content here, and let's center it on the page and add the appropriate styling.

So I'm going to go into our layouts and let's add some styles for our right-column. And for the right-column I'm gonna say I want this to be display: flex, I want it to be justify-content: center, align-items: center, and then first, let's just take a look at, oh, and one other thing, we want flex-direction to be column 'cause we want these paragraphs stacked on top of each other, hit save,

layout.scss

.content-page-wrapper {
  width: 100vw;
  display: grid;
  grid-template-columns: 1fr 1fr;
  height: 100vh;

  .right-column {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
  }
}

and that's working, we're at least centered and now let's go and let's add a few other items such as padding. So for padding, we'll give it pixels, hit save, there we go, that is looking great.

large

So we're almost done, I just wanna show you one little tricky part on why this is not perfect. If you notice, and maybe it's slightly different on whatever screen you're on but this should be relatively similar if I scroll down, do you notice how the page is longer than the screen size? And that's not what we're wanting. What I want is for this to load up and for there not to be any scrolling involved, everything should be able to be seen on this one page.

The issue is we said that we want this entire component here, that class, we want it to be 100% of the view height. The problem with that is with how view height works and this is where it can be tricky if you've never seen this before.

View height takes the screen size, it doesn't accommodate for anything else on the page. So our view height here is the view height, it is correct, if you scroll all the way down, this is the full size.

The tricky part is it's forgetting, or it's not forgetting, it doesn't care that there is a navigation element there, so we need to take that into account. So if you, oh, I just hit back, so if you inspect the navigation component, the navigation component is always going to be 84 pixels tall. So what we can do is we can perform a calculation with our view height.

So if you switch into the content-page-wrapper, you can say calc 100% view height minus 84 pixels, hit save, and there we go. Now everything is working, there is no scrolling or any kind of overflow happening below the page and this looks a lot more professional. So if you click Home and then come back and click About, this looks like a real About page.

.content-page-wrapper {
  width: 100vw;
  display: grid;
  grid-template-columns: 1fr 1fr;
  height: calc(100vh - 84px);

  .right-column {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    padding: 100px;
  }
}

large

And also, this isn't related to programming, this is just on a career note, if you do not have a nice set of headshots or anything like that and you're looking to get a job or you're looking for freelance work, I definitely recommend for you to do that.

Hopefully, you have a friend, you shouldn't have to pay for it, if you have a friend with a nice camera, you can do something like that, it really can make a big difference when a recruiter is looking at your page, if they can see nice, crisp pictures of you, it can give them a good first impression.

So that's on a career note, I definitely recommend for you to do that and that's part of the reason why for this layout, I picked to have a nice, big image because this looks really nice, at least in my opinion and to the other people I've shown it to, they really like this type of layout and it's conducive for people who are looking for a job, so that's why we did it.

In the next guide, we are gonna walk through the same process for our Contact page.

Resources