New in the CSS horizon: (Native) CSS Grids

New in the CSS horizon: (Native) CSS Grids

Grids like 960.gs, the Grids in Bootstrap 3 and Foundation or solutions like SUSY rely on floated elements (I make the distinction between Bootstrap 3 and 4 because in 4 you can switch your layout to Flexbox.) They work but they need exact CSS and measurements for the floats to work as intended (the fact that frameworks hide the complexities of existing grid systems doesn’t mean they are not there.)

The CSS Grid Level 1 specification is fundamentally different. When implemented grids will be baked into the browser’s CSS parser and will be treated as a first class citizen. We will only have to learn one way to do grids and content layout rather than having to choose a tool that will do multiple unnecessary calculations for us.

From the spec’s Background and Motivation section:

The capabilities of grid layout address these problems. It provides a mechanism for authors to divide available space for layout into columns and rows using a set of predictable sizing behaviors. Authors can then precisely position and size the building block elements of their application by into grid areas defined by these columns and rows. Figure 1 illustrates a basic layout which can be achieved with grid layout.

Grid or Flexbox?

If we look at examples using flexbox we’ll see that we can do a lot of the same things using Flexbox than we can with Grids. So the question becomes when would you use flexbox and when would you use grids for your layout?

The best explanation I’ve found of these differences is in anemail from Tab Atkins (editor of the Grid and Flexbox specifications) in the www-style mailing list:

Flexbox is for one-dimensional layouts—anything that needs to be laid out in a straight line (or in a broken line, which would be a single straight line if they were joined back together).

Grid is for two-dimensional layouts. It can be used as a low-powered flexbox substitute (we’re trying to make sure that a single-column/row grid acts very similar to a flexbox), but that’s not using its full power.

Flexbox is appropriate for many layouts, and a lot of “page component” elements, as most of them are fundamentally linear. Grid is appropriate for overall page layout, and for complicated page components which aren’t linear in their design.

The two can be composed arbitrarily, so once they’re both widely supported, I believe most pages will be composed of an outer grid for the overall layout, a mix of nested flexboxes and grid for the components of the page, and finally block/inline/table layout at the “leaves” of the page, where the text and content live.

CSS Grid Terminology

  • Lines: Lines make up the grid. These can be horizontal or vertical.
  • Tracks: Track is the space between two Grid Lines, either horizontal or vertical
  • Cells: Cell is the space between lines. So it is the smallest unit on our grid that is available for us to place an item into. Conceptually it is just like a table cell
  • Areas: Area is any area on the Grid bound by four grid lines. It may contain a number of Grid Cells

Browser support

According to caniuse.com support for CSS Grid is pretty sketchy as of right now but getting better.

  • Microsoft Edge and IE 11 support an older version of the specification (closer to their original submission to W3C)
  • Firefox support grids but you have to enable them in preferences by setting layout.css.grid.enabled to true in about:config
  • Chrome and Opera support grids but hide them behind the experimental Web Platform features flag in chrome://flags
  • Webkit supprt grids on their nightly builds but uses the -webkit prefix

So don’t use grids in production yet but the future is not so distant when we will have grids without floats 🙂

Working example

For this example I will attempt to create a 960px wide grid and will use it as the basis for placing content and playing with media queries to change what the grid will look like.

We will use the following HTML

<div class="wrapper">
 <div class="box box1">A</div>
 <div class="box box2">B</div>
 <div class="box box3">C</div>
 <div class="box box4">D</div>
 <div class="box box5">E</div>
 <div class="box box6">F</div>
</div>

To tell the browser that we want to use the grid layout we use a new value for the display property: display: grid. We can then create the grid using grid-template-column and grid-template-row.

The grid will have 2 10px gutter (1 from each side) and 1 40px column area we will repeat this pattern 16 times using the repeat attribute of our grid.

Although we don’t really need the grid-template-row attribute, we use it to explicitly give the rows a gutter of 10 pixels.

.wrapper {
 display: grid;
 grid-template-columns: 
   repeat(16, 10px 40px 10px);
 grid-template-rows: auto 10px auto;
}

We can then begin placing the content. It is important to realized that we have 48 column positions in each row 32 for gutters and 16 for the content cells.

