Tag Archives: CSS

Emulation Accuracy in Internet Explorer

Early preview versions of Internet Explorer 11 lacked Emulation features that we saw in Internet Explorer 9 and 10. When Windows 8.1 shipped, Internet Explorer 11 was found to have the Emulation features shipped with it. These tools are helpful, though they can be misleading at times.

My general workflow in the past when using these tools goes like this: A user reports an issue in Internet Explorer x. I instruct the latest version of Internet Explorer to emulate the reported version. If I encounter the same issue, I can debug using the modern version of Internet Explorer. If emulation does not reveal the same issue, I need to load up a virtual machine, or use a service like BrowserStack.

The problem with these tools is that it’s not entirely clear where the line of reliability resides. To what degree this emulation replicates the native experience is unknown (to me, at least). Due to this, I’ve decided to do a deep dive into Emulation and see just how reliable it is, and in which areas.

Computed Styles

The first dive wasinto Computed Styles. Does Internet Explorer generate the same computed styles as IE10 and IE9 when it is emulating those versions? Surprisingly, yes. Granted, I’m running instances of IE10 and IE9 in a Virtual Machine (compliments of modern.ie), so that should be considered. Also other important thing to note is that this pass-through assumes Standards Mode.

The comparison tables are being maintained in a Google Docs spreadsheet. Click the preview below for the full view.

comparison.table

Window Object

My next focus was on cycling over enumerable properties on the window object and laying those out for comparison. A cursory glance of this next table will reveal that Internet Explorer 11 emulates the window object from IE9 and IE10 very well. Granted, there are some very clear examples of where it brought along a couple extra methods and properties.

comparison.table.window

It’s worth noting that this particular table had to be done a couple of times. Some of these members don’t attach themselves to the window object until certain actions are performed. For instance, this table is front-loaded with a bunch of BROWSERTOOLS members that are pushed onto the window object when various portions of the developer tools are opened. Other members, such as $0, don’t exist until you perform an action like selecting an element in the DOM Explorer.

More on GIFs and Painting in Internet Explorer

About a week ago I wrote a post demonstrating the use of UI Responsiveness functionality in Internet Explorer 11 to determine how the browser handles animated GIFs in various states. This post was a fairly well-received so I wanted to expand a bit more upon it and cover a few more scenarios.

For the most recent round of testing, I setup a simple interval to change the className of the body element every few seconds. This, in turn, affects the placement and layout of a single image element within the document.

(function () {

  "use strict";

  var states = ["", "opacity", "visibility", "offscreen", "perpendicular"],
      container  = document.body,
      cycles = 0,
      nextState;

  function advanceState () {
    // Advance to next array index, or return to start
    nextState = states[++cycles % states.length];
    // Indicate a new performance mark in our developer tools
    performance.mark(nextState ? "Starting " + nextState : "Restarting");
    // Update the body class to affect rendering of image
    container.className = nextState;
  }

  setInterval(advanceState, 3000);

}());

I used the performance.mark method to add my own indicators in the performance graphs to help me identify when the demo was transitioning into a new state. These performance marks are represented in Internet Explorer by small upside-down orange triangles.

performance.ticks

Let’s walk through each of these triangles left to right, discussing the state they represent.

GIF Untouched

This state is represented by all activity to the left of the first performance mark. Not much needs to be said – Internet Explorer continued to paint the GIF as it sat animated on the screen.

performance.ticks.0

Setting GIF Opacity

This step is represented by all activity between the first and second performance marks. In this step, the image element has its opacity property set to 0. Even though the image is no longer visible, the browser continued repainting the region occupied by the image element.

performance.ticks.1

Setting GIF Visibility

This step is represented by all activity between the second and third performance marks. In this step, the image element has its visibility property set to hidden. Once the visibility property was set to hidden, the browser made one final repaint (presumably to hide the element) and no further paint events took place during the duration of this state.

Of relevance here is that the hidden attribute on the image itself has the same effect. When this attribute is present on the element, Internet Explorer will cease to repaint that elements occupied region.

performance.ticks.2

Setting GIF Outside of View

This step is represented by all activity between the third and fourth performance marks. In this step, the image element is positioned absolutely at top -100% left -100%. In spite of the fact the element is positioned outside of the viewport itself, the browser continued to run paint cycles.

performance.ticks.3

