moscardino.net

Solving the Contain Problem

Fixing an annoying layout issue.

I’ve been toying with the idea of making LexiTiles 2 for a while now. One of the major roadblocks is that I have yet to sit down and learn Angular and Ionic (current versions of each, not 1.X). The other major issue is the layout of the game board.

LexiTiles uses a grid of 25 tiles of letters. These tiles are all squares. Version 1 uses floats to make the grid. This works well enough, but scaling to different screen sizes poses a problem. The game board cannot scroll and everything must be on screen at once. This led to a bunch of seemingly random media queries to adjust the size of the tiles (and thus the board) to make sure that the board or parts of the UI were never off screen.

Since this solution is clearly not good enough, I wanted to figure out how I could solve this before really figuring out version 2.

I called it the Contain Problem. Essentially, my idea solution would have the board behave like a CSS background image when the the background size is set to contain. The board would maintain it’s aspect ratio while always being smaller than the viewport. I tried a lot of solutions, but most CSS concepts assume that vertical scrolling is acceptable, which it is not for this situation.

This morning I had an epiphany: vmin.

vmin is a CSS unit that is related to vw and vh. Where vw is 1/100 of the viewport’s width, and vh is 1/100 of the viewport’s height, vmin is 1/100 of the whichever is smaller: the viewport’s width or height. Perfect!

So I combined that with some CSS Grid and Flexbox magic to make the board styles simpler, and here it is the proof of concept:

See the Pen LexiTiles with CSS Grid by Andrew Moscardino (@amoscardino) on CodePen.

For the best demo, open that in full page view and resize your window. Notice how the board will never be too big for the window?

Note that this doesn’t work in IE or Edge since CSS Grid support isn’t fully there, yet.

I also should figure out how to make the letters size correctly. I’ll work on that next.