Ionic Design: Profile Page





Isner v. Kohlschreiber, Part III


Isner v. Kohlschreiber, Part III

The revised image.

Getting Started


Step 1: Transparent Header




Header Image




Now to add the avatar image and the player content.

Step 2: Player Avatar



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



Step 3: Player Information





  --ion-color-primary: #5c6a76;
  --ion-color-primary-rgb: 92,106,118;

  --ion-color-secondary: #9ba4ac;
  --ion-color-secondary-rgb: 155,164,172;

  --ion-color-tertiary: #303940;
  --ion-color-tertiary-rgb: 48,57,64;

  --ion-color-success: #9dc912;
  --ion-color-success-rgb: 157,201,18;



The full source can be found at: Feel free to ping me with questions or other design challenges in Ionic.


Dynamic Ionic Theming

With the shift to CSS variables for much of the styling of the Ionic components, a popular question on the Ionic forums is “How do I dynamically change the look my application at runtime?” For example, wanting a light or dark theme, or have the controls match the logo colors of your favorite sports team. In this post, I am going to show you the basics for doing this. To begin, generate a new Ionic application:

$ ionic start themedemo blank --type=angular

Once it is finished generating, open the home.html. Let’s replace the template code with the following:

This new template has some elements in the ion-header and three buttons that will we can use to alter the applied CSS variables.

Let’s set up the CSS variables that we will be interacting with, open the variables.scss file that is located in the theme directory. If you have not worked with this file before, this is where all the default Ionic theme colors are defined; primary, secondary, etc. In the :root declaration, we are going to add two new variables that we will be changing via our code. Add a –mycolor variable and set its value to rebeccapurple, and another variable –mytextcolor and define its value as #fff. Your variables.scss file should look like this at the start:

With our two variables now defined, we can now apply them. Open the global.scss file. This file is the proper place for setting any global CSS to our application. In this simple example, we are just going to change the background color and the text color of our Ionic toolbar. By checking the Ionic documentation on that component, there are two defined CSS variables for those properties; –background and –color respectively. If we just want to override the values, we could set them directly like this:

Unfortunately, we can not directly assign a CSS variable to another in this fashion. Instead, we need to declare it as a var before we can set the value of the property. To do this, we change our CSS to use the var function (

If you saved all the files and ran $ ionic serve, you should see your header’s toolbar in a nice purple and the text in white. Since there are no methods for those buttons to call they won’t function (and odds are your editor might be warning you about that fact).

Switching to the file, let’s add those methods. After the class definition, add an object that will define our theme colors. For more robust theming I would suggest creating a service or module that contains your theme management, but this example we will not add that level of complexity. Here is our new variable:

theme = {
  mycolor: 'rebeccapurple',
  mytextcolor: '#fff'

Currently, the Blank template’s component does not include a constructor, so let’s add a basic one:

constructor() { }

For the colorIt method, I want to show you how to set the property directly. This option works well if you are setting a small number of variables. To do this we will call method. This method has three parameters: the property name, the value (optional), and the priority (optional). Since we are interacting with CSS variables, we can not set the property name as –mycolor. Instead, we need to wrap the CSS variable with a ` or backtick. The new value that we want to set can be wrapped with the standard single quote. Here is what the code should look like:

colorIt() {`--mycolor`, '#ccc');`--mytextcolor`, '#000');

 Those two lines will change the CSS variables to their new values, and trigger a repaint of the screen.

But what if swapping themes requires changing more than just a few variables? Let me show you the foundation for solving that challenge. Two of the buttons in our template called the setTheme method, each passing in a string that was a theme name (light or dark). This method will update the theme object we defined in our class with new values. But the workhorse of the method is actually the forEach loop that we will call. This will walk through each of the properties names and set their values. Here is the full code:

setTheme(userTheme: string) {
  if (userTheme === 'dark') {
    this.theme.mycolor = 'rebeccapurple';
    this.theme.mytextcolor = '#fff';
  } else {
    this.theme.mycolor = '#ccc';
    this.theme.mytextcolor = '#000';

  Object.keys(this.theme).forEach(k =>`--${k}`, this.theme[k])

If you have not seen the ${} before, this is ES6’s template notation. If you run the application now you should be able to toggle the header bar color and text color. 


So, there are the basics for having dynamic themes in Ionic 4. Like I mentioned, you are probably going to want to expand upon this to have a proper service or module to manage your theming across your application. Feel free to ping me with questions or other design challenges in Ionic.

Ionic Design: Using the Grid Component

One of the things that catch my eye when I am scanning the Ionic Forums is design related questions. Sometimes these are questions around styling a component, but sometimes the poster asked for a more complex design solution. I save these, and when my schedule allows, I will tackle them. This design challenge was someone looking for a solution in the layout of a card. Here is my Adobe XD clone of the initial request (I have opted not to share the initial query).


As you can see there is an avatar, user name, game stats, and an action button.


Now I suspect the avatar might have led the poster to look at using the Ionic avatar component and in turn, the Ionic List component. Instead, I opted to leverage the Ionic Grid to solve this layout. Although there are four regions, I opted to consider this design to use two regions; one for the request button and one for the rest. While one might have chosen three regions, I wanted to make sure that the avatar was connected to the user name and game stats. By placing the user name and game stats in their own cell, it could shift positioning.

Let’s place our initial content within two columns in the Ionic grid inside an Ionic Card component:

We will focus on the text styling first. We will place the user name inside an h1 tag and add a CSS class of userName.

In our scss file we will set the following properties:

For the game stats, we will place it in a paragraph tag. For each stat, we will wrap in a span tag and assign each a specific CSS class for wins, draws, and losses. By doing this we can leverage the border property to create the colored bar under each stat.

Here is the CSS for this:

Turning to the avatar, we can apply the border-radius property and also enforce a maximum width. We will address positioning in a bit.

Our final element to be styled is the call to action button. This element will be the Ionic button component.

The Ionic button will adapt to each platform, which requires overriding some of those settings, notably the border radius and the text case. For the latter, we can set the CSS variable for border-radius and the background color.

The button’s text case is not one of the listed variables. Instead, we can use of one the Ionic’s CSS utilities. For Ionic, many of these CSS styling helpers were CSS attribute selectors. But with Ionic expanding to other frameworks, these helpers have become namespaces CSS classes. So we can apply the ionic-text-uppercase case to our button.

That covers the basic visual styling, so let’s tackle our positioning. The Ionic grid is built upon the CSS Flexbox. Flexbox is a powerful layout solution for layout in one direction.

Since we want our content to be vertically centered, we can use the align-items-center value for a flexbox. For the Ionic grid, we declare this on the ion row by applying it via a CSS class.

Next, we need to define the positioning of our two ‘cells’. For this, we can use Flexbox’s justify-content-between to position them against either side. Again, this is done by adding in a CSS class.

Let’s deal with our avatar and the text. The solution I opted to use was to turn the image into a block level element and float it to the left. We will add some margin to the right side to bump the text over. The game stats could also use some spacing between them and the user name so we can add some margin to that paragraph tag.

The button also needs some layout attention as it is currently aligned to the left of the container. What we would like is for the button to be anchored to the right edge of the container. To solve this we can apply another Ionic CSS utility class — the ion-float-right class.

The final touch is to reduce the inner spacing of our containing Ionic card component. If you scan the Ionic documentation, you will not find a CSS variable to adjust this. But fear not! Pulling up Dev tools in our browser we can see that that spacing is applied directly, meaning we can override it without difficulty.

Here is the final output running on my iOS emulator.


I think the design is fairly close to what I was using a reference. To learn more about Ionic CSS Utilities, see their documentation. For more information about the Ionic grid, I suggest you read over this section in the documentation.

If you found this design exercise useful or have questions let me know.

Background Images for Ionic 4

A common UI design that is applied to many mobile applications is to have an image serve as the background. This is a question that I see asked multiple times on the Ionic Forums, so I thought I would take a moment and outline the best approach to achieving this effect.

If you only need to attach your image to a specific page, just go to that page’s .scss file and define the –background variable. Here, I will set the image to reference a bg.jpg file I have in my assets directory, as well as set the parameters of how it should be rendered.

ion-content {
  --background: url(../../assets/bg.jpg) no-repeat center/cover fixed;

Note, the path to the asset is relative to the page’s directory.

But what if you wanted that image to be used across all of the pages? You could then move the code to the global.scss file. Since this is now being applied a global level, we need to adjust the url path:

ion-content {
  --background: url(/assets/bg.jpg) no-repeat center/cover fixed;

This initially will work, but watch closely when we transition from screen to screen. The background image will either shift or blank out for a moment.

This is due to the fact that the ion-content component that we have targeted with our CSS, is being destroyed when we navigate from screen to screen. To solve this we need to remember that Ionic at its heart is still just the web. So rather than focus on Ionic’s web components, we can think about what other HTML elements we might be able to use.

The answer is to have the body tag be the element that we attach our image to. So, in the global.scss file we can add:

body {

However, if you just made that change, you will find that the image no longer is visible. This is because the default values for ion-content are being applied. Meaning, the fill color is now being used, thus covering our image. To solve this, we need to override that with:

ion-content {
  --background: none;

And now we will have a nice static background for the application. (1)

Centering Gallery Elements

Recently, I was rebuilding one of my websites to be responsive. It is important to take advantage of the capabilities of modern browsers and be responsive, to support the growing use of the site on mobile devices. One portion of the design was a set of image gallery pages. These pages are pretty straight-forward, up to 5 columns of photos per row centered within the width of the page. As the window width reduces, the number of columns reduces. Again, nothing out of the ordinary with this design.


Block version of the design


I began by centering the containing div by setting the CSS properties of margin-left and the margin-right values to “auto”. That positioned the containing div correctly and it responded as expected as the browser width was changed. However, as the width of the window reduced, the thumbnails would begin to start to flow down to the next row, but they would display centered within the containing div. Not exactly the design I was looking for.

Centered elements

Centered elements

I applied a float:left to the thumbnails, and my centering last row was fixed! However, it introduced a new problem–the thumbnails no longer appeared to be centered as a group within the page. Adding the float to the thumbnails introduced extra spacing between the last column and the right boundary of the containing div.

Highlighting the margin right issue

Highlighting the margin right issue

I knew that had to be solved, so I began looking at many of my favorite tutorial sites, and found nothing. Lots of great samples of gallery pages, but all using the full width of browser in their samples or the thumbnail sizes would adapt to their widths. Nothing seemed to fit my design.

Next, I decided to look at using Flexbox. I had made the choice to only support “modern” browsers, so I knew that I did not need to worry too much about compatibility issues. But the same issues remained as I experimented with the various flex layout options; the last row items would be centered, or the gap on the right existed. Back to the drawing board!

Then I got to thinking about how the layout was computed. Each thumbnail would take the same fixed amount of space. Each would position itself to the left due to setting the float property to left. If the thumbnail did not have enough space within the width of the container, it would move to the next row. Float 101, right? But how did it know the space it had? I only defined the containing div to have a max-width and to center itself, and the width would vary based on the width of the window. It then struck me that if the width of the containing div matched the number of allowable columns, then there would not be extra space along the right.


If I can set the containing div to match my column widths, that container will still be properly centered. So I calculated the computed widths for 2,3,4, and 5 columns of thumbnails. So, when the browser’s width reaches specific widths, the containing div’s width is fixed to match the allowable number of columns. With a fixed width instead of a dynamic width, it can be properly centered on the page. Design problem solved!
The resulting CSS looks like this

 #photoMenu {
   margin-left: auto;
   margin-right: auto;
   height: auto;
   min-height: 220px;
 .thumbnail {
   position: relative;
   border: 5px solid #ddd;
   float: left;
   margin: 20px;
   width: 160px;
 .thumbnail img {
  max-width: 100%;
 .thumbnail h3 {
   position: absolute;
   bottom: 0;
   left: 0;
   width: 100%;
   margin: 0;
   text-align: center;
   color: white;
   font: bold 1em/1.5em Verdana, Sans-Serif;
   background: rgb(0, 0, 0);
 @media (min-width: 315px) {
   #photoMenu {
     width: 210px;
 @media (min-width: 525px) {
   #photoMenu {
     background-color: darkseagreen;
     width: 420px;
 @media (min-width: 735px) {
   #photoMenu {
     background-color: rebeccapurple;
     width: 630px;
 @media (min-width: 945px) {
   #photoMenu {
     background-color: bisque;
     width: 840px;
 @media (min-width: 1155px) {
   #photoMenu {
     background-color: aqua;
     width: 1050px;

For each of the media query breakpoints, I added a background color just to highlight it. Here is what the HTML looks like:

<div id="photoMenu">
  <div class="thumbnail">
    <img src="thumbnail.png" alt="">
  <div class="thumbnail">
    <img src="thumbnail.png" alt="">
  <div class="thumbnail">
    <img src="thumbnail.png" alt="">
  <div class="thumbnail">
    <img src="thumbnail.png" alt="">
  <div class="thumbnail">
    <img src="thumbnail.png" alt="">
  <div class="thumbnail">
    <img src="thumbnail.png" alt="">
  <div class="thumbnail">
    <img src="thumbnail.png" alt="">

You can see the completed sample here.

Little design…

With the upcoming 70th anniversary of the dawn of the atomic age, I am refreshing several of my websites on the subject. The first site I am working on is Trinity Remembered. The new design is now responsive. The images are much larger (and more of them). But one particular page was not quite right. All the other ‘menu’ screens had visual elements, while this one just had the list of available documents. So I spent some time fiddling with it. I tried adding icons before each document to see if that could solve. But in the end, it was as simple as increasing the indents of the sections and adding a thin gray rule under each sub-section was enough. This gave the eye enough clues of how to parse the information without being overwhelmed. Just thought I would share a tiny bit of my design process.