Setting GIF Orientation Perpendicular to Viewport

This step is represented by all activity between the fourth and fifth performance marks (the fifth mark is the ‘Restarting’ mark). In this step, the image is rotated using the transform property so as to set it at a right angle to the viewport, effectively hiding its content from the viewer. This orientation did not affect the browser paint cycle, and Internet Explorer continued repainting the region occupied by the image element.

performance.ticks.4

Conclusion

As a general rule, it appears Internet Explorer will run paint cycles for every animated GIF in the document, unless that element has its visibility property set to hidden. This is fairly reasonable, since setting visibility to hidden is the only explicit way to tell the browser not to render the element. Keep this in mind when performance is of key importance.

After running through and investigating this further I was curious what the same test would reveal in Chrome. I was pleased to see that Chrome would cease to paint for the opacity, visibility, and offscreen configurations. No performance marks are revealed in Chrome’s developer tools, but you can identify the timer functions by the presence of a small orange mark.

performance.ticks.chrome

Milestone Hangout 0.2.0 Reached

For months I’ve been doing weekly Hangouts where I walk through the HTML Specification, and most recently the CSS 2.1 Specification. This has served as a means by which I can help others get a better understanding of the core technologies behind solid web development, as well as an opportunity for myself to retrace some of the forgotten roots of these ubiquitous languages.

Recently I wrapped up episode 20, or 0.2.0, which covered Counters, Automatic Numbering, Lists, and Backgrounds in CSS. It was a great episode since I had never actually used counters in CSS to begin with. This was one of the benefits of retracing those old roots – there is a surprisingly amount of stuff that isn’t common enough that I ever learned about it in the past.

After roughly 21 hours of live hangouts I am about to start a series of JavaScript hangouts. These will take place at the same standard time, Thursday evenings at 7:30pm Eastern. If you’re new to web development, or don’t feel all that confident with JavaScript, please feel free to attend. You can login with your Twitter handle and ask questions in realtime.

If you want to drop through some of the older hangouts, they’re organized in two playlists:

Browsers – Broken By Design

I set out a few hours ago to write about a problem I had experienced in Safari, Chrome, Firefox, and Internet Explorer. Opera worked as I expected, which had me convinced the other vendors merely dropped the ball, and shipped partial implementations for the :visited and :link pseudo-classes.

My CSS was very simple:

:link {
    color: white;
    background: red;
}

:link::before {
    content: "Pseudo: ";
}

A color set for unvisited links, followed by some content in the ::before pseudo element on all unvisited links. So when I dropped in two links (one visited, one not) I expected to see the following:

image00 copy

Instead, what I saw was a litter of inconsistent results between Chrome, Safari, Internet Explorer, Firefox, and Opera. The above image came from Opera. It performed exactly as I suspected. The others, not so much.

Chrome and Firefox gave similar results; both set “Pseudo” as a virtual first-child of both anchors (though I only asked to have it on unvisited links), and leaked the background color from :link into :visited.

Internet Explorer did better than Chrome and Firefox; it preserved the “pseudo” text, but left the background of the visited link untouched. I was still very perplexed as to why it was spilling values from :link over into :visited.

You can observe something interesting in Internet Explorer – :visited links start visually identical to :link links, but are transitioned into their :visited state immediately thereafter. Setting a transition on all links reveals the change when the document loads:

a {
    transition: background 10s;
}

You’ll see the :link links remain unchanged but :visited links slowly adopt their end style. This is not the case for Chrome, Firefox, Opera, or Safari.

Safari appeared to be the most broken of them all. It duplicated everything. Further, I attempted to set additional styles to :visited, and it completely ignored them.

Discovering History

I found it incredible that all of these browsers, with the exception of Opera, would get this so wrong. So like any good developer I took to the web to see who else might be complaining about this, which is when I came across a Stack Overflow post suggesting this was somehow related to security concerns.

This offered another search vector; security issues. That was the needed catalyst for opening up a fascinating story about yet another creative attempt by developers to put their nose where it may not belong – in the client browser’s history.

Browsers typically style links with a default color to indicate whether it is a visited link or not. We’ve all seen those blue and purple links before – they’ve become quite at home on the web. Somebody got the (seriously) brilliant idea to create anchors ad hoc, and use getComputedStyle to see if the links represented visited or unvisited locations.

