Using CSS Grid Layout and Blend 5 to Build a Game

Share this article

I’d like to share with you a mysterious internal secret kept within Microsoft for a long time. It’s the real story behind the concept of the CSS Grid Layout imagined by Microsoft for IE10 and Windows Store Apps. Most of you probably think that this specification was designed to give developers a better layout engine for their websites and applications. But the original motivation was completely different. The very first aim was to be able to create a Tetris-like game in an easy way! I’m sure you’re not convinced yet. That’s why I’m going to prove it to you using Blend 5 as a companion. Ok, let’s go! Pre-requisites: to follow this tutorial, you need first to:

  1. Download/buy & install Windows 8 RTM on your machine: https://msdn.microsoft.com/en-US/windows/apps/br229516.aspx
  2. Download & install the free edition of Visual Studio 2012 Express RTM for Windows 8: https://msdn.microsoft.com/en-US/windows/apps/br229516.aspx that includes Expression Blend 5 for Visual Studio or use the higher versions.

Step 1: discover the secret behind the CSS Grid Layout thanks to Blend 5

Launch Expression Blend 5 and create a new HTML (Windows Store) project of type Blank App. Name it “TheRealCSSGridStory”: image Replace:
<p>Content goes here</p>
With:
<div class="mainGrid">
</div>
Let’s create a grid containing 10 columns and 20 lines, whatever the screen’s resolution, by using fraction units. For that, add this CSS rule:
.mainGrid {
    display: -ms-grid;
    width: 100%;
    height: 100%;
    -ms-grid-columns: (1fr)[10];
    -ms-grid-rows: (1fr)[20];
}
Select in the Live DOM the <div> mainGrid element and you should obtain this: image Let’s draw a shape inside this beautiful grid. Add this block of HTML inside the main grid:
<div class="shape1">
</div>
And insert this CSS associated with it:
.shape1 {
    -ms-grid-column: 4;
    -ms-grid-row: 3;
    -ms-grid-column-span: 3;
    -ms-grid-row-span: 2;
    background-color: red;
}
You should now see that in Blend 5: image Cool, but nothing yet looks like to a Tetris gaming piece. Let’s work on that. Add these two DIVs inside the shape1:
<div class="line1shape1"></div>
<div class="line2shape1"></div>
and replace the previous .shape1 rule with this block of CSS:
.shape1 {
    -ms-grid-column: 4;
    -ms-grid-row: 3;
    -ms-grid-column-span: 3;
    -ms-grid-row-span: 2;
    display: -ms-grid;
    -ms-grid-columns: 1fr 1fr 1fr;
    -ms-grid-rows: 1fr 1fr;
    width: 100%;
    height: 100%;
}
.line1shape1 {
    -ms-grid-column-span: 2;
    background-color: red;

}

.line2shape1 {
    -ms-grid-column: 2;
    -ms-grid-row: 2;
    -ms-grid-column-span: 2;
    background-color: red;
}
The shape1 is currently spanning on three columns and two rows. I’ll then create a new grid inside this area defined by three columns and two rows in order to have cells having exactly the same size as the cells of the main grid, whatever the resolution might be. Once done, I’ll create two lines in order to mimic the Z shape of the Tetris game. You should now have this result: z-shape in Tetris Even better, play with the various views available in the Device tab and you’ll see that our game is already implementing a responsive design! This is freaking cool, isn’t it? Here, for instance, is the outputs for the snapped view and the portrait view: z-shape in landscape view Let’s now resolve another problem. The Tetris grid gaming grid is composed of squares. Our current responsive design is stretching 100% width. Building a Windows 8 application for the Windows Store will most of the time meet widescreen monitors (current tablets are 1366×768 or 1920×1080 and most desktop PC have a 16/9 ratio). Let’s then assume that targeting a widescreen ratio is addressing almost all cases. To compute the proper responsive width, you need to do: 9/16 * 10/20 (the ratio of the main gaming grid) which equals to: 28.125%. Add this rule to target the main grid in full screen landscape mode:
@media screen and (-ms-view-state: fullscreen-landscape) {
    .mainGrid {
        width: 28.125%;
        }
}
Let’s now center the gaming grid by using… the CSS Grid Layout again! (And you should now start to believe it was truly designed for Tetris!) Switch the body element to –ms-grid made of one column and one row:
body {
    display: -ms-grid;
    -ms-grid-columns: 1fr;
    -ms-grid-rows: 1fr;
    width: 100%;
    height: 100%;
}
Now simply add this attribute to the CSS associated to the the main grid:
-ms-grid-column-align: center;
And the grid is now centered:
At this stage, you’re probably already shocked. “How could I have missed this incredible secret?” you’re wondering to yourself. Take a breath. Now that you know THE secret, let’s continue this tutorial together to discover other awesome possibilities delivered by the CSS specifications combined together.