Using the definition of the page’s HTML content and our CSS for the grid, we can do permutations like these:

.box6 {
  grid-column: 2/7;
  grid-row: 1/4;
}

.box1 {
  grid-column: 2/35;
  grid-row: 5 / 6;
}

.box2 {
  grid-column: 4/12;
  grid-row: 4;
}

.box3 {
  grid-column: 2/12;
  grid-row: 7/8;
}

.box4 {
  grid-column: 2 / 6;
  grid-row: 8;
}

.box5 {
  grid-column: 36/47;
  grid-row: 2/9
}

The Pen at http://codepen.io/caraya/pen/pgpeXY shows what these declarations look like in an actual page.

Things to Notice:

One of the most frustrating things is that we can’t create create implicit rows with the code we have created. In order to get rows working with this setup it appears like we have to sset up an arbitrary number of rows in our grid definition.

All elements we want to have positioned in the grid must have column and row placement definitions.

The master class from the expert

I love Rachel Andrew and the passion that she has for Grids in CSS. Her presentation from CSS Conf EU 2014 along with her book A pocket guide to CSS 3 Layout Modules 2nd edition got me interested in grids and revisiting flexbox as layout technique.

Links and resources

New in the CSS horizon

I’ve been looking at some CSS layout modules and aspects of the level 3 Fonts CSS Module and I have to admit that I’m happy, very happy. There are three areas where I’m going to concentrate this time around.

  • CSS Flexbox
  • CSS Grids
  • New functionality and their support level
  • Enhancement to font handling and new font features

I’m hoping to write more of these articles on a regular basis to keep up to speed in developments around CSS and web technologies. I’m partocularly interested in Flexbox because it is used by Polymer as the primary way to layout content.

In Flex boxes and the holy grail I made a first attempt at using a flex layout. It sorta worked… I was able to get the layout to work but the main content would never fit the height of the menu and sidebar. In the new example of flex holy grail it works.

If you want more information and examples of Flexbox and Grid Layouts I definitely recommend Rachel Andrew’s CSS3 Layout Modules as a good guide to work alongside.

Better Markdown from Node

Unless I write an email in Gmail I do all my writing using Markdown a quick text-based writing system. I love Markdwon but have always been upset at the limitations placed in the original Markdown, the fact that there is no actual specification for Markdown and that Markdown’s creator has been a douche when it comes to supporting the community effort of rectifying some of the shortcomings of the original Markdown tool (leading to the CommonMark effort).

I currently use Ulysses for MacOS/iOS as my primary writing tool and then copy and paste to a Markdown enabled instance of WordPress using Jetpack. The one thing I’ve only been partially successful in doing is to convert the Markdown directly into HTML and uset it as is.

The best I’ve been able to do is convert the Markdown file to (badly formatted) HTML and insert it into a template… for some reason the converter keeps thinking that bulledted lists should be formated with paragraphs (as in <li><p>) and that creates issues with dropcaps in list items. I have to manually clean the documents after conversion and I’m pretty sure I can do better than that.

The idea

If I’m publishing the content to WordPress I don’t need to do anything further. The Markdown code is good enough to publish with only minor alterations (WordPress has some issues with the way it renders Markdown and you need to preview your content before you publish).

There are times when I want to publish content to the web without having to worry about manually generating the HTML. In order to get the page ready we’ll do the following:

  1. generate the HTML from Markdown
  2. Insert the generated HTML into an existing HTML template
  3. Visually inspect the page and the underlying HTML
  4. Clean up the resulting page based on inspection

The tools

I’ve plugged the Markdown process to my CSS Starter Kit. SO the template is linked to the CSS generated for the starter kit and also to Prism syntax highlighter.

The Markdown section uses the following tools

  • Remarkable Markdown Gulp plugin
    • gulp-remarkable
  • Wrapper to insert HTML into a template
    • gulp-wrap

Gulp build file

I’ve added two tasks to work with Markdow. The first task will generate HTML from all the files under src/md-content that ends with an md extension and place them in the src/html-content directory.

Note that this task will only convert to HTML the content of the Markdown file. It will not add head or body elements. That will come in the next task.