Mozilla reports that you could test more than 200,000 urls every minute with this approach. As such, you could – with a great deal of accuracy – fingerprint the user visiting your site based on the other urls they have visited; and browser history runs deep.

Scorched Earth Solution

The solution implemented by Firefox (and apparently others) was to greatly reduce the presence of visited links. They started by instructing functions like getComputedStyle and querySelectorAll to lie (their words, not mine) about their results. Sure enough, a simple check confirms that though my :visited links have a different font color than :link links, getComputedStyle says they’re the same rgb value.

Mozilla’s Christopher Blizzard continues with a very key point (emphasis added):

You will still be able to visually style visited links, but you’re severely limited in what you can use. We’re limiting the CSS properties that can be used to style visited links to color, background-color, border-*-color, and outline-color and the color parts of the fill and stroke properties. For any other parts of the style for visited links, the style for unvisited links is used instead. In addition, for the list of properties you can change above, you won’t be able to set rgba() or hsla() colors or transparent on them.

And there it was, the explanation that tied all of the seemingly broken pieces together. The browser would instruct :visited to share property values with :link. The browsers aren’t broken; they were designed to fail.

Test Confirmations

I wanted to explore the now-understood implementation a bit further, so I tried a few things. Querying the DOM for :visited links (expecting 1 of 2) was my first decision. I also queried the DOM for :link as well – expecting 2 due to the new security:

Browser Number of :visited Number of :link
Chrome 0 2
Firefox 0 2
Internet Explorer 0 2
Safari 0 2
Opera 1 2

Nearly all of the browsers report no :visited link, with the exception of Opera. All browsers report a total of 2 links when querying :link.

So it seems like you can still get a list of visited sites in Opera. Internet Explorer, Firefox, Chrome, and Safari all prevented the exploit from being carried out. But one thing about Internet Explorer intrigued me; remember the transitioning I spoke of earlier?

Internet Explorer Still Vulnerable?

I noticed that if I set transition: background 10s on anchors in Internet Explorer you would slowly see all visited links slowly tween into their end state. Transitions fire the transitionend event when they complete, so could we still get the user’s visited links in Internet Explorer?

The CSS to test this is very simple:

a { transition: background .01s }
:link { background: red }

And the following JavaScript:

/* Anchor var, fragment, and array of guesses */
var anchor;
var fragment = document.createDocumentFragment();
var websites = [
    'http://bing.com',
    'http://google.com',
    'http://jquery.com',
    'http://appendto.com',
    'http://stackoverflow.com'
];

/* Listen for completed transitions */
document.addEventListener("transitionend", function (event){
    console.log(event.target.href);
}, false);

/* Create a link for each url */
websites.forEach(function(url){
    anchor = document.createElement("a");
    anchor.setAttribute("href", url);
    anchor.innerHTML = url;
    fragment.appendChild( anchor );
});

/* Add our document fragment to our DOM */
document.body.appendChild(fragment);

Immediately upon being added to the DOM our :visited anchors will start to transition away from looking like a :link anchor. Once that transition is complete, we learn what the URL is, and confirm that the user has visited that site.

Closing Thoughts

I was reminded today just how exciting our industry is. People are constantly experimenting, learning new things, and sharing that knowledge. Industry experts, developers, designers, and browser vendors are always working to shift and adjust in light of the ever-evolving web.

Although the CSS2.1 Specification says something, that doesn’t make it so – even if the feature is 15 years old. If the ends justify the means, browser vendors will (and did) fire-bomb their own code-base to protect the end user.

Finally, we’re all in this together; we ought to work together. Microsoft launched the @IEDevChat twitter account not too long ago to assist developer’s who are attempting to follow web-standards. Then even organized a group of developers who wanted to volunteer and help build a better web; you can find (and join) it online at http://useragents.ie.

I’m sure there’s more history here that I’ve yet to discover, but what I have seen is enough to pique my interest. If you have anything else to share, or can contribute to the vulnerability test approach above, please leave a comment below. I may swing back around and check out the other browsers later on.

Designing with Pseudo Elements in IE10

Pseudo Elements in IE10

When Internet Explorer 10 came onto the scene as one of the first desktop browsers engineered for touch, it brought with it a few upgrades to many form elements. Input fields began, overnight, to render with their own clear buttons, causing some anguish among designers who had already provided similar functionality on their own.

image05

