Ionic Design: Profile Page

When reviewing questions on the Ionic Forums, I often see questions that are frequently asked. I recently saw a request for help about creating a profile screen, and since I was working on similar features, so the request for help on implementing the design of this profile screen came at a good time.

dribbble-profile

The original design in this example was done by Sebastian Heit and was posted on Dribble. Before we dive into the code, let’s break down the design into sub-tasks to help focus the effort. First, this design has a transparent header and a full-width image as a header graphic. Next is the avatar image, Roger Federer, that sits in between the header image and the lower section. This is a standard design for many profile screens. Beneath the avatar is some player information and some social media buttons. The sample on Dribble included some tabs, but for my attempt, I will ignore that design element.

To recreate this design I needed to obtain visual elements. The header graphic (in this case a tennis court) and a headshot of Roger Federer. I found a nice profile image of Roger Federer without any trouble. For the header graphic, I searched Flickr for a suitable substitute. I found this image by Zepfanman.com, and it is available to be used by me.

Isner v. Kohlschreiber, Part III

I brought the image into Photoshop to apply the blue tint and the blur effect, giving me this result:

Isner v. Kohlschreiber, Part III

The revised image.

Getting Started

I generated a new Ionic blank template: $ ionic start profile blank –type=angular, then copied the background image and the avatar image into the newly created assets folder in the project directory.

Step 1: Transparent Header

The first styling task that I wanted to take on was to make the header transparent. Since Ionic’s header component supports this style, I just needed to add a translucent attribute to the ion-header tag. By itself, this will only make the header transparent while the ion-content will still be positioned under the header. This means if our content were to scroll, it would not scroll under the header. If that is what your design calls for, you need to add the fullscreen attribute to the ion-content as well and set it to true.

In the HTML template, I added buttons that were in the design; a button with an icon of the Back arrow with a label of Favorites and, a Checkmark button. Since this is not in a real app, the Back Arrow is an actual button in my sample. Typically, this would be an Ionic Back Button component in order to pick up the built-in navigation features.

Another thing to note is the checkmark button. Ionic’s icon library has that icon available. There was one minor issue with it in that the interior checkmark was transparent. This did not match the design, so I took the source SVG file and made a quick edit to change this. I saved this new version of the icon into the assets folder as well. That ion-icon will use the src attribute to point to my icon instead of the name attribute which will use the Ionicon library.

Header Image

The next step in recreating this design was applying that header image I prepared earlier. Switching from the HTML template file to the .scss file, this I can set the –background variable of the ion-content component to point to the background graphic. Positioning is set to be the top and center. As for how the image should be shown in the viewport, I opted for cover and fixed. I also did not want it to be repeated, so I included the no-repeat option.

In the .scss file, I also made sure that the ion-toolbar‘s background was transparent by setting its background variable to transparent.

If you save both files and run $ ionic serve in the command line, you should see the image being applied to the background and also under our transparent header.


<ion-header translucent no-border>
<ion-toolbar>
<ion-buttons slot="start">
<ion-button color="light">
<ion-icon slot="start" name="ios-arrow-back"></ion-icon>
Favorites
</ion-button>
</ion-buttons>
<ion-title>&nbsp;</ion-title>
<ion-buttons slot="end">
<ion-button>
<ion-icon slot="icon-only" src="../../assets/checkmark-filled.svg"></ion-icon>
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content fullscreen="true" slot="fixed" >
<div class="ion-padding">
The world is your oyster.
<p>If you get lost, the <a target="_blank" rel="noopener" href="https://ionicframework.com/docs/">docs</a&gt; will be your guide.</p>
</div>
</ion-content>

view raw

home.html

hosted with ❤ by GitHub


ion-content {
–background: url(../../assets/background_full.jpg) no-repeat top center/cover fixed, #fff;
position: relative;
height: 100%;
width: 100%;
}
ion-toolbar {
–background: transparent;
}

view raw

home.scss

hosted with ❤ by GitHub

Now to add the avatar image and the player content.

Step 2: Player Avatar

Creating the avatar portion of the design will be done using various divs and applying the correct CSS positioning types. Let’s being by defining the HTML structure. To begin, we will wrap everything in a basic div and give it a CSS class of card. This div will act as our master container for our content. Next, we will add another div that will provide the vertical spacing needed to show the rest of the header image. On that div, we will set the class to header.  Within the header div, another div is added, which will be used to position the avatar image. Here is the full HTML snippet:


<div class="card">
<div class="header">
<div class="avatar">
<img src="../../assets/player104.png" alt="">
</div>
</div>
</div>

view raw

home.html

hosted with ❤ by GitHub

