Layout on the web is certainly an extremely time consuming process and the most outdated. Floats and such still don’t cut it.
At it’s core, Grid Style Sheets (GSS) reimagines CSS layout and harnesses the Cassowary Constraint Solver – the same algorithm Apple uses to compute native layout. OK sounds good, but is it a pre-processor? Well… no not exactly.
GSS enables far better layout control through building relational rules between different elements.
Let’s take CSS and bend it to our will as we look into the layout capabilities of the GSS project.
Test Drive GSS on GitHub
The example above can be downloaded on GitHub in order to test locally. You can also follow along with the similar example used in this video by GSS partner in crime Dan Tocchini.
Please be aware the version I’ve posted on GitHub alleviates the Flash Of Unstyled Content (FOUC) through the use of JavaScript detection and a CSS opacity transition via the ready state class provided by GSS. This ensures content is still visible should JavaScript fail.
The Purpose of GSS
Ever tried to center something in CSS? The plethora of techniques and methods are astounding! Current centering methods in CSS use approaches such as flexbox, table display, inline-block, transforms, absolute positioning…the list goes on and on when all we want to do is center something!
I’m also sure you’ve all heard of element queries, but why are they so difficult to obtain right now? The answer is cyclic dependencies that naturally arise in relative layout logic and arithmetic. That means if we have 3 boxes and each box depends on the width of the previous one we end up in a never ending loop. For example…
box1[width] === box2[width] === box3[width]
This is the reason we still have media queries that only respond to the screen size. The great thing about the Cassowary layout algorithm is the fact that it can actually resolve these cyclic dependencies that naturally occur even if you try to avoid them intentionally. Cassowary can also remove the need for a deep understanding of parent/child relationships among DOM nodes. This means true source order independence plus the ability to detect the relation of one element to another in a particular layout.
How to Install GSS
Lets start by installing GSS to your project. You can also hop over to the GSS docs and read a bit more if you’d like. If you have bower you can simply use the command:
$ bower install gss
If you don’t use Bower you can also find it for Grunt as well as an npm package, but it’s suggested to just use Bower and call it a day.
Now that we have GSS installed we can insert the appropriate call for our files like so…
<script>
GSS_CONFIG = {
worker: "path/to/gss/worker.js"
}
</script>
<script src="path/to/gss/dist/gss.js"></script>
GSS stylesheets can be loaded by adding a different type
attribute to the link
tag like so…
<link rel="stylesheet" href="my-gss-styles.gss" type="text/gss">
The Belly of GSS
Since GSS is independent of DOM structure we need to make it aware of every bit of information concerning constraints and proportions. Essentially, GSS needs to understand the properties of elements like width and height. Think of GSS as another world where everything that exists must be taught it’s “spacial relationship” to it’s encompassing environment.
Currently all numbers are treated as pixels with the exception of properties like z-index
. Pseudo selectors such as ::window
, ::parent
, ::this
, and ::left
are also available.
Properties
x or left
y or top
right
bottom
center-x
center-y
GSS also has different strengths that can be added to constraints. The following strengths for weakest to strongest are listed in order starting from the top.
Strengths
!weak
!medium
!require
!strong
If you’d like to dive deeper into the docs and learn the syntax feel free to click here. The idea is that the syntax should visually depict the layout for example…
@horizontal |-[#button1]-[#button2]-[#button3]-[#button4]-| in(#panel) gap(10);
Hopefully reading the Visual Format Language (VFL) syntax above you walk away understanding the buttons are placed in a row horizontally within a container called #panel
and possess a gap of 10px in-between each adjacent button.
Parting Thoughts
GSS is a wonderful start to a project granting authors the power to bend layout at will compared to what’s possible with our current state of CSS. On the other hand constraint-based layouts aren’t a silver bullet as it takes practice & thinking more like a programmer.
The heavy reliance on JavaScript contributes to my slight discomfort with GSS in general as I would rather see this done with CSS where it belongs. Since GSS requires a bit of JavaScript that means when JavaScript is turned off or fails during transmission then the entire layout goes with it. You’ll have to ask yourself how you feel about something like that since the layout is not crucial to accessible content. If JavaScript is turned off your content doesn’t vanish -it just turns into naked HTML… still accessible right? What about progressive enhancement techniques?
There will still be cases where screen size matters. Constraint based layout systems (i.e. element queries and such) are only part of the solution. Don’t go throwing your @media
queries out the window just yet boys and girls. Situations like orientation still require screen size detection as element queries aren’t suitable for the context.
Will GSS have a place in your heart and toolbox for those times when you need more than what CSS can give? I guess only time will tell. Got something to mention or say about GSS or CSS layout in general? Let us know in the comments!
Might as well try it, since css has been a great disappointment, this reminds me of a funny tweet i read a while ago it says “We were able to put a man on a comit, but still can’t properly align objects with CSS”, its absolutely true.
Thanks for the great post, i’ll give it a try.
Thanks Paul! If you come up with a cool use case using GSS please send it up to the repo for archiving in order to showcase this project more to the community. GSS might not be the ultimate solution, but it’s sure nice to have it in the toolbox when CSS is failing.
Good approach, I feel this can be helpful for special cases. Nevertheless, I prefer the traditional way of CSS, it brings a clean output and inline styling out of the screen.
Thanks for the point Ailin. I certainly feel very close to CSS as well, but as I point out it’s nice to have something like this if the case warrants the need.
Hey Dennis! Thanks for the post, I’ve found GSS very interesting for a few years but personally I haven’t gotten much use out of it. In 2014 when I needed element queries the most, it was so slow/bloated on mobile browsers that loading a page with GSS would usually result in a crash before it finished loading/rendering.
I’m sure GSS has had improvements since then, and the speed of JavaScript has definitely increased in newer hardware, but I still required a solution that would work on the less-than-premium hardware and in less-than-perfect browsers.
I ended up creating an element query plugin called EQCSS which has a much smaller learning curve than GSS – it’s just an extension of what CSS already does, not a totally different language. Check out the documentation and examples over at http://elementqueries.com
Between declarative styling, like CSS, and constraint-based layout like GSS – I think the declarative approach is more powerful. It seems that constraints work best when you have a few items in your layout, and little content, but as mobile interfaces become increasingly complex it’s not web developers who are begging for constraint-based layout, but app developers who are begging for CSS-like styling abilities for their apps. That says something to me as a CSS guy, and says we should be experimenting and finding ways to push the limits of declarative styling languages. I hope EQCSS is the CSS-like counterpart to what GSS does in its own syntax.
Also, I noticed you’re located in Buffalo! I’ll have to take you for a coffee the next time I’m through town so we can chat more about this in person 🙂 Great post!