It wasn’t long until Stack Overflow, and other communities, began hearing the groans of web designers wanting to know how they can turn off these new progressive enhancements. But what initially appeared to be a nuisance is actually a great opportunity. These new pseudo elements give us more control than ever before.

Quick Brushup

Pseudo elements are parts of the document that are not declared in our markup, but are provided by the browser when rendering certain elements. For instance, pseudo-elements exist that represent the ::first-line of text in a paragraph. This requires no additional markup to function, but gives us great control over how things look.

image06

I would like to cover nearly 20 pseudo elements in the remainder of this article, demonstrating with each what type of effect(s) we can achieve in our presentation.

Here’s a list of what we’re going to cover:

::after ::before
::first-letter ::first-line
::-ms-browse ::-ms-value
::-ms-check ::-ms-clear
::-ms-expand ::-ms-fill
::-ms-fill-lower ::-ms-fill-upper
::-ms-reveal ::-ms-thumb
::-ms-ticks-after ::-ms-ticks-before
::-ms-tooltip ::-ms-track
::selection

Before and After Pseudo Elements

The ::before and ::after pseudo elements create virtual children within the container (like an invisible <span> element). These appear before all other children, and after all other children, respectively. You can use these to achieve many great effects, such as fading an image out and adding text over the top of it.

image02

The HTML for the above is very simple. It’s nothing more than an image within a figure element.

<figure>
    <img src=”jonathan-sampson.jpg">
</figure>

In the CSS we’re using ::after (::before is used the same way) to add a positioned element over the top of our image, give it a gradient background, and some text content.

figure {
    position: relative;
}

figure::after {
    /* Text and Color */
    color: white;
    font: 1em "Segoe UI";
    content: "@jonathansampson";
    text-shadow: 0 .1em .2em #004D71;
    /* Size and Placement */
    left: 0; bottom: 0;
    width: 100%; padding: 2em 0;
    display: block; position: absolute; 
    /* Background */
    background: linear-gradient(to top, white 1em, transparent);
}

First Line and Letter Pseudo Elements

By using the ::first-line and ::first-letter pseudo elements we can target the first line of text in a text block, as well as the first letter in that line, and modify their styles independently of their surroundings. By combining both of these, we can achieve an effect like the following:

image03

The above consists of nothing more than a simple paragraph, as far as markup is concerned.

<p>When Internet Explorer 10 came onto the scene...</p>

The styles too are very concise and easy to understand.

p {
    font: 1em "Segoe UI";
}

p::first-line {
    font-weight: bold;
}

p::first-letter {
    font: 5em "Script";
    float: left;
    line-height: .5em;
    padding: .15em .15em 0;
}

Browse and Value Pseudo Elements

File uploads have always been a pain to style; in the past we didn’t have much access to the button itself. Today with the ::-ms-browse and ::-ms-value pseudo elements we can target individual parts of the file upload control and create a far better presentation than was ever possible before.

image07

The markup here is familiar and short; it’s just a single file input.

<input type="file">

The CSS, on the other hand, is slightly more verbose since we’re targeting the input element, the browse and value pseudo elements collectively, as well as individually.

input {
    background: transparent;
}

::-ms-browse, ::-ms-value {
    border: 0;
    padding: 1em;
    color: rgb(71,194,254);
    background-color: rgb(1,132,195);
    background-image: 
        linear-gradient(to bottom, transparent 1px, rgb(71, 194, 254) 1px, transparent 1em),
        linear-gradient(to top, transparent 1px, rgba(0,0,0,.2) 1px, transparent 2em);
}

::-ms-browse {
    font-weight: bold;
    background-color: rgb(1, 107, 157);
    border-radius: 0 .5em .5em 0;
}

::-ms-value {
    border-radius: .5em 0 0 .5em;
}

Check Pseudo Element

With ::-ms-check we now have access to the inner-part of a radio or checkbox. This means we can now modify its presentation just as easily as we could the rest of the element itself. In the example below we’ve increased padding, changed the background color of the checked-portion, updated the foreground color, and even added a subtle inner glow.

image09

The CSS is very straightforward.

::-ms-check {
    border: 0;
    color: white;
    padding: .25em;
    background-color: rgb(1,132,195);
    box-shadow: inset 0 0 .5em rgb(71, 194, 254),
}

Clear and Reveal Pseudo Elements