gulp.task('markdown', () => {
  return gulp.src('src/md-content/*.md')
    .pipe(markdown({
      preset: 'commonmark',
      typographer: true,
      remarkableOptions: {
        typographer: true,
        linkify: true,
        breaks: false
      }
    }))
    .pipe(gulp.dest('src/html-content/'));
});

The second time will build the full HTML files. It will take each of the HTML fragments we created with the Markdown task, insert them into a template and save them to the root of our src directory with the name of the fragment as the name of the HTML file.

gulp.task('build-template', ['markdown'], function() {
  gulp.src('./src/html-content/*.html')
    .pipe($.wrap({src: './src/templates/template.html'}))
    .pipe(gulp.dest('./src/'))
});    

We make the task dependent on Markdown to make sure we have the freshest HTML fragments before inserting them into the templates.

What’s next

Working with WordPress and its Markdown parser I’ve gotten used to typing in HTML code manually. Videos in the page are added as HTML with the following snippet

<div class="video">
<iframe width="560" height="315" 
src="https://www.youtube.com/embed/K1SFnrf4jZo" 
frameborder="0" allowfullscreen></iframe>
</div>

It would be nice if we can just tailor the Markdown we write to produce the same HTML without having to write it by hand.

Remarkable, the Markdown library I’m using for this project, has a rich plugin ecosystem. I’m researching how to run plugins inside the Gulp task. Once this is done I will be able to incorporate the results of the plugins into the HTML content. This may mean I’ll have to use the HTML in the blog (instead of the Markdown file directly) but I still save myself from having to code the HTML manually 🙂

Performance auditing using Chrome Dev Tools, Web Page Test and Page Speed Insight

Although Chrome Dev Tools gives us an approximation of what a connection would be like in a given device it’s not 100% accurate, it can’t be since our Macbooks and Windows devices don’t have to deal with the additional constraints that a mobile device has.

Why should we test in an actual device?

All cores in a laptop or desktop systems are symmetric as opposed to mobile devices where some of the cores are powerful and some of the cores (the ones that happen to do all of the work) are less powerful, use less power and generate less heat.

All laptops and desktops have large heat sinks over the CPU and fans (or liquid systems for some gaming rigs) to dissipate the heat. Mobile devices have no such things, that’s why we’re always concerned about burning ourselves with mobile devices.

Best explanation on how this affects performance and why we should care is Alex Russell’s presentation at the Polymer Summit

So we have unreliable hardware (we can’t tell if the right CPU cores will be ready when the user first access an application) in a flat out hostile network with high RTT that, potentially, takes a long time to actually complete.

The graphic below shows the HTTP Archive Trend for Average number of requests for Javascript resources and the average size of all responses for a single website between November, 2015 and November, 2016. HTTP Archive only deals with resources as they are transferred through the wire.

JS Transfer Size and Average # of Requests from HTTP Archive

JS Transfer Size and Average # of Requests from HTTP Archive

If we accept that the default Dev Tools emulation in Chrome Desktop is not a faithful representation of how a site will load in a mobile device. We can create custom profiles and adjust the latency for each of our connections we cannot account for the unpredictability of mobile networks.

In the rest of the post we’ll look at 3 tools that will allow us to get a better read on how our application is performing:

  • Chrome Remote Debugging
  • Page Speed Test to run your app closer to where your users are
  • Page Speed Insight to get feedback and metrics on your app performance

Using Chrome Remote Debugging

If you use Android, you can plug your device and run your app on the device to trace your app’s performance in an actual mobile device using your desktop’s Dev Tools. This will eliminate some of the issues Alex discussed on the video above. Running remotely through Dev Tools using the device will use the devices cell or wifi connectivity and will fire the device’s cores as it would when working independently of the computer it’s tethered to.

Because we can’t rely on the results from simulating connection speed using desktop Chrome’s Dev Tools this will produce a much more accurate Dev Tools trace of your application. The trace can be opened in other instances of Chrome for review and further analysis.

Chrome Dev Tools Remote Debugger describes how to plug in your Android device and use your desktop Chrome Dev Tools to create traces and debug your application.

