Introducing GSS: Grid Style Sheets

Rafay Saeed Ansari
Rafay Saeed Ansari
Share

You may have recently heard of Grid Style Sheets (GSS) in the world of HTML and CSS. GSS re-imagines CSS layout and replaces the browser’s layout engine with one that harnesses the Cassowary Constraint Solver. Those of you who didn’t understand a word of that…hello, and welcome!

GSS promises a better future. GSS promises relative positioning and sizing. GSS promises to center any element inside another with one line of code. And GSS delivers. The question is: How?

In this article, I’ll cover a brief history of GSS and an in-depth overview of the features it has to offer. I’ll also look at GSS for constraint-based layouts, the Cassowary constraint algorithm, and walk you through the process of installing and using GSS.

Those of you who’d rather not wait around for the W3C or browsers to catch up, I urge you to hang in there and pay close attention while I explain the mystery that is GSS. On that note, let’s start with a little history.

A Brief History

GSS is a creation of The Grid with Dan Tocchini as its founder and CEO. This answers why the not-so-grid-based style sheets are called Grid Style Sheets.

The war between web developers and front-end technology to present ideas onto the web has been going on for years. CSS has proved to be triumphant for the past decade. However, building increasingly complex user interfaces with tools that haven’t evolved with time is something web developers are expected to do on a regular basis. For example, vertically centering an element with CSS has not been the simplest of tasks, especially with variable-height elements.

Flexbox is one of the most recent solutions, but even small changes there require you to go deep within your HTML content and CSS presentation and make changes.

It’s time for GSS to take the arena. GSS tackles these problems and many more — problems that developers have had for over a decade.

Essentially, GSS is a CSS preprocessor and JavaScript runtime that exploits Cassowary.js. Those of you who don’t already know, Cassowary.js is the JavaScript port Apple uses in Cocoa Autolayout.

Both GSS and Cassowary are founded on constraint programming, making it ideal for empowering declarative languages like CSS. Constraint programming is a paradigm by which web developers are concerned with declaring the “what” and leaving the “how” up to a mathematical solver.

Constraint programming focuses on intentions, not implementation.

Now that we’ve established some background information, let’s move on to the features GSS offers.

Overview of GSS

One of the biggest problems with CSS is relativity. You can expect any CSS element to have an unending list of properties — padding, height, width, float, margins, borders, outlines — but none of this information tells us where the element will be located with reference to other elements on the page (or even the page as a whole). The endless list also doesn’t answer where the element will be displayed with different screen sizes.

This brings us to the first Feature of GSS: You define what you want the layout to be. Gone are the days of spending countless hours of trial-and-error, strategizing how the layout should be constructed.

Since we already discussed that GSS utilizes Cassowary.js, here is another great feature of GSS: An element can be centered within any other with one line of code. This makes a lot of workarounds unnecessary and things of the past.

For instance, if you want to add a Subscribe button in line vertically with, say, a heading on the right side of your site’s page, you would use the following code:

.subscribe-button[right] == ::window[width];
.subscribe-button[center-y] == .header[center-y];

Another feature: GSS makes floats, table cells, clearfix, and horizontal/vertical centering obsolete. Bid farewell to the perilous pitfall that is a float because we’ve got the W3C itself saying that floats are not ideal for application layouts.

“As websites evolved from simple documents into complex, interactive applications, tools for document layout, e.g. floats, were not necessarily well suited for application layout.”
W3C Grid Layout Module (working draft)

What about CSS features like !important? The fourth feature of GSS does something similar: GSS employs constraint hierarchy to prioritize constraints with strengths. We’re talking about four built-in strength levels here:

  • !weak
  • !medium
  • !strong
  • !require

Note that !require is a special strength that ensures that the constraint will hold and if it doesn’t then everything breaks. It is advisable to use it carefully and infrequently.

The level of strength increases down the list and stronger constraints are given higher priority during execution. Let’s look at an example:

#light[years] == 50 !weak;
#light[years] == 20 !medium;
#light[years] == 35 !strong;

/* #light[years] will hold the value 35 */

You’ve made it this far, let’s look at some constraint-based layouts now.

GSS for Constraint-Based Layouts

Constraints are basically relationships between two or more variables that may or may not hold. All numeric properties of elements qualify to be constrained. Here’s an example:

p[line-height] >= 10;
p[line-height] <= ::window[height] / 20;
  • p is called a selector
  • line-height is the property that GSS will compute a value for
  • [] is used to access the property
  • <= and >= define inequality constraints
  • 10 and 20 are numerical values in pixels

In the example given above, both constraints hold valid. Here’s an example of constraints which do not hold.

#elementa[height] == 150;
#elementb[height] == 150;
#elementa[height] + #elementb[height] == 225;