Switching to the home.page.scss file, we will add the CSS needed to style and position the avatar. The card class will center the content horizontally by setting the margin value to be 0 and auto. Then set the header class to define the height of the div to be 200 pixels. The avatar class is where the heavy lifting will begin. The width and height of this div will be the desired width of our avatar image. The critical CSS that needs to be applied is setting the position attributes value to relative. For good measure, we will set the margin to be 0 and auto (to ensure centering horizontally). Within the avatar div, the image tag will be defined by setting its source to a nice profile photo of Roger Federer. It is on the image tag that CSS will make our avatar how we want it. First, the display type is changed to block from inline. Next, the border-radius is set to 50% to generate a circle around the image. The border property is set to be 8 pixels, solid and our green (#9DC912). In case the image has transparency, set the background color to white. Otherwise, our header image will be visible inside the avatar. Those properties will get our shape and style correct, but will not solve our positioning needs. To fix that, change the position property to absolute. This will allow us to place the image where we want it. Since its parent’s position is relative, it will be set absolute with respect to its parent and not the page. However, we still need to define what that absolute location is. Here we can leverage the CSS calc function to solve this. While I could have supplied a pre-calculated number, I wanted to demonstrate the math behind the value. The goal of the calculated number is to place the image half-way down its height (including the border). In this case, it is 80 pixels (half the defined avatar width) + 4 pixels (half the border width) times -1, so that image is moved downward.


.card {
margin: 0 auto;
.header {
height: 200px;
.avatar {
width: 160px;
height: 160px;
position: relative;
margin: 0 auto;
img {
display: block;
border-radius: 50%;
position: absolute;
bottom: calc(-1*(80px + 4px));
border: 8px solid #9Dc912;
background-color: #fff;
}
}
}
}

view raw

home.scss

hosted with ❤ by GitHub

Here is what the screen should look like at this point:

avatar-1

Since there is no additional content yet, the avatar will be ‘floating’ over our background.

Step 3: Player Information

With our avatar in place, we can turn our attention to the player information portion of the design. This portion is mostly a collection of traditional HTML tags, along with the ion-chip component and the ion-button component.


<div class="card-body">
<div class="user-meta ion-text-center">
<h3 class="playername">Roger Federer</h3>
<h5 class="country">Switzerland</h5>
<h6 class="ranking">Current ranking: <ion-chip>
<ion-label>2</ion-label>
</ion-chip>
</h6>
</div>
<ion-button expand="full" color="primary">http://rogerfederer.com</ion-button&gt;
<ion-button expand="full" color="secondary">@RogerFederer on Twitter</ion-button>
<ion-button expand="full" color="secondary">View profile at ATP</ion-button>
</div>

view raw

home.html

hosted with ❤ by GitHub

The CSS for the card-body is where we need to set two things; the background color (white) and the height. If we don’t set a height value, this div might not fill the screen. To solve this, the CSS calc function will come to rescue again. This time we will take the full height (100vh) and subtract the header height we defined (200 pixels), as well as the toolbar’s height (56 pixels). We will also adjust the spacing, font size, weight, and color of some of the other elements as well.


.card-body {
background-color: #ffffff;
padding: 30px;
height: calc(100vh – (200px + 56px));
overflow: hidden;
.user-meta {
padding-top: 40px;
.playername {
font-size: 24px;
font-weight: 600;
color: #303940;
}
.country {
font-size: 90%;
color: #949ea6;
text-transform: uppercase;
margin: 0 auto;
}
}
}

view raw

home.scss

hosted with ❤ by GitHub

For styling the ion-chip, we just need to set the –background variable to #9DC912 and the –color variable to #fff.

The final touch is to set the overall CSS variables to align with our design. Using the Ionic Color Generator I altered the color set. Here are the changed color values:

  --ion-color-primary: #5c6a76;
  --ion-color-primary-rgb: 92,106,118;
  --ion-color-primary-contrast: #ffffff;
  --ion-color-primary-contrast-rgb: 255,255,255;
  --ion-color-primary-shade: #515d68;
  --ion-color-primary-tint: #6c7984;

  --ion-color-secondary: #9ba4ac;
  --ion-color-secondary-rgb: 155,164,172;
  --ion-color-secondary-contrast: #ffffff;
  --ion-color-secondary-contrast-rgb: 255,255,255;
  --ion-color-secondary-shade: #889097;
  --ion-color-secondary-tint: #a5adb4;

  --ion-color-tertiary: #303940;
  --ion-color-tertiary-rgb: 48,57,64;
  --ion-color-tertiary-contrast: #ffffff;
  --ion-color-tertiary-contrast-rgb: 255,255,255;
  --ion-color-tertiary-shade: #2a3238;
  --ion-color-tertiary-tint: #454d53;

  --ion-color-success: #9dc912;
  --ion-color-success-rgb: 157,201,18;
  --ion-color-success-contrast: #ffffff;
  --ion-color-success-contrast-rgb: 255,255,255;
  --ion-color-success-shade: #8ab110;
  --ion-color-success-tint: #a7ce2a;

If you have not worked with adjusting the global variables, these are defined in the variables.scss file. With that, we have recreated the profile screen!

profile-2.png

The full source can be found at: https://github.com/chrisgriffith/ionic-profile-design Feel free to ping me with questions or other design challenges in Ionic.

 

One comment

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.