In the video below Boris Smus shows how to remote debug an application on your mobile device using Desktop Chrome.

Using WebPage Speed Test

Webpage Speed Test provides tools to test your application in the same geographical location you expect your users to be. Depending on the region you will have different browsers and devices to test with.

If using Chrome (any version) you can generate trace of the test Pagespeed test runs. These tests can be imported into other instances of Chrome or Chromium-based browser and used for collaborative debugging and performance analysis.

Using Page Speed Insight

Page Speed Insights works slightly different than WPST. It runs tests against the given website but instead of providing metrics and statistics it provides suggestions and solutions for improving the page load speed. A score of 85 or higher (out of 100) indicates that the page is performing well and, of course, the higher the score the better.

  • time to above-the-fold load: How long does it take to load the content the user sees when she first loads the site/app
  • time to full page load: How long does it take for the browser to fully render the page

Network performance is a tricky thing and can vary considerably between browsers, devices and networks. Because of this PageSpeed Insights only considers the network-independent aspects of page performance: the server configuration, the HTML structure of a page, and its use of external resources such as images, JavaScript, and CSS. The results will vary according to your network.

PWA auditing with Lighthouse

Progressive Web Applications describe a set of technologies that make web applications look and behave like native applications without sacrificing the ease of authoring and the tools we use to create our apps.

There are many things that go into making a PWA and it’s extremely hard to keep everything in mind as you’re developin and testing your content. That’s where Lighthouse comes in.

Lighthouse is a tool developed by Google’s Chrome Team to detect and measure features of PWAs, provide best practices and performance advice for your application.

Lighthouse is available as a chrome extension

and as a Node-CLI tool.

Install Lighthouse

You can find instructions for installing Lighthouse, both the Chrome Extension and the CLI in the Github Repository README file.

Conected City

This is a moon idea (in the spirit of Google’s moon projects) for a connected downtown. It uses Mountain View as an example not because it’s Google’s headquarters but because it’s my home town and I’m most familiar with how it works.

A typical day

I’ve decided to drive today… it doesn’t happen very often and I’m starting to miss the monster. The console at home is telling that the day is going to be nice, in the upper 70s and that I should prepare for a cooler night. The forecast says it’ll be 50 by 10pm tonight.

The car monitor reminds me that my oil change is past due and makes an appointment for me on Saturday morning after 10am. I park near city hall so I can still get a walk on my way to the coffee shop. As I walk past the Performing Arts Center my phone tells me that they are doing a revival of “The Book of Mormon” and that the next play will be the touring company for “Rent”. I use my phone to buy tickets for Rent, I have already seen Mormon.

As I walk past restaurants I’m flashed with menus and specials only for the kind of food I like, my phone already knows my preferences. When I walk by my optometrist’s office I’m reminded that I need to get a new pair of glasses and that I should schedule the appointment soon or I’ll have to get a new eye exam.

My favorite sushi place has a special promotion in addition to their happy hour special. I may consider coming back for dinner.

As I look at my phone more and more stores send me information about what they are offering both their specials for today and the usual ‘you should buy here and not in the huge local chains’ advertisement.

I get to the coffee shop. There’s new art today and they tell me everything about it and about the artist who created it. I get a digital gallery of the exhibit and a link to the artist’s website. I’m also notified that the nook on the second floor has been reserved for the afternoon and that there’s been a change on the music schedule for tonight. I shrug, wasn’t planning on staying anyways, as I move to order my coffee.

The explanation

The vignete above may sound very science fiction but it is much closer to reality than what you may think. Technologies like iBeacon or Google’s Physical Web offer ways to have physical spaces communicate with users and provide an online experience beyond what they already have and do online.

The whole idea relies on beacons, physical objects that you place in the space where you want to broadcast information from. Some of these beacons can be used outdoors (say by the door of your business or office) and others are designed to be used indoors (to give you department news and cupons when you visit a retailer like Target or a mall like Valley Fair or The Mall of America.)

Dreaming through the noise

Now imagine that we can create apps (web or native) that processes the data from these beacons and, based on stated preferences, gives us only those items that are relevant to us in the form of a URL list or a brief snippet of each item in a simple card based layout.

Links and Resource