Step 2: moving or rotating a shape

My first idea was to try avoiding JS by using as much CSS as possible. I then first tried to use CSS3 Animations to move and animate the shape on the various rows/columns. But the bad news is that you can’t change the –ms-grid-column or –ms-grid-row values via CSS3 animations. This will then be the job of some JavaScript code. I then started to think about how I will rotate the shape. CSS Transforms seemed to be perfectly adapted for that. Let’s check that by doing some experiments. Blend 5 is really cool for that as you can directly see live the outcome of your changes. Add a rotation of 90 degrees on shape1 by adding this class to its DIV element:
.shape1rotated {
    transform: rotate(90deg);
}
I’m sure you weren’t expecting this: Rotated shape Problem: it’s not properly aligned to the gaming grid. To align our shape to the grid, we need some small adjustments:
.shape1rotated {
    transform-origin: 33% 50%;
    transform: rotate(90deg) translateX(-33%);
}
And we now have the same rotation as a Tetris-like game. Here are two screenshots before/after the rotation: z-shape before rotation z-shape after rotation We can even go further than that by using a transition set on shape1 via this:
transition: all 1s ease-out;
And now, removing/adding the .shape1rotated class on the shape1 DIV will trigger a smooth rotation animation. Check out the result inside Blend 5 thanks to this short video:

Download Video: MP4, WebM, HTML5 Video Player by VideoJS

At this stage, we could think that this approach is the good one to build our game. But this is unfortunately not yet the case. Here’s why. Try moving the shape by simply changing its –ms-grid-column property. Blend 5 will reflect the changes directly. When not rotated, the shape can be moved up to the 8th column: z-shape moved to the 8th column So far so good. But when you’re rotating it by adding the .shape1rotated class to the DIV: z-shape rotated to the 8th column You see that there is still 1 row available on the right for the shape’s move. If you think we simply need to move it to the 9th row, you’re wrong! Indeed, here is what we’ll obtain on the 9th row: z-shape gets compressed when moved to the 9th row You probably forgot that we’re currently moving a DIV element displaying a grid layout of three columns and two rows matching exactly the underlying gaming grid. When moving it, we really have the feeling that this is a block part of the main grid we’re moving. But for this trick to work, we need at least three columns available to contain our shape element. If it’s contained in two columns (when set to the 9th column) or less, it will be “compressed”, as in the screenshot. There are two ways to resolve that. 1 – Stop using CSS Transforms and draw the rotated shape using another grid definition. For instance, using three divs inside the shape instead of two. But using such an approach will prevent us having the nice CSS Animations in place. 2 – Redefined the main grid to work on 12 columns instead of 10 and we’ll use only the columns from 2 to 11 (a sort of clipping area if you wish). This will resolve our “overflow” problem. Let’s implement the second solution. Redefine the main grid using this:
.mainGrid {
    display: -ms-grid;
    -ms-grid-columns: (1fr)[12];
    -ms-grid-rows: (1fr)[20];
    -ms-grid-column-align: center;    
    width: 100%;
    height: 100%;
}
To also have the proper ratio, you need to update the associated media query:
@media screen and (-ms-view-state: fullscreen-landscape) {
    .mainGrid {
        width: 33.75%;
        }
}
33.75% = 9/16 *12/20 Let’s also add a “virtual grid” to delimitate the space where we will be able to move the shapes.  Inside the main grid DIV, insert this one:
<div class="virtualGrid">
</div>
Associated with this block of CSS:
.virtualGrid {
    -ms-grid-column: 2;
    -ms-grid-column-span: 10;
    -ms-grid-row-span: 20;
    border-right-style: dashed;
    border-left-style: dashed;
    background-color: #505A5A;
}
It will help to delimit the gaming area with a grey background and some dashed border lines. Now, if I’m moving the Z shape on column 9, row 2, here is the result: z-shape at column 9 If I’m rotating it with CSS Transforms, I can move it correctly on column 10: Rotated z-shape moved correctly to column 9

Bonus – handling the Portrait mode:

If you’d like to support the portrait mode (which is even better for the Tetris grid game), add this CSS Media Query definition:
@media screen and (-ms-view-state: fullscreen-portrait) {
        .mainGrid {
        width: 106.66%;
        }
}
As the ratio need to be computed as = 16/9 * 12/20 = 106,66%. Tetris grid in landscape

Step 3: adding some code to handle part of the game logic

