Reliable grid layout in SAP Build Apps
If you’ve ever tried to layout things in a grid using SAP Build Apps, you might have noticed that it’s not as easy as you might think it would be. In this blog I will teach you how to make responsive grids that look just the way you’d expect them to!
Disclaimer: This grid functionality is made works for both web and mobile, BUT if web has navigation menu enabled, the layout will not work out of the box correctly for just one card, and the formula will have to be adjusted accordingly.
Step 1: Basic structure
The basis of my grid structure consists of two Container components within each other. The outer container is in this app called Questions and the inner container is Card. The purpose of the outer Questions container is to be a horizontal container with wrap enabled. Due to this, when we repeat the inner Card container with data, the cards will follow horizontally and then wrap to new rows when there is more than will fit the screen in one go.
The role of the inner Card container is to display the grid items and take care of all the grid items being the same size and otherwise look the same. Repeat the Card container with your data.
Now, before any customization to the width or height is done, your repeated data will look something like this:
This is not yet what we want, so onto the next step we go!
Step 2: Gaps and paddings
Surprisingly, the gaps between cards and the page’s paddings are a crucial part of getting the grid to look right.
First, set the Card containers gaps to be as you desire. In a typical grid, the gap should be the same to the right as it is to the top (or bottom if you choose to use bottom instead of top). Take note of the gap you set to be to the right + left of the component, as you will need this number of pixels in step 3. For me this number is 16px + 0px, so 16px. The formulas in the next step might not work if you also set left gap, so only set one of them if possible.
Next, you’ll want to set the page paddings, and this will affect all the components on the page.
Why do you need to set page paddings, you ask? Good question, but frustrating answer: because there’s an unavoidable gap to the right of every wrapped row that you can’t remove, and the way to make it unnoticeable for the user is to do this trick with the page padding.
Remove as much from the page padding to the right as you set as the right gap in the previous part. 16px in my case. Take also note of the total padding of the page on the left and right. 32px + 16px = 48px in my case.
Now you’ll need to add this to all of the rest of the components on the page. I do this by chucking everything else on the page in a container or two and giving those containers the same amount of right padding as I removed from the page padding, and the issue is gone.
Step 3: Define advanced height and width for card
Now that everything else has been prepped, to get our desired grid effect on Card, we will be using the “Advanced” section under “Layout” properties.
These are the only values you need to set, and if you don’t care how small the card may get, you can skip the minimum width. Set the height to the height you want every item to be.
The magic itself happens in the formula I’ve set for the width. I wanted the grid to have a different amount of cards depending on how wide the available viewport is, so I’m using systemVars.dimensions.viewport.width in my calculations. I recommend to always using viewport instead of screen or window, since this will give the most usable value for both mobile and web. Viewport is the size of the browser or on mobile the size of the screen available for the app.
After determining how wide the screen is and choosing how many cards I want to be shown (4, 3, 2 or 1), I need to do some deductions to take into account the page paddings and the gaps between the cards: deduct the page paddings from the whole width of the viewport, and once you’ve divided that available width for the cards to as many cards as you want displayed for that specific screen width, you also remove 16px for the gaps between the components.
IF(systemVars.dimensions.viewport.width>1500, (systemVars.dimensions.viewport.width-48)/4-16, IF(systemVars.dimensions.viewport.width>1000, (systemVars.dimensions.viewport.width-48)/3-16, IF(systemVars.dimensions.viewport.width>700, (systemVars.dimensions.viewport.width-48)/2-16, systemVars.dimensions.viewport.width-48-16)))
(Note that the formula for the smallest viewport width will have to be adjusted if you have navigation menu enabled!)
Optional: Tips for keeping content from overflowing
All the containers above are set by default to hide overflowing content, and that is as should be. However, if you have a text or multiple texts that may be of varying lengths, you might want to make sure that it is cut off early before it pushes the other content out of the container, which leaves them out of sight.
To prevent texts from taking too much space, you could use the TRUNCATE formula after a certain amount of characters, but you never know how many rows that may or may not be. Instead, I recommend using the Number of lines property of the text. Here I’ve set one of the content texts to have a maximum of 3 lines.
I’ve also set the top-most text in a Container with a custom height and width so that it will grow to fill the space that is available and the rest of the content is always aligned at the bottom of the Card container.
There you have it, a responsive grid with no weird alignments for the last item and with different amount of items for different screen widths. Let me know in the comments if you have any questions or remarks 🙂
For more blog posts on relevant topics, check out the SAP Builders Group!