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:
|<p>6W 3D 2L</p>|
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.
|<h1 class="userName>Chris Griffith</h1>|
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.
|<span class="wins">6W</span><span class="draws">3D</span><span class="losses">2L</span>|
Here is the CSS for this:
|border-bottom: 6px solid #62f254;|
|border-bottom: 6px solid #edce59;|
|border-bottom: 6px solid #d04749;|
Turning to the avatar, we can apply the border-radius property and also enforce a maximum width. We will address positioning in a bit.
|<img class="avatar" src="../../assets/avatar.png" />|
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.
|<ion-button class="ion-text-uppercase">Register Result</ion-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.
|<ion-row class="ion-align-items-center ion-justify-content-between">|
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.
|<ion-button size="small" class="ion-float-right ion-text-uppercase">Register Result</ion-button>|
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.
|-webkit-padding-start: 0 !important;|
|padding-inline-start: 0 !important;|
|-webkit-padding-end: 0 !important;|
|padding-inline-end: 0 !important;|
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.