Now that we’ve solved the graphics part of the game using only some pure CSS & HTML code, we need the help of JavaScript to move/rotate the shape in the gaming area. We’re going to re-implement the CSS logic via a JS object that’s going to be defined thanks to WinJS.Class. Open the “TheRealCSSGridStory” in Visual Studio 2012. Create a TetrisShapeZ.js file in the JS directory and copy/paste this code:
(function () {
    "use strict";

    var ShapeZ = WinJS.Class.define(
    /// Constructor - columnIndex is optional. If provided, defines the column the shape starts in
        function (columnIndex) {
            // We're creating the equivalent of this HTML block :
            // <div class="shape1 ">
            //     <div class="line1shape1"></div>
            //     <div class="line2shape1"></div>
            // </div>
            this._shape1 = document.createElement("div");
            var line1 = document.createElement("div");
            var line2 = document.createElement("div");
            this._shape1.className = "shape1";
            line1.className = "line1shape1";
            line2.className = "line2shape1";
            this._shape1.appendChild(line1);
            this._shape1.appendChild(line2);
            // Boolean to indicate if the shape is in its default orientation mode or not
            // True means not rotated, false means rotated
            this._defaultOrientation = true;
            // Setting the column position in the main grid
            if (columnIndex) {
                this._currentColPos = columnIndex;
                this._shape1.style.msGridColumn = this._currentColPos;
            }
            else {
                this._currentColPos = 1;
            }
            // We always start at line 1
            this._currentLinePos = 1;
            // Boolean to know if the shape can be move/rotate or not
            // If true, this means we've reached the last line possible
            this._fixed = false;
        },
        {
            /// Specify in which HTML element displayed in CSS Grid you'd like to work with
            /// width is the number of columns of the grid & height is the number of lines
            insertIntoGrid: function (element, width, height) {
                element.appendChild(this._shape1);
                this._gridWidth = width;
                this._gridHeight = height;
                // These are the left & bottom max limit for this shape
                // when displayed in default orientation mode
                this._maxLeft = width - 3;
                this._maxBottom = height - 1;
            },
            /// Rotate the Z shape 90 degrees anti/clockwise using CSS Transforms
            /// by simply removing/adding the shape1rotated class
            rotate: function () {
                if (!this._fixed && this._defaultOrientation) {
                    // rotating 90 degrees clockwise, it will trigger also the CSS Transition
                    WinJS.Utilities.addClass(this._shape1, "shape1rotated");
                    this._defaultOrientation = false;
                    // the left limit is now +1 vs the default orientation
                    this._maxLeft = this._gridWidth - 2;
                }
                else {
                    if (!this._fixed && this._currentColPos < this._maxLeft) {
                        // removing the shape1rotated will automatically reset the shape
                        // to its initial matrix and again the CSS Transition will do the 
                        // animation for you
                        WinJS.Utilities.removeClass(this._shape1, "shape1rotated");
                        this._defaultOrientation = true;
                        this._maxLeft = this._gridWidth - 3;
                    }
                }
            },
            // Internal function called by public moveLeft/moveRight
            _moveHorizontally: function (direction) {
                if (!this._fixed && (this._currentColPos < this._maxLeft || direction === -1) && 
                (this._currentColPos > 2 || direction === 1)) {
                    this._currentColPos = this._currentColPos + direction;
                    this._shape1.style.msGridColumn = this._currentColPos;
                }
            },
            /// Move the shape on the immediate left column
            /// Test if you've reached the left limit or not
            moveLeft: function () {
                this._moveHorizontally(-1);
            },
            /// Move the shape on the immediate right column
            /// Test if you've reached the right limit or not
            moveRight: function () {
                this._moveHorizontally(1);
            },
            /// Move the shape down on the immediate below line
            /// Test if you've reached the bottom limit or not
            moveDown: function () {
                if (!this._fixed) {
                    this._currentLinePos = this._currentLinePos + 1;
                    this._shape1.style.msGridRow = this._currentLinePos;
                    if (this._currentLinePos === this._maxBottom) {
                        this._fixed = true;
                    }
                }
            }
        }
    );

    WinJS.Namespace.define("CSSTetris", { ShapeZ: ShapeZ });
} ());
Simply read the code to understand what it’s doing. It should be commented enough to be self-explicit. Add a reference to this script file in default.html and keep only this block of HTML inside the body:
<div class="mainGrid">
    <div class="virtualGrid">
    </div>
</div>
Jump into default.js. The cool part of having well-documented code is that we now have interesting IntelliSense details like for the constructor: Intellisense for ShapeZ(columnIndex) constructor or the rotate function: Intellisense for the rotate function To properly use this code, add this block of JS just after processAll call:
document.addEventListener("keydown", OnKeyDown, false);
mainGrid = document.getElementsByClassName("mainGrid")[0];
myShape = new CSSTetris.ShapeZ(4);
myShape.insertIntoGrid(mainGrid, 12, 20);
init();
And add these two functions:
function init() {
    setInterval(function () {
        myShape.moveDown();
    }, 1000);
}