Initially, both elements elementa and elementb are constrained to have a height of 150px. In the third line, the sum of the two elements is 225px. Therefore, one of the two element’s constraint’s will not hold.

Selectors in GSS

Selectors in GSS are queries over a group of HTML elements and they are used to determine the elements that will ultimately be affected by the constraint. Selectors are important because you have to select and observe elements from the DOM before you apply constraints to them.

The following fundamental selectors are supported by GSS.

#elementID[height] == 150;   /* id      */
div[height] == 150;         /* element */
.className[height] == 150; /* class   */

Rulesets in GSS

Rulesets will let you define multiple constraints over a single selector. You can nest them and use CSS properties in them too.

This nested ruleset:

section < article {
  .aclass {
    height: == 150;
  }
}

Is the same as:

(section < article .aclass)[height] == 150;

Properties in GSS

I’ve already covered properties in the examples above but let’s look at them a little more closely. In GSS, properties are the variables that belong to an element. When we use properties that are known by CSS, their corresponding GSS-calculated value is assigned as inline styles on the element.

Something like this:

.container {
  height: == #elm[height];
}

Would be equal to:

.container {
  &[height] == #elm[height];
}

An Introduction to the Cassowary Constraint Algorithm

GSS employs a JavaScript port (Cassowary.js) of the Cassowary Linear Arithmetic Constraint Solving Algorithm by Badros, Borning and Stuckey, 1999. The algorithm finds optimal solutions for layouts based on input constraints given in natural language by the user.

The user is not required to ensure that the input constraints do not contradict with one another. In fact, this is the essence of the Cassowary algorithm; it incrementally evaluates the constraints and discovers an optimal solution automatically.

Computational Limitations of the Cassowary Algorithm

The constraints solver behind GSS is called the Cassowary algorithm. This algorithm can only compute constraints that are linear (i.e. of the form y = mx + c). The basic operators ( +, -, *, /) are supported by the algorithm. Multiplication and division of two (or more) constrained variables is not linear and will, therefore, throw an error.

/* this expression is not linear */
#elementa[height] * #elementb[width] == newElement;

Installing GSS

For client-side installation, install via Bower:

$ bower install gss

Then add this code to your markup’s <head> section:

<script src="/bower_components/gss/dist/gss.js"></script>
<script type="text/javascript">
  window.engine = new GSS(document);
</script>

You can also download version 2.0.0 via GitHub as a zip file.

Once you’ve installed GSS, load your .gss stylesheets by adding type=text/gss on a <link> tag:

<link rel="stylesheet/gss" type="text/gss" href="my-first-gss-styles.gss"></link>

Or using a <style> element:

<style type="text/gss">

  /* GSS code ... */

</style>

Once you have everything up and running, you can start following along with some code examples. Below I’ll go over a beginner’s tutorial.

A GSS Beginner’s Tutorial

The examples I’ll be creating will be displayed via CodePen but I’ll go through the tutorial like a standard HTML document. First I’ll add the following line of code to my HTML to add the GSS engine script:

<!-- GSS engine script -->
<script src="gss.js"></script>

I’ll be using a CodePen-hosted version of the file, but you can find a CDN-hosted version here. Next I’ll add the following code under the GSS reference script (the line I just added above) to pass GSS the document object.

<!-- Giving GSS the document object -->
<script type="text/javascript">
  window.engine = new GSS(document);
</script>

If you prefer, this could be placed in a separate JavaScript file that gets included after the engine script.

Example 1: Vertically Centering an Element

I’ll create a div and enclose some text in h2 tags in the GSS layout and add this to the HTML:

<div class="foo">
  <h2>When in doubt, use GSS.</h2>
</div>

After adding some basic styling, I can get into adding some GSS to create the layout. This is where the fun starts.

My goal is to vertically center the .foo element inside the viewport, despite its size, and be able to keep the same alignment in place even if the size of the element changes.

Here are the constraints that I will apply to achieve this goal:

  • Use the ::window selector to center the element with the visible part of the page in the browser.
  • Use ::[intrinsic-height] attribute to get a relative value of the height of the element which will be used to determine the relative width.

First, I’ll add a <style> block to the HTML with the type attribute set to text/gss:

<style type="text/gss">
</style>

A <style> block is necessary to define the GSS I’m going to add. I’m going to position the element in the center of the screen by adding the following code inside the <style> tags:

<style type="text/gss">
  .foo {
    center: == ::window[center];
    height: == ::[intrinsic-height];
    width: == height / 2;
  }
</style>

And that’s all that’s needed. The element is now centered (with dynamic height) vertically using GSS. Below is the demo:

See the Pen Vertical Centering with GSS by SitePoint (@SitePoint) on CodePen.

Try the full screen demo and try resizing the browser vertically to see the element stay centered at any window size.

Example 2: Element Rotation Based on Dynamically Changing Window Width