This article opened with an example of the new ::-ms-clear pseudo element, and a short description of the frustration it has caused many designers who have already had long-standing functionality in place to clear fields. Often times designers just want it to go away.

::-ms-clear {
    display: none;
}

Easy enough.

Similar to the ::-ms-clear pseudo element is the ::-ms-reveal pseudo element. This is represented as a button in password fields. When pressed, and held, it reveals the password in the text box to which it is associated.

You can also set its display to none if you wish to get rid of it.

Expand Pseudo Element

The ::-ms-expand pseudo element grants you power over the button typically displayed with select menus. By leveraging this pseudo element we can round corners, set gradient backgrounds, and so much more.

image01

I cheated here just a bit and added styles to both the select element, and the ::-ms-expand pseudo element.

select {
    color: #333;
    padding: .25em;
    border-radius: .5em;
    background-color: #f1f1f1;
    background-image:
        linear-gradient(to bottom, white, transparent);
    border: 1px solid rgb(71, 194, 254);
}

::-ms-expand {
    padding: .25em;
    margin-left: .25em;
    border-radius: 50%;
    color: rgba(0, 0, 0, .25);
    background-color: rgb(71, 194, 254);
    background-image: 
        linear-gradient(to bottom, rgba(255, 255, 255, .8), transparent 1em);
    border: 1px solid rgba(71, 194, 254, .5);
}

Fill Pseudo Element

The ::-ms-fill pseudo element works with the <progress> element, which shows an advancement in a set of sequences or length of time. The “filled” portion of the progress bar is exposed to us for additional styling on top of those styles applied directly to the main element itself.

While this element, visually, isn’t as complex as others we can still have some fun with it.

image00

progress {
    border: 0;
    height: 1.5em;
    border-radius: .25em;
    background-color: #f1f1f1;
}

::-ms-fill {
    border: 0;
    background-image:
        linear-gradient(to top, transparent 1px, rgba(255,255,255,.5) 1px, transparent 1em),
        linear-gradient(to left, rgba(0,0,0,.3) 3px, transparent 3px),
        linear-gradient(to right, rgba(0, 0, 0, .3), transparent);
}

Fill Upper/Lower, Ticks Before/After, Thumb, Tooltip, and Track Pseudo Elements

The range control is full of pseudo elements. The right side of the range, the left, the (optionally visible) ticks above or beside the control, the track itself, the popup tooltip, and the handle to change the value. In the following image you can see nearly every pseudo element adjusted in some way, shape, or form (tooltip not visible).

image08

The upper fill was given a slight glimmer while the lower fill was left solid. The ticks before (above the slider) and after (below) were made lighter. The thumb was rounded, given a slight gradient for depth, and a hollow-looking center. Lastly the track pseudo element was given white, semi-opaque, markers.

::-ms-tooltip {
    display: none;
}

::-ms-ticks-before, ::-ms-ticks-after {
    color: #999;
    display: block;
}