function OnKeyDown(event) {
    switch (event.keyCode) {
        case KEYCODE_X:
            myShape.rotate();
            break;
        case KEYCODE_LEFT:
            myShape.moveLeft();
            break;
        case KEYCODE_RIGHT:
            myShape.moveRight();
            break;
        case KEYCODE_DOWN:
            myShape.moveDown();
            break;
    }
}
And we’re done! We now have a very basic game using CSS Grid Layout coupled with CSS Transforms & Animations for the graphics part and a couple of JS lines of code to have the beginning of the basics of a Tetris-like game. Here is a short video demonstrating the final result:

Download Video: MP4, WebM, HTML5 Video Player by VideoJS

You can download the final Visual Studio solution corresponding to the three steps of this tutorial here: https://david.blob.core.windows.net/win8/TheRealCSSGridStory.zip So, are you now convinced that CSS Grid Layout was made to simplify the creation of Tetris-like games?

This article is part of the HTML5 tech series from the Internet Explorer team. Try-out the concepts in this article with 3 months of free BrowserStack cross-browser testing @ https://modern.IE.
This article originally appeared on David Rousset’s MSDN blog, Coding4Fun on 12 Feb 2013.

Frequently Asked Questions (FAQs) about CSS Grid Layout and Blend 5 Game Development

How can I start learning CSS Grid Layout for game development?

Starting with CSS Grid Layout for game development requires a basic understanding of HTML and CSS. Once you have that, you can start learning about the CSS Grid Layout, which is a two-dimensional grid-based layout system designed for responsive web design. You can learn it through various online tutorials, books, and coding games like the one discussed in our article. These games provide a fun and interactive way to learn and practice CSS Grid Layout.

What is Blend 5 and how is it used in game development?

Blend 5 is a powerful design tool for building interactive and animated web content. It provides a visual interface for designing and prototyping user interfaces, making it easier to create complex layouts and animations. In game development, Blend 5 can be used to design the game interface, create animations, and manage game assets.

How can I use CSS Grid Layout and Blend 5 together in game development?

CSS Grid Layout and Blend 5 can be used together to create a responsive and interactive game interface. You can use CSS Grid Layout to create the game layout and use Blend 5 to design the game elements and animations. The combination of these two tools allows you to create a game that is visually appealing and responsive to different screen sizes.

What are some challenges I might face when using CSS Grid Layout for game development?

Some challenges you might face when using CSS Grid Layout for game development include understanding the grid concepts, managing complex layouts, and ensuring the game is responsive on different screen sizes. However, with practice and the right resources, these challenges can be overcome.

Are there any resources available to help me learn CSS Grid Layout and Blend 5 for game development?

Yes, there are many resources available to help you learn CSS Grid Layout and Blend 5 for game development. These include online tutorials, books, coding games, and community forums. Our article provides a detailed guide on using CSS Grid Layout and Blend 5 for game development, which can be a great starting point.

Can I use other design tools in combination with CSS Grid Layout for game development?

Yes, you can use other design tools in combination with CSS Grid Layout for game development. However, the choice of tools depends on your specific needs and the complexity of the game you are developing.

How can I ensure my game is responsive on different screen sizes using CSS Grid Layout?

CSS Grid Layout is designed for responsive web design, which means it automatically adjusts the layout based on the screen size. You can use the ‘fr’ unit to define flexible grid tracks and the ‘auto’ keyword to automatically size grid items.

What are some best practices for using CSS Grid Layout in game development?

Some best practices for using CSS Grid Layout in game development include planning your grid layout in advance, using the ‘fr’ unit for flexible grid tracks, and using the ‘auto’ keyword for automatic grid item sizing. It’s also important to test your game on different screen sizes to ensure it’s responsive.

Can I use CSS Grid Layout for 3D game development?

CSS Grid Layout is a two-dimensional layout system, which means it’s not designed for 3D game development. However, you can use it to create the game interface for a 3D game.

How can I debug issues in my game developed using CSS Grid Layout and Blend 5?

Debugging issues in your game can be done using the developer tools in your web browser. These tools allow you to inspect the CSS and HTML code, view the grid layout, and debug any issues. For issues related to Blend 5, you can use the debugging tools provided in the software.

David RoussetDavid Rousset
View Author

David Rousset is a Senior Program Manager at Microsoft, in charge of driving adoption of HTML5 standards. He has been a speaker at several famous web conferences such as Paris Web, CodeMotion, ReasonsTo or jQuery UK. He’s the co-author of the WebGL Babylon.js open-source engine. Read his blog on MSDN or follow him on Twitter.

HTML5 Dev Center
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week