For this next example, I’ll create a simple colored square shape and have it rotate dynamically. First let’s boot GSS by adding the following lines of code in the <head> section of the document:

<script>
  GSS_CONFIG = {
    worker: "/path/worker.js",
    useWorker: false,
    fractionalPixels: false
  }
</script>
<script src="/path/gss.js"></script>

Note that you would have to edit the code above to point to the correct location for the files. You can get the worker.js file here, and the gss.js file here.

Note: Due to some bugs, the above file paths point to pre-2.0.0 versions of GSS to get this to work.

Now let’s create the square shape by adding this to the HTML:

<div class="square"></div>

…and add some styling to it in the CSS:

.square {
  background: rgb(255, 0, 0);
}

Now I’ll go back to the HTML and add some GSS constraints.

Keep in mind that with GSS, you simply make an intention and leave the mathematical computation up to the algorithm. In this example, I’m trying to create a constraint between the element and the window by which a rotation is produced in the element when the width of the window changes dynamically.

Here are the constraints that I will apply to achieve this goal:

  • Use the ::window[center] selector to center the element inisde the visible part of the page in the browser.
  • Use ::window[width] to create a constraint with rotate-z, which will create the rotational effect on the element around its z-axis. Here, the value received from ::window[width] represents the degree of rotation.

I’ll add a style block to the HTML with a type set to text/gss, like I did in the first example. Remember that a style block is necessary to define the GSS I’m going to add.

<style type="text/gss">
</style>

I’m going to associate the square box with the screen using GSS constrains by adding the following code inside the style tags:

<style type="text/gss">
  .square {
    center: == ::window[center];
    rotate-z: == ::window[width];
    size: == 175;
  }
</style>

And with that, it’s done. Check out the final CodePen demo:

See the Pen Dynamic Rotation using GSS by SitePoint (@SitePoint) on CodePen.

If you view the full screen demo, try resizing the window. You’ll notice that the square box will change its rotation position when the width of the window is altered.

The Future of GSS

The future of GSS looks promising. It’s time we moved forward with front-end technology. I suggest that you practice on smaller scale prototypes before you rip apart your entire stylesheet library.

What I’ve covered here is only a small sample of what you can do with GSS, but I hope that you found this tutorial helpful and informative to get you started.

Have you used GSS yet? How was your experience? Let me know in the comments section.

Frequently Asked Questions about GSS (Grid Style Sheets)

What is GSS (Grid Style Sheets)?

GSS, or Grid Style Sheets, is a powerful tool for web developers and designers. It is a constraint-based layout engine that allows you to create responsive and flexible layouts using a simple and intuitive syntax. GSS extends the traditional CSS model by introducing the concept of constraints, which allows you to define relationships between elements and control their behavior in a more precise and flexible way.

How does GSS differ from traditional CSS?

Traditional CSS uses a box model for layout, which can be limiting and complex when creating complex layouts. GSS, on the other hand, uses a constraint-based model, which allows for more flexibility and precision. With GSS, you can define relationships between elements and control their behavior in a more intuitive way.

How can I start using GSS?

To start using GSS, you need to include the GSS engine in your project. This can be done by downloading the GSS library from the official website or by using a package manager like npm. Once the GSS engine is included in your project, you can start writing GSS code in your CSS files.

Can I use GSS with my existing CSS code?

Yes, GSS is designed to work alongside traditional CSS. This means you can gradually introduce GSS into your projects without having to rewrite your existing CSS code. GSS code can be written in separate files or mixed with regular CSS code.

What are the benefits of using GSS?

GSS offers several benefits over traditional CSS. It allows for more precise control over layout, making it easier to create complex and responsive designs. GSS also simplifies the code, making it easier to read and maintain. Additionally, GSS supports live editing, which means you can see changes in real-time as you code.

Is GSS supported by all browsers?

GSS uses JavaScript to implement its constraint-based layout engine, which means it should work in any modern browser that supports JavaScript. However, as with any new technology, it’s always a good idea to test your designs in multiple browsers to ensure compatibility.

Are there any resources available to learn GSS?

Yes, there are several resources available to learn GSS. The official GSS website provides a comprehensive guide and documentation. There are also several online tutorials and courses available that cover GSS in depth.

Can GSS be used for mobile web development?

Yes, GSS is an excellent tool for mobile web development. Its constraint-based layout engine allows for responsive designs that adapt to different screen sizes and orientations. This makes it easier to create a consistent user experience across different devices.

Is GSS open source?

Yes, GSS is an open-source project. This means that anyone can contribute to its development and use it for free in their projects. The source code for GSS is available on GitHub.

What is the future of GSS?

As a relatively new technology, GSS is still evolving. However, its powerful features and the growing interest in constraint-based layout suggest that it has a promising future. As more developers adopt GSS, we can expect to see more resources, tools, and community support for this innovative technology.