::-ms-ticks-before {
    background: linear-gradient(to top, #CCC, transparent 30%);
}

::-ms-ticks-after {
    background: linear-gradient(to top, transparent 70%, #CCC);
}

::-ms-fill-upper {
    background-color: rgb(1, 107, 157);
    background-image: 
        linear-gradient(to bottom, transparent 1px, rgba(255,255,255,.25) 1px, transparent 70%);
}

::-ms-fill-lower {
    background-color: rgb(1,132,195);
}

::-ms-thumb {
    background-color: white;
    background-image: 
        radial-gradient(circle, rgb(1, 107, 157) 20%, transparent 20%),
        linear-gradient(to top, #CCC, white);
    border-radius: 50%;
    border: 0;
}

::-ms-track {
    color: rgba(255, 255, 255, .5);
}

Selection Pseudo Element

The last pseudo element we’re going to look at is the ::selection pseudo element. This represents any selection of text in the document. The control you have over this is extended to the foreground color, and background color of the selection.

image04

By default selected text is white with a blue background. In the example above we have changed the text to black, and the background to hot pink (in true Irish fashion).

::selection {
    color: black;
    background: pink;
}

Conclusion

We’ve looked at nearly every pseudo element available in Internet Explorer 10, as well as a few types of modifications we can make to the UI by leveraging their presence in the document. It’s important to note that different browsers may have different pseudo elements you’ll have to target in order to modify the same (or similar) document elements. This post was merely an exploration of those that presently exist in Internet Explorer.

If you have any questions about the above examples, please feel free to reach out to myself, or any of my fellow IE User Agents. You can do so by leaving a comment below on this post, or tagging your tweet with the #IEUserAgents hashtag (we’re listening). If you have questions about general development and Internet Explorer, follow and interact with @IEDevChat on twitter.

If you would like access to Internet Explorer from your Mac to test these features, you can use BrowserStack, or download a free Virtual Machine from http://modern.ie. I use both methods regularly – I would encourage the virtual machine route if you have the space/memory.

That’s it. Go change the web.

Display: Grid – The Future of Responsive Grid Layouts

Brief History

The history of front-end design strategies is a wild thing to study. We started with linear page-outlines, largely consisting of a wall of text and hyperlinks. We later got clever and began co-opting <table> to give us more control over page layouts. We should have all been smacked for doing it, but it was the convention at the time.

When tables began to be more of a nuisance than a solution the community started leveraging floats, and working to define their design requirements in terms of laterally-shifted elements that sat next to one another. Of course that too presented a new set of problems – we had to perform an embarrassing amount of CSS acrobatics to clear our floats, or achieve something as simple as the Holy Grail of layouts (which was trivial with <table>).

Things got better; tried and true conventions and approaches were packaged up into wildly popular frameworks like Nathan Smith’s 960 Grid System, and appeared to have solved all of our problems for a short while. But the fact remained that while we had comfort, it came at the cost of meaningless additional markup, and cryptic classnames. The DOM was getting noisy.

Introducing Grid Layouts

Browser vendors and standards bodies took it upon themselves to start working on alternative, more reliable solutions. With the release of Internet Explorer 10 we saw the first major browser implement a CSS-based Grid System.

For the first time, we are able to author our content as it ought to be, without nesting it in arbitrary ad-hoc divs to give ourselves a little advantage in CSS. We can now turn simple markup into easily-manipulated sophisticated layouts.

No more absolutely positioned elements, pointless margins or padding, etc. CSS Grids completely liberate you – the designer – from having to wrestle with the layout engine to get the effect you want without forcing you to compromise on your markup or CSS.

Defining Columns and Rows

The CSS is remarkably very simple to grok; and if you’ve ever spent any time in the past wiggling through tables, you’ll find much of the code very familiar-sounding. We start by setting an element up as our grid container. In the code above, I used the body element:

body {
  display: -ms-grid;
}

Because this technology is still experimental, you can only access it by using the -ms- prefix. Once we have set our display mode to -ms-grid, we have to define our columns and rows. This too is very straightforward:

body {
  display: -ms-grid;
  -ms-grid-rows: 100px 200px 1fr;
  -ms-grid-columns: 1fr 150px;
}

This results in a grid that has three rows, and two columns. Think of a table that has three table rows, and two table cells in each row. Our first row is 100px tall. Our second is 200px tall. Lastly, our third row is the full remaining fractional value; so whatever is left over after 300px is taken away, that will be the height of our third row.

We took a similar approach for our columns. Our first column takes the remainder of the horizontal space left over after 150 pixels have been given to our second column. At this point, your design will be mangled beyond recognition. Until you specify where each element ought to reside, they will all be tossed into row one, column one – do you even grid, bro?

Placing and Sizing Grid Items

Once you have your rows and columns defined, it’s trivial to move your elements around from any column or row to another. For instance, suppose we wanted to move our <h1> element into the first row, and have it span both columns:

h1 {
  -ms-grid-row: 1;
  -ms-grid-column: 1;
  -ms-grid-column-span: 2;
}

It’s so straightforward that it requires no explanation.

Not only can we specify which column and row our element resides in, we can also instruct our element to span additional columns and rows to better align our grid contents as we see fit.

Your main bag of tools consists of the following properties:

Property Description
-ms-grid-row target row
-ms-grid-row-align horizontal alignment
-ms-grid-row-span number of rows to span
-ms-grid-column Target column
-ms-grid-column-align Vertical alignment
-ms-grid-column-span Number of columns to span

The alignment properties accept values such as start, end, center, and stretch. In a left-to-right layout, start will align the element to the left while end will align it to the right. Stretch will cause the element to consume all available space in the grid location. By default grid items are stretch, so don’t freak out if an image initially looks wonky.

Responsive Grids

With this much control over the layout in our CSS, you can imagine the amount of flexibility we have when we add media queries into the mix. All of a sudden, we can rearrange everything when in portrait mode as opposed to landscape, or desktop as opposed to mobile.

Below I created a simple example that shifts the layout around above and below the 400 pixel mark. In the left image we have more of a “mobile” experience, and in the right we’ve rearranged the elements (without touching the markup, woot) to present a wider experience.

image02image00

Here are the two media queries. Note the small amount of changes needed to completely restructure things.

body {
  -ms-grid-columns: 50% 50%;
  -ms-grid-rows: auto auto 1fr;
}

@media screen and (max-width: 400px) {
  nav  {
    -ms-grid-row: 2;
    -ms-grid-column: 1;
    -ms-grid-row-align: center;
    -ms-grid-column-align: center;
  }
  h1 {
    -ms-grid-row: 1;
    -ms-grid-column: 1;
    -ms-grid-column-span: 2;
    -ms-grid-row-align: center;
    -ms-grid-column-align: center;
  }
  img {
    -ms-grid-row: 2;
    -ms-grid-column: 2;
  }
  article {
    -ms-grid-row: 3;
    -ms-grid-column: 1;
    -ms-grid-column-span: 2;
  }
}

@media screen and (min-width: 400px) {
  nav  {
    -ms-grid-row: 3;
    -ms-grid-column: 2;
  }
  h1 {
    -ms-grid-row: 2;
    -ms-grid-column: 2;
  }
  img {
    -ms-grid-row: 1;
    -ms-grid-column: 2;
  }
  article {
    -ms-grid-row: 1;
    -ms-grid-column: 1;
    -ms-grid-row-span: 3;
  }
}

I have purposefully kept the examples here relatively simple, but only because I don’t feel this requires a great deal of explanation to get my point across – grids are freaking amazing.

In this short introduction we’ve seen how to create a grid container, assign arbitrary numbers of columns and rows with various dimensions. We placed elements, moved them around, and dynamically updated their properties to completely reconfigure our layout.
In the midst of all this excitement, there is a bit of bad news (isn’t there always?).

The Caveat

As of writing this the only browser to currently support CSS Grids is Internet Explorer 10. This means all of the code from above will have no effect in Chrome, Firefox, Opera, or any of the other major browsers. Check caniuse.com/css-grid for most recent changes.

If you are interested in developing Windows Store Applications with HTML, CSS, and JavaScript, you can definitely put this feature into your bag of tricks to ensure your app looks and feels the way you expect.

Although you can’t put it to much use on the open web, it is still good to begin developing a familiarity with the technology as the W3C Grid Layout spec is in the works and will hopefully find its way to Candidate Recommendation in the future.

Need More Direction?

If you’re looking for some assistance with any of the above content, or even with IE’s implementation of CSS Grids, you have a few places you can go to get assistance. Stack Overflow is almost always my first suggestion, though it currently doesn’t have much content around IE’s CSS Grids implementation (likely to change in the near future).

Another great place to look would be the @IEDevChat account on twitter. Additionally, if you want to get the attention of the User Agents (of useragents.ie) you can tag your tweet with #IEUserAgents. This notifies a developer experienced in Internet Explorer to come and assist you. Sweet deal, right?

On a Mac? Don’t have Internet Explorer 10? You’re not out of luck – you can test all of these features using http://browserstack.com. Additionally, you can download a free virtual machine with IE10 from http://modern.ie. I happen to be working on this demo in a virtual machine, and the performance is stellar on my MacBook Air in Parallels.

That’s it. Go be awesome.

Visualizing :hover Propagation

The :hover pseudo-class can be tossed into a CSS selector to target the state of the element when the user’s cursor is currently positioned over the element. Due to the hierarchical structure of the DOM, anytime you activate the :hover state of an element, you activate it for all ancestral elements too. Wanting a quick illustration for this, I took to JSFiddle.

http://jsfiddle.net/FwKqq/6/show/

Repeating Lateral Text Shadows

I’ve wanted to do this effect for some time now. It consists of one or more lines of text with variable indentation, and seemingly ever-repeating washed out copies of the text on both sides running off screen.

Decided to use text-shadow to implement it, though support is not as broad as I’d like to see. The primary pain in this is with the offset for the text-shadows. Due to the varying length of each line, you have to provide specific offsets for each line having the effect. This could a lot less painful if it were to be built with a preprocessor.

I’ve uploaded the demo over at Dabblet, JSFiddle, and CodePen. And for those who don’t have a browser that supports text-shadow, here’s a screenshot of the result:

shadows

One really neat side-effect of this approach is that because it uses shadows, it inherently gives off a responsive feel; in the demos above you can see that it extends as far left and right as its parent permits.

Update: Now Animated using @keyframes

Sometimes Chrome is the broken browser (Or, How Chrome failed me twice in one night)

For several years it’s been generally accepted by the web-development community that Internet Explorer is nothing more than a means by which developers are subjected a great deal of emotional and mental trauma. Well, that has changed in the last couple of versions, but most developers are still licking their slow-healing wounds.

One thing that bothers me though is how so many automatically feel as though these types of issues only exist with Internet Explorer, generally touting Google Chrome as the full-featured flawless alternative. Granted, Google has done an outstanding job with the Chrome browser, and I personally use it for most of my work, but Chrome is in no way special. It too is capable of causing a lot of upset – such was the case this evening for me.

I worked on a couple of marquee demos over the last few days which gave me another idea. I wanted to cover an element with its ::after pseudo-element, apply a transparent-to-black background on the pseudo-element, and then animate it off to the right using @keyframes. I didn’t want this to be visible as it moved off to the right, so I applied a parent element of the same dimensions, and set its overflow to hidden. Queue the tears.

Chrome 24, wouldn’t respond. It just sat there, frozen. I could have sworn I did something wrong, but the demo was so simple in its construction. Where was I going wrong? I ended up testing the same demo in Internet Explorer 10, and found it it immediately kicked off without any problems. So, back to Chrome – it turns out there was a question on Stack Overflow asked some time back regarding this very issue, which led me to news that Chrome had apparently fixed this in version 26 (unstable at the time of this writing).

Opening up Canary, I was pleased to see that my pseudo-elements were indeed being animated. Nice work Chrome! This was the first issue tonight where Internet Explorer 10 was working as expected, and Chrome was not. Next I noticed the pseudo-element bleeding out over the rounded edges of the parent; that’s not supposed to happen when you’ve got overflow:hidden set – right?

Back to Internet Explorer 10, I confirm that overflow:hidden does as it advertises, and the pseudo-element is not visible outside of its parents rounded corners – way to go Internet Explorer 10! But I still needed an unequivocal demonstration of this bug to confirm if Chrome was indeed busted, and misbehaving. That demo is now available online. As of today (January 20, 2013), this demo is broken in all versions of Chrome, but working in Internet Explorer 10 and Firefox.

So what’s the story here? The take-away is that Internet Explorer is no longer the browser it used to be. It’s a fully-qualified modern browser capable of some really killer things. It is well-built, and carries as much respect for standards as its competition. Chrome, on the other hand, did not come down to us from the gods of Mount Chrominus. It too is flawed in some ways, while brilliant in others.

Jumping on the one-browser-to-rule-them-all bandwagon doesn’t help the developer’s plight, it worsens it. Advocate standards, not browsers. Get behind good practices such as progressive-enhancement, feature-detection, and when necessary polyfills. Don’t champion a browser, champion the web.

Sometimes Chrome is the broken browser – it happens.

CHROME, Y U NO ANIMATE PSEUDO-ELEMENTS LIKE IE10?

Free Web-Development Course

I have recently started offering a free web-development course both in person and online. The title of this meetup is “Home-Brew Web Development” and it takes place every Thursday evening at 7:30pm Easter Standard Time (unless otherwise stated). Each meetup is streamed live online at http://learn.sampson.ms, and archived on YouTube immediately afterwards.

We will start by learning HTML, followed by CSS. Eventually we will get into more advanced topics but I plan to keep it simple for now. This course is intended for those who have zero (or very little) experience in web-development, but are interested in it as a hobby, or a career-opportunity.

If you would like to receive regular updates regarding this course, future meetings, and more, you may subscribe to the newsletter via the link below. If at anytime you wish to stop receiving emails and stop attending the meetup, you’re totally free to go – it’s your call :)

Subscribe: http://eepurl.com/u_A61
Episodes: http://www.youtube.com/playlist?list=PL3IYnZmsleiXRVk1G-dcX4AJ_9kcSIO99