CSS Articles

Sort by:


  1. Building RTL-Aware Web Apps & Websites: Part 1

    Making the web more accessible to more people, in more languages, is an ongoing effort and a mission we take very seriously at Mozilla.

    This post is the first of a series of articles to explain one of the most neglected and least well-known corners of web development: RTL (right-to-left) development. In a web development context it means making your web content compatible with RTL languages like Arabic, Hebrew, Persian, and Urdu, which are all written from right to left.

    This area is often neglected by developers because of the lack of teaching resources. In this series, we hope to provide enough information to allow developers to make content that’s accessible to a broader global audience using the RTL capabilities that most web browsers currently provide.

    What actually is RTL?

    To make things clear, there is a difference between a language and its script. A script is the text or written form — while the language refers to the spoken form. So technically, right-to-left describing the script in which a language is written, comparable to left-to-right scripts, like English or French, more familiar to many Western readers.

    For example, “Marhaban” – which means hello – is a word written in the English script, but has Arabic as its language, while “مرحبا” is both Arabic script and Arabic language.

    On the web, as we said earlier, the term Right-To-Left indicates more than just a script for writing. It stands for all facets of developing web apps and websites that do not break or become unreadable when used with Arabic, Urdu or any other RTL script.

    Before continuing, let’s just clear up some misconceptions about RTL.

    First, RTL is not about translating text to Arabic: It means more than translating your website into Arabic and calling it a day. It’s about making every aspect the UI and layout RTL-friendly. And as I always say – and can’t stress it enough – do RTL right or don’t bother! Doing it halfway will lose your audience and credibility.

    Second, RTL is more than just “flip all the things”: I’m not sure if this issue has been fixed yet or not, but setting your locale to Arabic in Gnome will cause the time to be shown as PM 33:12 instead of 12:33 PM.

    Well, that is not how it works. I’m a native Arabic speaker but that doesn’t mean I tell time backwards. There are some exceptions and things to pay attention to about numbers, and we will cover them in this series.

    Why should I care about RTL?

    You might have the impression that RTL is hard, scary, and will add a great deal of work to your project! Really, it’s not that difficult. Once you comprehend the basics, the extra effort required is not that great.

    You should really care about adding right-to-left support to your web app or website for many, many reasons. There are over 410 million native RTL speakers around the world as of 2010 (That’s a lot of people! Note: The assessment is based on Wikipedia’s list of all the languages.) It’s also millions of potential users and a huge potential market for your app or website. Most companies now add RTL support to their software (e.g. Windows, iOS, Android) and websites, so native RTL speakers expect your website to meet their expectations regarding RTL support. Without this support visitors to your web application may not become repeat users.

    In the case of Firefox OS, we only started shipping devices to the Middle East when we had RTL support fully implemented in the system, and thus our partner Orange was able to sell devices with the OS on it. This obviously opens up a whole new market of users to Firefox OS.

    Best practices for RTL

    Here are some general rules of thumb to keep in mind when developing RTL-aware websites and web apps:

    • Think from the right: In a region with an RTL script and language, books open from the right-hand side. Thus, most UI elements related to readability are going to be mirrored.
    • Hardware legacy UI is a thing: In MENA (Middle East and North Africa) and other regions where RTL languages are spoken, people use gadgets too. Audio hardware has the same control layout as anywhere else in the world. So buttons like Play, Fast Forward, Next, Previous have always been the same. And because of that, it’s not a good idea to mirror any of those buttons. Please don’t RTL the media player buttons. Another example of hardware legacy is the physical feature phone keyboard; before there were Blackberries and similar keyboards for handhelds, there was the simple physical numpad — until very recently it was widely popular in MENA countries. For this reason, It is strongly advised to *not* mirror the number keys. A good example of this is Firefox OS. As its initial target was developing countries, we made sure not to make the dialer mirrored in RTL.
    • Firefox OS Contacts AppThinking Right-To-Left is not thinking left-handed: Remember not to confuse developing RTL UIs with southpaw-first ones. In RTL regions of the world, right-handed people are a majority, just like in the rest of the world. So anything that is not related to how the user reads the actual content on the page should not be mirrored. An example of this is the Firefox OS A-Z scrollbar (image to the right) in the Contacts App. It is placed on the right because it’s easier to scroll through with the right hand, so such a thing should not go on the other side when your page is in RTL mode.

    Down to business: How to RTL content

    The first step towards making a web page RTL is adding the code dir="rtl" to the <html> tag:

    <html dir="rtl">

    dir stands for direction and setting its value to rtl defaults the horizontal starting point of elements to the right instead of the left.

    To target an element with CSS only when the page is RTL:

    1. Create a copy of any regular CSS rules that target it.
    2. Add a html[dir="rtl"] attribute selector onto the front of the selector chain.
    3. Next, whenever you find a property or a value that represents horizontal positioning of some kind in the RTL rule, use its opposite. For example, if you find `float: left` you should change it to float: right.

    As an example, if the original rule is as follows —

    .someClass {
        text-align: left;
        padding: 0 10px 0 0;
        text-decoration: underline;

    we would paste a copy of it after the original and update it as follows:

    html[dir="rtl"] .someClass {
        text-align: right;
        padding: 0 0 0 10px;

    Notice that the text-decoration: underline; declaration has been removed. We don’t need to override it for the RTL version because it doesn’t affect any direction-based layout elements. Thus, the value from the original rule will still be applied.

    Here’s an even more detailed example you can hack on directly:

    See the Pen dYGKQZ by Ahmed Nefzaoui (@anefzaoui) on CodePen.

    Of course, real-life cases won’t be quite as simple as this. There are applications with a huge number of CSS rules and selectors, and there are multiple strategies you could adopt. Here is one recommended approach:

    1. Copy and clean up: First, copy the content of your stylesheet to another file, add html[dir="rtl"] to all the rules, then clear out any properties that do not relate to horizontal direction setting. You should end up with a more lightweight file that deals purely with RTL.
    2. Mirror the styles: Change all of the properties left in the new file to their opposites: e.g. padding-left becomes padding-right, float: right becomes float: left, etc. Note: if you originally had padding-left and you changed it to padding-right, remember that the original padding-left still exists in the original rule. You must add padding-left: unset alongside padding-right, otherwise the browser will compute both properties: the padding-left from the original CSS rule and the new padding-right in the RTL rule. The same is true for any property that has multiple direction variants like the margin-left|right, border-left|right
    3. Paste back: After you’ve completed the previous steps, paste the newly created rules back into the original file, after the originals. I personally like to add a little comment afterwards such as: /* **** RTL Content **** */ for the sake of easier differentiation between the two parts of your style file.

    A better way: isolating left/right styles completely

    Sometimes you will find yourself facing edge cases that produce code conflict. This involves properties inheriting values from other properties, meaning that sometimes you won’t be sure what to override and what not to. Maybe you’ve added the margin-right to the RTL rule but are not sure what to set as the value for the original margin-left? In all real-world cases it is advisable to adopt another approach, which is better in general but more long-winded. For this approach we isolate direction-based properties completely from the rules for both the LTR and the RTL cases. Here’s an example: say we have .wrapper .boxContainer .fancyBox listed like this:

    .wrapper .boxContainer .fancyBox {
        text-align: left;
        padding-left: 10px;
        text-decoration: underline;
        color: #4A8CF7;

    Instead of adding another property for RTL with both padding-left and padding-right, you can do this:

    .wrapper .boxContainer .fancyBox {
        text-decoration: underline;
        color: #4A8CF7;
    html[dir="ltr"] .wrapper .boxContainer .fancyBox {
        text-align: left;
        padding-left: 10px;
    html[dir="rtl"] .wrapper .boxContainer .fancyBox {
        text-align: right;
        padding-right: 10px;

    This solution consists of 3 parts:

    1. The original rule/selector with only non-direction based properties, because they are shared by the LTR and the RTL layout.
    2. The left to right case — html[dir="ltr"] — with only the direction-based CSS properties included, their values set to match your LTR layout.
    3. The right to left case — html[dir="rtl"] — with the same properties as the LTR case, only with their values set according to what you want in your RTL layout.

    Notice that in the second rule we had padding-left only and in the third one we had padding-right only. That’s because each one of them is exclusive to the direction that was given to them in the dir attribute. This is a nice, clean approach that doesn’t require unsetting of properties. This is the exact approach we use when adding RTL support to Firefox OS. (Note: the unset keyword isn’t supported in all browsers. For the best compatibility you may need to explicitly re-declare the desired value for any properties you want to unset.)

    How do we get and set the direction of the page using JavaScript?

    It’s fairly easy, and requires only one line of code: document.documentElement.dir
    You can assign this line to a variable, and have it outputted to the console to see for yourself:  

    var direction = document.documentElement.dir; console.log(direction);

    Or try this example:

    See the Pen WQxWQQ by Ahmed Nefzaoui (@anefzaoui) on CodePen.

    To set the direction of the page, just use the following:
    document.documentElement.dir = "rtl"

    And here’s an example of both getting and setting the direction value for a web page:

    See the Pen gaMyPN by Ahmed Nefzaoui (@anefzaoui) on CodePen.

    Automatic RTL solutions

    Enough talk about manual ways to do RTL. Now let’s take a look at some automated approaches.


    Twitter has developed a solution to automate the whole process and make it easier for bigger projects to implement RTL. They have open sourced it and you can find it on Github.

    This NPM plugin covers pretty much all the cases you could find yourself facing when working on RTL, including edge cases. Some of its features include:

    • no-flip: To indicate to the mirroring engine that you don’t want a certain property flipped, just add /* @noflip*/ at the beginning of the property. So, for example, if you write /* @noflip*/ float: left, it will stay as float: left after css-flip is run.
    • @replace: When you have background images that differ between LTR and RTL, you can specify a replacement image by including /*@replace: url(my/image/path) before the original property. Let’s say you have background-image: url(arrow-left.png). If you update the line to
      /*@replace: url(arrow-rightish.png) */ background-image: url(arrow-left.png);
      You will end up with background-image: url(arrow-rightish.png); in the RTL layout.

    You can use css-flip through the command line by executing
    css-flip path/to/file.css > path/to/file.rtl.css or by requiring css-flip in your page. More about that on their github repo. css-flip is being actively used on Twitter properties.


    Another option for automatic conversion is a tool from Mohammad Younes called rtlcss — this is also available on github and provides some pretty nifty features. With this one engine you can:

    • Rename rule names (e.g. renaming #boxLeft to #boxRightSide).
    • Completely ignore rules from the mirroring process.
    • Ignore single properties.
    • Append/prepend new values.
    • Insert new property values in between other property values.

    Basic usage is via the command line — you can create your RTL CSS equivalent by the running the following in the same directory your original CSS is available in:

    rtlcss input.css output.rtl.css

    And of course you can just require it in your page. More details are available on github.

    This project is very popular and is being used by several projects including WordPress.

    Final words

    While there is still a lot to cover, this article aims to provide you with enough knowledge to start exploring RTL confidently. In the next article we’ll cover more advanced topics around RTL.

    Be sure to ask any questions you may have around RTL in the comments section and we will try to answer them here or in the next post!

  2. The future of layout with CSS: Grid Layouts

    In this article we’ll take a look at the wonderful world of the CSS Grid Layout, a relatively new W3C specification that has partially started to see the day in some browsers.

    But before we dive into what this new CSS technique is all about and how to use it, let’s quickly review grid theory.

    My really short introduction to grid theory

    I am not a designer nor did I know much about grid theory before stumbling upon the CSS Grid Layout specification, so don’t take my word for it and go look it up yourself, but if you don’t care to, here’s my pitch:

    In essence, a grid is a set of invisible vertical and horizontal lines that are used to position the various design and content pieces of a web page, magazine, or newspaper. The goal of a grid is to serve as a base for placing the various pieces of content and to make sure these pieces are aligned and spaced out evenly. A grid, even if not visible, provides the viewer with a way to navigate content visually.

    So what has CSS got to do with it?

    CSS is getting a set of entirely new properties that, when used together, allow you to define grids for your web content to go onto. These properties are defined in the CSS Grid Layout specification.

    CSS hasn’t particularly been known for its ability to handle complex layouts. Although this may not have been a problem when CSS first came out, it has evolved to be a pretty common one over the years, as all sorts of complex layouts couldn’t be easily implemented. People have been very creative at getting around the lack of support by using floats or absolute positioning and a variety of CSS layout frameworks emerged.

    So it’s about time CSS got some proper layout solutions to support today’s use cases.

    Can I use it?

    Yes you can start using it today, to experiment and learn. It’s a bit too early to use it on a commercial website.

    Chrome has implemented the specification far enough to play with Grid. Turn the experimental Web Platform features flag on to get it to work. The Chrome implementation is currently the most up-to-date with the recent changes to the CSS Grid Layout specification.

    Internet Explorer had the first implementation of CSS Grid (dating back to IE10), but the spec has evolved since it was added and so it’s not entirely compatible with the latest spec anymore. They’ll be updating their implementation soon.

    Firefox has started implementing it too, so it shouldn’t be too long before you can use it in this browser.

    Finally, a polyfill exists, so you have no excuses not to start experimenting. (And I strongly encourage you to do so!) You probably should not use the polyfill in production, however.

    So what’s a CSS grid layout?

    At its core, a grid layout in CSS is a set of vertical and horizontal lines that define cells into which content can be arbitrarily positioned.
    So it looks like a table in a way, except for a few key differences we’ll see later.

    1 zcOcwuBtMoBaUfHHAJPNyg

    The figure above shows the building blocks of a grid:

    • Lines: In this case there are 4 vertical lines and 3 horizontal lines. Lines are given numbers starting from 1. Vertical lines are shown from left to right, but this depends on the writing direction. Lines can optionally be given names, which helps with referencing them in CSS, as we’ll see later.
    • Tracks: A track is simply the space between 2 parallel lines. So in the above example, there are 3 vertical tracks and 2 horizontal tracks. Lines are useful to indicate where content starts and stops, but tracks are ultimately where content goes.
    • Cells: A cell is where a horizontal and a vertical track meet. In the figure above, only one cell has been highlighted, but there are 6 cells in the grid.
    • Areas: An area is a rectangular shape that can span an arbitrary number of cells. Areas, like lines, can be named. In the above grid, we could for example define areas A, B and C as shown below:

    1 zcOcwuBtMoBaUfHHAJPNyg

    Now that we know these simple definitions, let’s take a look at what makes grids so powerful.

    One key advantage of CSS grids is that they enforce real separation of layout and markup.

    Indeed, the grid itself is completely defined in pure CSS. This means that apart from the parent HTML element the grid is applied to, there’s no need to define any extra elements for the columns, rows, cells, or areas.

    When you think of it, that’s a really interesting property. One aspect of it is that the visual order of elements on the page is decoupled from the order of elements in the markup. That’s important because on a page the source order is used for things like speech and tab navigation, so CSS Grids allow you to optimize the markup for accessibility without compromising your ability to manipulate the visual result. One other point is that the markup will be somewhat lighter and easier to understand, and therefore easier to maintain.

    But more importantly, it gives us a very powerful tool for separating the content from the layout, effectively decoupling them in a way that makes it possible to change one without impacting or otherwise breaking the other.
    As a designer, you can easily experiment with new layouts without having to change anything other than CSS, as long as your new layouts provide the expected lines and areas the content uses.
    And as a developer, you simply use the numbered or named lines and areas to position your content on the grid.

    Imagine the simple following grid layout:

    1 zcOcwuBtMoBaUfHHAJPNyg

    In this layout, named areas have been defined, allowing content to be positioned in them simply by referencing the names. This means that not only can we change this layout relatively easily in the future, as long as we maintain the named regions (here the named regions act as the layout’s public API in a way), but media-queries can be used to change this layout dynamically too. Remember, the whole layout is defined in CSS, so media-queries play with grid layouts very well.

    For instance, using a media query, the previous layout could switch to something like this on smaller screens:

    1 zcOcwuBtMoBaUfHHAJPNyg

    Enough with the theory, let’s see how grid layouts are actually defined using CSS.

    Creating grids with CSS

    Defining a grid requires only one HTML element to be present: the grid container. That’s the element the layout is going to be applied to. Any HTML element that’s a child of the grid container is a grid item. Grid items are what go onto the grid.

    Setting an element as being a grid container is as simple as:

    .container { display: grid; }

    Just doing this though isn’t nearly enough, we also need to define what this grid looks like, how many columns and rows it has, and how big they are.
    This can be done using grid templates as shown in the following example:

    .container {
      display: grid;
      grid-template-rows: 200px 100px;
      grid-template-columns: repeat(4, 100px);

    In the example above, we’re explicitly defining a grid that has 2 rows and 4 columns. Note how the repeat() function is used here to avoid repeating a fragment of the tracks 4 times, this is equivalent to 100px 100px 100px 100px.

    Each of the defined tracks is given a size, and so we end up with a grid structure that looks like this:

    1 zcOcwuBtMoBaUfHHAJPNyg

    But grids can also be implicitly defined like in:

    .container {
      display: grid;
      grid-template-rows: auto;
      grid-template-columns: repeat(4, 100px);

    In this case, the browser will keep on adding rows as needed to fit the content.

    Now let’s add some content. As we said previously, we only need 2 levels of elements, the container and the items, so let’s use this:

    <div class="container">
      <div class="item1">item 1</div>
      <div class="item2">item 2</div>
      <div class="item3">item 3</div>
      <div class="item4">item 4</div>
      <div class="item5">item 5</div>

    Which, without any specific CSS code to position the items, leads to the following arrangement:

    1 zcOcwuBtMoBaUfHHAJPNyg

    As you can see above, since we didn’t define where these items should sit on the grid, the browser has positioned them automatically by putting one item per cell until the first row got filled in, at which point it decided to put the rest of the items on the next row.

    The spec defines an algorithm for automatically placing items on the grid if they haven’t been given a position. This is sometimes useful when, for example, you have either many items or a dynamic number of items and don’t want to or can’t define the position for them all.

    Let’s see how our items can be positioned on the grid.

    .item1 {
      grid-row-start: 1;
      grid-row-end: 2;
      grid-column-start: 1;
      grid-column-end: 3;
    .item2 {
      grid-row-start: 1;
      grid-row-end: 2;
      grid-column-start: 3;
      grid-column-end: 5;

    Here we’ve defined the position of the 2 first items, which means that the other ones will still be automatically positioned by the browser, as shown below:

    1 zcOcwuBtMoBaUfHHAJPNyg

    The above example uses line-based placement in that it uses numeric indexes of lines to place items. Items 1 and 2 are defined to be positioned between horizontal lines 1 and 2, and between vertical lines 1 and 3 and 3 and 5.

    What happens now if we keep on adding items, but there aren’t any grid cells defined to receive them?

    1 zcOcwuBtMoBaUfHHAJPNyg

    The grid keeps on adding rows and columns as needed. Note that these new tracks will have their sizes depend on the content size.

    So that’s all well and good, but one thing that’s really useful when it comes to CSS Grids is grid areas, as we saw earlier. Let’s take a look at how grid areas can be used in CSS.

    First of all you’ll need to define the grid container and its tracks and areas:

    .container {
      display: grid;
      grid-template-rows: 100px auto 100px;
      grid-template-columns: 100px auto;
        "header  header"
        "sidebar content"
        "footer  footer";

    In this example, we’ve defined 3 rows, the top and bottom ones being 100px high, while the middle one will just adapt to its content. We’ve also defined 2 columns, the left one 100px wide, and the right one adapting to its content.

    We’ve also introduced the grid-template-areas property that may look strange at first, but it’s really simple when you realize it’s only a representation of the grid with names on it. Let’s explain this.

    We said we had 3 rows and 2 columns right? Let’s represent them in ascii-art like this:

    | . | . |
    | . | . |
    | . | . |

    Each dot is a cell where areas can be defined. So let’s define areas for a typical website layout:

    | header | header |
    | sidebar| content|
    | footer | footer |

    We want the header and footer to span the whole width, so we’ve repeated them in the 2 columns.
    Now, if we just remove all the useless ascii-art style borders and include each line in double-quotes, we get something like this:

    "header  header"
    "sidebar content"
    "footer  footer"

    which is exactly how grid areas are defined in CSS using the grid-template-areas property. It helps thinking about it as a 2D representation of the grid in ascii-art and aligning area names.

    You can also use dots ‘.’ when a cell isn’t covered by an area. Here’s an example:

    .container {
      display: grid;
      grid-template-rows: repeat(5, 100px);
      grid-template-columns: repeat(5, 100px);
        ". . . . ."
        ". . . . ."
        ". . a . ."
        ". . . . ."
        ". . . . .";

    In this example, there are 25 cells and 1 area that is defined to occupy only the center cell.

    Now, going back to the previous header, sidebar, content, footer example, let’s add some markup to it:

    <div class="container">
      <div class="header">header</div>
      <div class="sidebar">sidebar</div>
      <div class="footer">footer</div>
      <div class="content">
        <p>Lorem ipsum dolor sit amet...</p>

    The last thing that needs to be done now is position each grid item in the correct named areas (we’ve conveniently used class names that correspond to area names here):

    .header { grid-area: header; }
    .sidebar { grid-area: sidebar; }
    .footer { grid-area: footer; }
    .content { grid-area: content; }

    Which would produce something like this:

    1 zcOcwuBtMoBaUfHHAJPNyg

    Now, if we wanted to change this layout at any point, or make it adapt to variable screen sizes thanks to media queries, we would only have to change the grid declaration. Maybe to something like this:

    .container {
      display: grid;
      grid-template-rows: auto;
      grid-template-columns: 100%;

    Without any other changes to the CSS or markup, we’ve produced this:

    1 zcOcwuBtMoBaUfHHAJPNyg

    We could even completely reshuffle the order of items in the grid without having to change their order in the markup.

    CSS Grids in the real world

    So far we’ve only seen simplistic examples of grids, but websites making use of grid systems often have much more complex grid structures. It’s not uncommon for such websites to be based on 12 columns, each of them separated by gutters (narrower columns used to space things out).

    Take for example, this design showcase website makes use of a grid to display the designs uploaded by their users. Here the grid is very easily visible because each design occupies exactly one cell (excluding gutter rows and columns):

    Dribbble’s grid layout is also responsive, so if the viewport size changes, the size and number of columns change gradually, as shown in the following animation:

    Using the new properties that come with the CSS Grid Layout implementation, we can try and create a dribbble-like layout. For an added twist, let’s try and insert a piece of text content on the second row, and make that content span the whole row.

    First of all, our markup will be something like this:

    <ul class="dribbbles">
      <li class="dribbble">...</li>
      <li class="dribbble">...</li>
      <li class="dribbble">...</li>
      <li class="advert">Some text ....</li>

    Here the dribbbles element is the main container for all items, and each .dribbble element represents one of the designs showcased on the page. The last item, .advert, is the piece of textual content we want to show on the second row.

    Now, let’s make a grid for it:

    .dribbbles {
      display: grid;
      /* Let's assume the default design has a fixed width */
      width: 880px;
      grid-template-columns: repeat(4, 220px);
        ".      .      .      ."
        "advert advert advert advert";
      justify-items: center;
    .advert {
      grid-area: advert;

    Here we’ve defined 4 columns in our grid. We haven’t said anything about rows, so the browser will automatically create rows as needed.
    We did, however, define a couple of rows using the grid-template-areas property and that’s because we need to place our advert text content on the second row. So we’ve just said that we want a first row with empty cells that are going to be filled in automatically with grid items, as they come, and then a second row that defines an advert area that spans all 4 columns.

    Finally, the second rule in there uses the grid-area property to place the grid item that has the class advert inside the advert area.

    Given the markup we created earlier, this should end up looking something like this:

    Pretty simple, right? Of course this requires some styling code to make the items look nice and all, but the layout CSS code is really short and there’s no extra markup required.

    Now, we can make this responsive too. Let’s say we want to jump to a 3-columns layout for smaller screens:

    @media (max-width: 880px) and (min-width: 660px) {
      .dribbbles {
        width: 660px;
        grid-template-columns: repeat(3, 220px);
          ".      .      ."
          "advert advert advert";

    And so on, for all the screen sizes we want to support. And so, just adding a couple more short media queries, we could end up with something like this:

    Sites like Dribbble don’t use the CSS Grid Layout yet, but there are well known CSS libraries that provide grid systems.

    A good example of a grid system in CSS is the Bootstrap CSS library but there are others like PureCSS, 960 Grid System, Responsive Grid System, Materialize, and more.

    These grid systems unfortunately have to use arrangements of carefully sized and floated DIVs, and need extra DIVs for columns and rows, as well as pseudo-elements for clearing floats. It’s not all that complex—after all, the tricks that these libraries rely on have been known for years—but they’re still just tricks, and it’s time we get a proper built-in solution and get rid of them.

    Don’t get me wrong, these libraries are awesome in all sorts of way, and most importantly, they helped make it clear we needed a new CSS feature for defining grids in web layouts. Ultimately, therefore, they are what made the CSS Grid Layout specification possible.

    Closing words and references

    As we saw, CSS grids are a pretty good tool for defining layouts that have nice characteristics like authoring simplicity, maintainability, separation of content and layout — characteristics that play well with responsive design.
    But we’ve only barely scratched the surface of what is possible with CSS grids. The various properties and syntax possibilities allow for a lot of really cool things to be done, and I hope this article makes you want to dig further by yourself.

    Here are some interesting references if you wish to know more:

  3. Scroll snapping explained

    Have you ever tried to snap your page’s contents after scrolling? There are many JavaScript libraries out there providing this functionality. Here are a few examples:

    As this is a common use case related to page layout and behavior, the W3C has published a pure CSS approach to scroll snapping.

    CSS scroll snapping, (available since July’s Firefox 39 release), allows you to control where to stop on an overflowing element when it’s scrolled. This lets you section your page into logical divisions and thus create smoother, easier-to-interact-with user interfaces. Touch devices in particular benefit from this feature, where it is easier for people to pan through pages instead of tapping through hierarchical structures.

    Image gallery

    Image galleries are surely the most common use case for scroll snapping: Users can flip through the images, viewing one image at a time by swiping or scrolling the page. So let’s see how this can be achieved with the new properties:

    img {
      width: 200px;
    .photoGallery {
      width: 200px;
      overflow: auto;
      white-space: nowrap;
      scroll-snap-points-x: repeat(100%);
      scroll-snap-type: mandatory;

    The related HTML code looks like this:

    <div class="photoGallery">
      <img src="img1.png"><img src="img2.png"><img src="img3.png">

    Here’s a live demo:

    See the Pen wKvYdK by Potch (@potch) on CodePen.

    The code above creates a simple image gallery with three images, which can be scrolled through horizontally.

    In this case the size of the images and their containing <div> are set to 200 pixels. The overflow: auto; displays a scrollbar on clients that support it. white-space: nowrap; serves to keep all images horizontally aligned. The definition “scroll-snap-points-x: repeat(100%);” sets a repeated horizontal snap point at 100% of the viewport width of the container <div>, in this case at 200 pixel intervals. Setting scroll-snap-type: mandatory; has the effect that snapping is forced. The viewport will always snap at a snap point, so the display will never stay in between two images.

    Item lists

    You’ve probably seen plenty of online product pages listing different features with an image of each feature and a description next to it, or an interface displaying a series of user testimonials.

    In these cases, scroll snapping lets you align the sections so that maximal display space is used.

    .features {
      width: 400px;
      height: 250px;
      padding: 0;
      overflow: auto;
      scroll-snap-type: proximity;
      scroll-snap-destination: 0 16px;
    .features > section {
      clear: both;
      margin: 20px 0;
      scroll-snap-coordinate: 0 0;
    img {
      width: 50px;
      height: 50px;
      margin: 5px 10px;
      float: left;
    section:last-child {
      margin-bottom: 60px;

    And here’s the related HTML code:

    <div class="features">
      <section id="feature1">
        <img src="feature1.png"/>
        <p>Lorem ipsum...</p>
      <section id="feature2">
        <img src="feature2.png"/>
        <p>Lorem ipsum...</p>

    Here’s a live demo:

    See the Pen NGWOjN by Potch (@potch) on CodePen.

    When you scroll within the example above, each feature section is positioned so that the top is aligned with the top of the viewport to display as much text as possible. This is achieved by applying scroll-snap-coordinate: 0 0; to the sections. The two zeros refer to the x and y coordinates of the element where it will snap to the container element. scroll-snap-destination: 0 16px; defines the offset position within the container element to which the inner elements should snap. In this case, that’s 16 pixels below the top of the container so that the text at top of the section has some margin at the top.

    In addition to the properties currently defined within the CSS Scroll Snap Points specification, Gecko implements the additional properties scroll-snap-type-x and scroll-snap-type-y, for setting the snap type individually per axis. These long-hand properties may be added to the specification in the future.

    Currently snap points can only be set through coordinates, either referring to the start edge of the container element or the ones within it. Sometimes this requires some calculation to set them at the right position. Future extensions to this feature may extend the functionality to be able to set snap points on the box model instead, which would make it easier to place them. There’s already a discussion about this within the www-style mailing list.

    Has this new functionality caught your interest? Then it’s time to give it a try! And if you don’t remember how to use the different properties, you can always refer to the documentation on MDN.

  4. Making and Breaking the Web With CSS Gradients

    What is CSS prefixing and why do I care?

    Straight from the source:

    “Browser vendors sometimes add prefixes to experimental or nonstandard CSS properties, so developers can experiment but changes in browser behavior don’t break the code during the standards process. Developers should wait to include the unprefixed property until browser behavior is standardized.”

    As a Web developer, users of your web sites will be affected if you use prefixed CSS properties which later have their prefixes removed—especially if syntax has changed between prefixed and unprefixed variants.

    There are steps you can take in stewardship of an unbroken Web. Begin by checking your stylesheets for outdated gradient syntax and updating with an unprefixed modern equivalent. But first, let’s take a closer look at the issue.

    What are CSS gradients?

    CSS gradients are a type of CSS <image> function (expressed as a property value) that enable developers to style the background of block-level elements to have variations in color instead of just a solid color. The MDN documentation on gradients gives an overview of the various gradient types and how to use them. As always, CSS Tricks has top notch coverage on CSS3 gradients as well.

    Screenshot of's CSS with a CSS gradient

    Removing (and then not removing) prefixed gradients from Firefox

    In Bug 1176496, we tried to remove support for the old -moz- prefixed linear and radial gradients. Unfortunately, we soon realized that it broke the Web for enough sites ([1], [2], [3], [4], [5], [6]) that we had to add back support (for now).

    Sin and syntax

    Due to changes in the spec between the -moz- prefixed implementation and the modern, prefix-less version, it’s not possible to just remove prefixes and get working gradients.

    Here’s a simple example of how the syntax has changed (for linear-gradient):

    /* The old syntax, deprecated and prefixed, for old browsers */
    background: -prefix-linear-gradient(top, blue, white); 
    /* The new syntax needed by standard-compliant browsers (Opera 12.1,
       IE 10, Firefox 16, Chrome 26, Safari 6.1), without prefix */
    background: linear-gradient(to bottom, blue, white);

    In a nutshell, to and at keywords were added, contain and cover keywords were removed, and the angle coordinate system was changed to be more consistent with other parts of the platform.

    When IE10 came out with support for prefixless new gradients, IEBlog wrote an awesome post illustrating the differences between the prefixed (old) syntax and the new syntax; check that out for more in-depth coverage. The article on CSS3 gradients also has a good overview on the history of CSS gradients and its syntaxes (see “Tweener” and “New” in the “Browser Support/Prefixes” section).

    OK, so like, what should I do?

    You can start checking your stylesheets for outdated gradient syntax and making sure to have an unprefixed modern equivalent.

    Here are some tools and libraries that can help you maintain modern, up-to-date, prefixless CSS:

    If you’re already using the PostCSS plugin Autoprefixer, you won’t have to do anything. If you’re not using it yet, consider adding it to your tool belt. And if you prefer a client-side solution, Lea Verou’s prefix-free.js is another great option.

    In addition, the web app Colorzilla will allow you to enter your old CSS gradient syntax to get a quick conversion to the modern prefixless conversion.

    Masatoshi Kimura has added a preference that can be used to turn off support for the old -moz- prefixed gradients, giving developers an easy way to visually test for broken gradients. Set layout.css.prefixes.gradients to false (from about:config) in Nightly. This pref should ship in Firefox 42.

    Modernizing your CSS

    And as long as you’re in the middle of editing your stylesheets, now would be a good time to check the rest of them for overall freshness. Flexbox is an area that is particularly troublesome and in need of unbreaking, but good resources exist to ease the pain. CSS border-image is also an area that had changes between prefixed and unprefixed versions.

    Thanks for your help in building and maintaining a Web that works.

  5. Drag Elements, Console History, and more – Firefox Developer Edition 39

    Quite a few big new features, improvements, and bug fixes made their way into Firefox Developer Edition 39. Update your Firefox Developer Edition, or Nightly builds to try them out!


    The Inspector now allows you to move elements around via drag and drop. Click and hold on an element and then drag it to where you want it to go. This feature was added by contributor Mahdi Dibaiee.

    Back in Firefox 33, a tooltip was added to the rule view to allow editing curves for cubic bezier CSS animations. In Developer Edition 39, we’ve greatly enhanced the tooltip’s UX by adding various standard curves you can try right away, as well as cleaning up the overall appearance. This enhancement was added by new contributor John Giannakos.


    The CSS animations panel we debuted in Developer Edition 37 now includes a time machine. You can rewind, fast forward, and set the current time of your animations.


    Previously, when the DevTools console closed, your past Console history was lost. Now, Console history is persisted across sessions. The recent commands you’ve entered will remain accessible in the next toolbox you open, whether it’s in another tab or after restarting Firefox. Additionally, we’ve added a clearHistory console command to reset the stored list of commands.

    The shorthand $_ has been added as an alias for the last result evaluated in the Console. If you evaluated an expression without storing the result to a variable (for example), you can use this as a quick way to grab the last result.

    We now format pseudo-array-like objects as if they were arrays in the Console output. This makes a pseudo-array-like object easier to reason about and inspect, just like a real array. This feature was added by contributor Johan K. Jensen.


    WebIDE and Mobile

    WiFi debugging for Firefox OS has landed. WiFi debugging allows WebIDE to connect to your Firefox OS device via your local WiFi network instead of a USB cable. We’ll discuss this feature in more detail in a future post.

    WebIDE gained support for Cordova-based projects. If you’re working on a mobile app project using Cordova, WebIDE now knows how to build the project for devices it supports without any extra configuration.

    Other Changes

    • Attribute changes only flash the changed attribute in the Markup View, instead of the whole element.
    • Canvas Debugger now supports setTimeout for animations.
    • Inline box model highlighting.
    • Browser Toolbox can now be opened from a shortcut: Cmd-Opt-Shift-I / Ctrl-Alt-Shift-I.
    • Network Monitor now shows the remote server’s IP address and port.
    • When an element’s highlighted in the Inspector, you can now use the arrow keys to highlight the current element’s parent (left key), or its first child, or its next sibling if it has no children, or the next node in the tree if it has no siblings (right key). This is especially useful when an element and its parent occupy the same space on the screen, making it difficult to select one of them using only the mouse.

    For an even more complete list, check out all 200 bugs resolved during the Firefox 39 development cycle.

    Thanks to all the new developers who made their first DevTools contribution this release:

    • Anush
    • Brandon Max
    • Geoffroy Planquart
    • Johan K. Jensen
    • John Giannakos
    • Mahdi Dibaiee
    • Nounours Heureux
    • Wickie Lee
    • Willian Gustavo Veiga

    Do you have feedback, bug reports, feature requests, or questions? As always, you can comment here, add/vote for ideas on UserVoice, or get in touch with the team at @FirefoxDevTools on Twitter.

  6. Understanding the CSS box model for inline elements

    In a web page, every element is rendered as a rectangular box. The box model describes how the element’s content, padding, border, and margin determine the space occupied by the element and its relation to other elements in the page.

    Depending on the element’s display property, its box may be one of two types: a block box or an inline box. The box model is applied differently to these two types. In this article we’ll see how the box model is applied to inline boxes, and how a new feature in the Firefox Developer Tools can help you visualize the box model for inline elements.

    Inline boxes and line boxes

    Inline boxes are laid out horizontally in a box called a line box:


    If there isn’t enough horizontal space to fit all elements into a single line, another line box is created under the first one. A single inline element may then be split across lines:


    The box model for inline boxes

    When an inline box is split across more than one line, it’s still logically a single box. This means that any horizontal padding, border, or margin is only applied to the start of the first line occupied by the box, and the end of the last line.

    For example, in the screenshot below, the highlighted span is split across 2 lines. Its horizontal padding doesn’t apply to the end of the first line or the beginning of the second line:


    Also, any vertical padding, border, or margin applied to an element will not push away elements above or below it:


    However, note that vertical padding and border are still applied, and the padding still pushes out the border:


    If you need to adjust the height between lines, use line-height instead.

    Inspecting inline elements with devtools

    When debugging layout issues, it’s important to have tools that give you the complete picture. One of these tools is the highlighter, which all browsers include in their devtools. You can use it to select elements for closer inspection, but it also gives you information about layout.


    In the example above, the highlighter in Firefox 39 is used to highlight an inline element split across several lines.

    The highlighter displays guides to help you align elements, gives the complete dimensions of the node, and displays an overlay showing the box model.

    From Firefox 39 onwards, the box model overlay for split inline elements shows each individual line occupied by the element. In this example the content region is displayed in light blue and is split over four lines. A right padding is also defined for the node, and the highlighter shows the padding region in purple.

    Highlighting each individual line box is important for understanding how the box model is applied to inline elements, and also helps you check the space between lines and the vertical alignment of inline boxes.


  7. Ruby support in Firefox Developer Edition 38

    It was a long-time request from East Asian users, especially Japanese users, to have ruby support in the browser.

    Formerly, because of the lack of native ruby support in Firefox, users had to install add-ons like HTML Ruby to make ruby work. However, in Firefox Developer Edition 38, CSS Ruby has been enabled by default, which also brings the support of HTML5 ruby tags.


    What is ruby? In short, ruby is an extra text, which is usually small, attached to the main text for indicating the pronunciation or meaning of the corresponding characters. This kind of annotation is widely used in Japanese publications. It is also common in Chinese for books for children, educational publications, and dictionaries.

    Ruby Annotation

    Basic Usage

    Basically, the ruby support consists of four main tags: <ruby>, <rb>, <rt>, and <rp>. <ruby> is the tag that wraps the whole ruby structure, <rb> is used to mark the text in the normal line, <rt> is for the annotation, and <rp> is a tag which is hidden by default. With the four tags, the result above can be achieved from the following code:


    Since <rb> and <rt> can be auto-closed by themselves, we don’t bother to add code to close those tags manually.

    As shown in the image, the duplicate parts as well as <rp>s are hidden automatically. But why should we add content which is hidden by default?

    The answer is: it is more natural in semantics, and it helps conversion to the inline form, which is a more general form accepted by more software. For example, this allows the page to have a decent effect on a browser with no ruby support. It also enables the user agent to generate well-formed plain text when you want to copy text with ruby (though this feature hasn’t yet been landed on Firefox).

    In addition, the extra content makes it possible to provide inline style of the annotation without changing the document. You would only need to add a rule to your stylesheet:

    ruby, rb, rt, rp {
      display: inline;
      font-size: inherit;

    Actually, if you don’t have those requirements, only <ruby> and <rt> are necessary. For simplest cases, e.g. a single ideographic character, you can use code like:


    Advanced Support

    Aside from the basic usage of ruby, Firefox now provides support for more advanced cases.

    By default, if the width of an annotation does not match its base text, the shorter text will be justified as shown in the example above. However, this behavior can be controlled via the ruby-align property. Aside from the default value (space-around), it can also make the content align to both sides (space-between), centered (center), or aligned to the start side (start).

    Multiple levels of annotations are also supported via tag <rtc> which is the container of <rt>s. Every <rtc> represents one level of annotation, but if you leave out the <rtc>, the browser will do some cleanup to wrap consecutive <rt>s in a single anonymous <rtc>, forming one level.

    For example, we can extend the example above to:


    If you do not put any <rt> inside a <rtc>, this annotation will become a span across the whole base:

      <rtc lang="en">A Certain Scientific Railgun</rtc><rp></rp>

    You can use ruby-position to place the given level of annotation on the side you want. For the examples above, if you want to put the second level under the main line, you can apply ruby-position: under; to the <rtc> tag. Currently, only under and the default value over is supported.

    (Note: The CSS Working Group is considering a change to the default value of ruby-position, so that annotations become double-sided by default. This change is likely to happen in a future version of Firefox.)

    In the end, an advanced example of ruby combining everything introduced above:

    Advanced Example for Ruby

    rtc:lang(en) {
      ruby-position: under;
      ruby-align: center;
      font-size: 75%;
      <rtc lang="en">A Certain Scientific Railgun</rtc><rp></rp>

    Got questions, comments, feedback on the implementation? Don’t hesitate to share your thoughts or issues here or via bugzilla.

  8. Introducing @counter-style


    The characters that indicate items in a list are called counters — they can be bullets or numbers. They are defined using the list-style-type CSS property. CSS1 introduced a list of predefined styles to be used as counter markers. The initial list was then slightly extended with addition of more predefined counter styles in CSS2.1. Even with 14 predefined counter styles, it still failed to address use cases from around the world.

    Now, the CSS Counter Styles Level 3 specification, which reached Candidate Recommendation last week, adds new predefined counter styles to the existing list that should address most common counter use cases.

    In addition to the new predefined styles, the spec also offers an open-ended solution for the needs of worldwide typography by introducing the @counter-style at-rule — which lets us define custom counter styles or even extend existing ones — and the symbols() function. The latter is a shorthand for defining inline styles and is useful when the fine-grained control that @counter-style offers is not needed.

    This article provides a guide to using the new counter features of CSS Level 3.


    A @counter-style at-rule is identified by a name and defined with a set of descriptors. It takes a numerical counter value and converts it into a string or image representation. A custom counter style definition looks like this:

    @counter-style blacknwhite {
      system: cyclic;
      negative: "(" ")";
      prefix: "/";
      symbols: ◆ ◇;
      suffix: "/ ";
      range: 2 4;
      speak-as: "bullets";

    The different available descriptors have the following meanings:

    1. system – the system descriptor lets the author specify an algorithm to convert the numerical counter value to a basic string representation. For example, the cyclic system cycles repeatedly through the list of symbols provided to create counter representations.
    2. negative – the negative descriptor provides the ability to specify additional symbols, such as a negative sign, to be appended/prepended to a counter representation if the counter value is negative. If only one symbol is specified, it will be added in front of the marker representation. A second value, if specified (as in the example below), will be added after the marker.
      @counter-style neg {
        system: numeric;
        symbols: "0" "1" "2" "3" "4" "5" "6" "7" "8" "9";
        negative: "(" ")";

      The above counter style definition will wrap negative markers in a pair of parentheses, instead of preceding them with the minus sign.

    3. prefix – specifies a symbol that will be prepended to the final counter representation.
    4. suffix – specifies a symbol that will be appended to the final counter representation.The default value of the suffix descriptor is a full stop followed by a space. If you need to replace the full stop “.” with a parenthesis, you can specify the suffix descriptor:
      @counter-style decimal-parenthesis {
        system: numeric;
        symbols: "0" "1" "2" "3" "4" "5" "6" "7" "8" "9";
        suffix: ") ";
    5. rangerange lets the author define a range of values over which a counter style is applicable. If a counter value falls outside the specified range, then the specified or default fallback style is used to represent that particular counter value, for example:
      @counter-style range-example {
        system: cyclic;
        symbols: A B C D;
        range:  4 8;

      The above rule will apply the style only for counter values starting from 4 to 8. The fallback style, decimal, will be used for the rest of the markers.

    6. pad – as the name suggests, the pad descriptor lets the author specify a padding length when the counter representations need to be of a minimum length. For example, if you want the counters to start at 01 and go through 02, 03, 04, etc., then the following pad descriptor should be used:
      @counter-style decimal-new {
        system: numeric;
        symbols: "0" "1" "2" "3" "4" "5" "6" "7" "8" "9";
        pad: 2 "0";

      (For a better way to achieve the same result, but without specifying the counter symbols, see the section below about extending existing systems.)

    7. fallback – the fallback specifies a style to fall back to if the specified system is unable to construct a counter representation or if a particular counter value falls outside the specified range.
    8. symbols and additive-symbols – specify the symbols that will be used to construct the counter representation. The symbols descriptor is used in most cases other than when the system specified is ‘additive.’ While symbols specifies individual symbols, the additive-symbols descriptor is composed of what are known as additive tuples – , which each consist of a symbol and a non-negative weight.Symbols specified can be strings, images in the form url(image-name) or identifiers. The below example uses images as symbols.
      @counter-style winners-list {
        system: fixed;
        symbols: url(gold-medal.svg) url(silver-medal.svg) url(bronze-medal.svg);
        suffix: " ";
    9. speak-as – specifies how a counter value should be spoken by speech synthesizers such as screen readers. For example, the author can specify a marker symbol to be read out as a word, a number, or as an audio cue for a bullet point. The example below reads out the counter values as numbers.
      @counter-style circled-digits {
        system: fixed;
        symbols: ➀ ➁ ➂;
        suffix: ' ';
        speak-as: numbers;

      You can then use a named style with list-style-type or with the counters() function as you normally would use a predefined counter style.

      ul {
        list-style-type: circled-digits;

      On a supported browser, the counter style above will render lists with markers like this:

      @counter-style demo image

    The system descriptor

    The system descriptor takes one of the predefined algorithms, which describe how to convert a numerical counter value to its representation. The system descriptor can have values that are cyclic, numeric, alphabetic, symbolic, additive, fixed and extends.

    If the system specified is cyclic, it will cycle through the list of symbols provided. Once the end of the list is reached, it will loop back to the beginning and start over. The fixed system is similar, but once the list of symbols is exhausted, it will resort to the fallback style to represent the rest of the markers. The symbolic, numeric and alphabetic systems are similar to the above two, but with their own subtle differences.

    The additive system requires that the additive-symbols descriptor be specified instead of the symbols descriptor. additive-symbols takes a list of additive tuples. Each additive tuple consists of a symbol and its numerical weight. The additive system is used to represent “sign-value” numbering systems such as the Roman numerals.

    We can rewrite the Roman numerals as a @counter-style rule using the additive system like this:

    @counter-style custom-roman {
      system: additive;
      range: 1 100;
      additive-symbols: 100 C, 90 XC, 50 L, 40 XL, 10 X, 9 IX, 5 V, 4 IV, 1 I;

    Extending existing or custom counter styles

    The extends system lets authors create custom counter styles based on existing ones. Authors can use the algorithm of another counter style, but alter its other aspects. If a @counter-style rule using the extends system has any unspecified descriptors, their values will be taken from the extended counter style specified.

    For example, if you want to define a new style which is similar to decimal, but has a string “Chapter ” in front of all the marker values, then rather than creating an entirely new style you can use the extends system to extend the  decimal style like this:

    @counter-style chapters {
      system: extends decimal;
      prefix: 'Chapter ';

    Or, if you need the decimal style to start numbers from 01, 02, 03.. instead of 1, 2, 3.., you can simply specify the pad descriptor:

    @counter-style decimal-new {
      system: extends decimal;
      pad: 2 "0";

    A counter style using the extends system should not specify the symbols and additive-symbols descriptors.

    See the reference page on MDN for details and usage examples of all system values.

    A shorthand – The symbols() function

    While a @counter-style at-rule lets you tailor a custom counter style, often such elaborate control is not needed. That is where the symbols() function comes in. symbols() lets you define inline counter styles as function properties. Since the counter styles defined in this way are nameless (anonymous), they can not be reused elsewhere in the stylesheet.

    An example anonymous counter style looks like this:

    ul {
        list-style-type: symbols(fixed url(one.svg) url(two.svg));

    Even more predefined counter styles

    CSS Lists 3 vastly extends the number of predefined styles available. Along with the predefined styles such as decimal, disc, circle and square that existed before, additional styles such as hebrew, thai, gujarati, disclosure-open/close, etc. are also added to the predefined list. The full list of predefined styles enabled by the spec can be seen here.

    Browser support

    Support for @counter-style and the symbols() function along with the new predefined styles landed in Firefox 33. Google Chrome hasn’t implemented @counter-styles or the symbols() function yet, but most of the new numeric and alphabetic predefined styles have been implemented. There is no support in IE so far. Support has already landed in the latest releases of Firefox for Android and in the upcoming Firefox OS 2.1, which has support for @counter-style. Support for symbols() will land in Firefox OS 2.2.


    Check out this demo page and see if @counter-style is supported in your favorite browsers.

  9. Exploring object-fit

    On web documents, a common problem concerns the display of different sized images (or videos) in the same place. Perhaps you are writing a dynamic gallery app that accepts user submissions. You can’t guarantee that everyone will upload images of exactly the same aspect ratio, so what do you do?

    Letting the aspect ratio distort to fit the containing replaced element nearly always looks horrible. And doing some kind of dynamic cropping or resizing on the fly each time might be more work than you have the capability to implement. (For instance, maybe you’re working on a CMS and don’t have permission to edit anything except the page content.)

    The CSS Image Values and Replaced Content module provides properties called object-fit — which solves such problems, and object-position — which sets the horizontal and vertical position of the content inside the element.

    These elements have decent support across modern browsers (with the exception of IE). In this article we’ll look at a few examples of how they can be used.

    Note: object-fit works with SVG content, but the same effect can also be achieved by setting the preserveAspectRatio="" attribute in the SVG itself.

    How do object-fit and object-position work?

    You can successfully apply object-fit to any replaced element, for example:

    img {
      height: 100px;
      width: 100px;
      object-fit: contain;

    The five possible values of object-fit are as follows:

    1. contain: The content (e.g. the image) will be resized so that it is fully displayed with intrinsic aspect ratio preserved, but still fits inside the dimensions set for the element.
    2. fill: The content will expand to exactly fill the dimensions set for the element, even if this does break its aspect ratio.
    3. cover: Preserves the aspect ratio of the content, but alters the width and height so that the content completely covers the element. The smaller of the two is made to fit the element exactly, and the larger overflows the element and is cropped.
    4. none: Completely ignores any height or weight set on the element, and just uses the replaced element content’s intrinsic dimensions.
    5. scale-down: The content is sized as if none or contain were specified, whichever would result in a smaller replaced element size.

    object-position works in exactly the same way as background-position does for background images; for example:

    img {
      height: 100px;
      width: 100px;
      object-fit: contain;
      object-position: top 70px;

    Percentages work, but they’re actually resolved against the excess available space — the difference between the element’s width & the replaced content’s final rendered width. So object-position: 50% 50% (the default value) will always exactly center the replaced element. Furthermore, object-position: 0% 0% always means align with top-left corner, object-position: 100% 100% *always* means align with bottom-right corner, etc.

    The keywords top, center, right, etc. are really just handy aliases for 0%, 50%, 100%, etc.

    Note: You can see some object position examples in our basic example page.

    The effects of the different object-fit values

    The following code examples show the effects of the different object-fit values.

    Letterboxing images with object-fit: contain

    Sometimes referred to as letter-boxing, there are times when you will want to preserve the aspect ratio of the images on a page, but get them to fit inside the same area. For example, you might have a content management system that allows you to upload products on an e-commerce site or images for an image gallery, with lots of different content authors. They may upload images in roughly the right size, but the dimensions are not always exact, and you want to fit each image into the same amount of space.

    Having images with the aspect ratio shifted usually looks horrible, so you can letterbox them instead with object-fit: contain (object-fit: contain example):

    img {
      width: 480px;
      height: 320px;
      background: black;
    .contain {
    	object-fit: contain;

    Cropping images with object-fit:cover

    A different solution is to maintain aspect ratio, but crop each image to the same size so it completely envelops the <img> element, with any overflow being hidden. This can be done easily with object-fit:cover (object-fit: cover example):

    .cover {
      object-fit: cover;

    Overriding a video’s aspect ratio with object-fit: fill

    Going in the opposite direction, it is also possible to take a video and force it to change aspect ratio. Maybe some of your content editor’s videos have a broken aspect ratio, and you want to fix them all on the fly, in one easy fell swoop?

    Take the following video image:

    a video with a broken aspect ratioIf we embedded it into a page with this:

    <video controls="controls" src="windowsill.webm"
        width="426" height="240">

    It would look terrible: the video would appear letter-boxed, since the <video> element always tries to maintain the source file’s intrinsic aspect ratio. We could fix this by applying object-fit: fill (object-fit: fill example):

    .fill {
      object-fit: fill;

    This overrides the video’s intrinsic aspect ratio, forcing it to completely fill the <video> element so it displays correctly.

    Interesting transition effects

    Combining object-fit and object-position with CSS transitions can lead to some pretty interesting effects for image or video galleries. For example:

    .none {
      width: 200px;
      height: 200px;
      overflow: hidden;
      object-fit: none;
      object-position: 25% 50%;
      transition: 1s width, 1s height;
    .none:hover, .none:focus {
    	height: 350px;
    	width: 350px;

    Only a small part of the image is shown, and the element grows to reveal more of the image when it is focused/hovered (object-fit: none example).

    This is because by setting object-fit: none on the <img>, we cause the content to completely ignore any width and height set earlier, and spill out of the sides of the element. We then use overflow: hidden to crop anything that spills out. A transition is then used to smoothly increase the size of the <img> element when it’s hovered/focused, which reveals more of the image.

    Gallery example

    To show a slightly more applied usage of object-fit, we have created a gallery example:

    an image gallery showing sixteen pictures in a four by four grid

    an image gallery showing one large image

    The 16 images are loaded via XHR, and inserted into the images as ObjectURLs.

    for(i = 1; i <= thumbs.length ; i++) {
      var requestObj = 'images/pic' + i + '.jpg';
    function retrieveImage(requestObj,imageNo) {
      var request = new XMLHttpRequest();'GET', requestObj, true);
      request.responseType = 'blob';
      request.onload = function() {
        var objectURL = URL.createObjectURL(request.response);
        thumbs[imageNo].onclick = function() {

    Each image in turn is given an onclick handler so that when clicked the images appear full size, filling the screen (the main image, initially set to display: none; in the CSS is given a class of blowup, which makes it display and fill the whole screen; the main image’s src is then set to the same object URL as the thumb that was clicked).

    thumbs[imageNo].onclick = function() {
      mainImg.className = 'blowup';
      for(i = 0; i < thumbs.length; i++) {
        thumbs[i].className = 'thumb darken';

    Clicking a full size image makes it disappear again.

    mainImg.onclick = function() {
      mainImg.className = 'main';
      for(i = 0; i < thumbs.length; i++) {
        thumbs[i].className = 'thumb';

    All the sizing is done with percentages so that the grid remains in proportion whatever the screen size.

    body > div {
      height: 25%;
    .thumb {
      float: left;
      width: 25%;
      height: 100%;
      object-fit: cover;

    Note: the thumbnails have all been given tabindex="0" to make them focusable by tabbing (you can make anything appear in the page’s tab order by setting on tabindex="0" on it), and the onclick handler that makes the full size images appear has been doubled up with an onfocus handler to provide basic keyboard accessibility:

    thumbs[imageNo].onfocus = function() {
      mainImg.className = 'blowup';
      for(i = 0; i < thumbs.length; i++) {
        thumbs[i].className = 'thumb darken';

    The clever parts come with the usage of object-fit:

    1. The thumbnails: These have object-fit: cover set on them so that all image thumbs will appear at the same size, at the proper aspect ratio, but cropped different amounts. This looks pretty decent, and creates a nice effect when you resize the window.
    2. The main image: This has object-fit: contain and object-position: center set on it, so that it will appear in full, at the correct aspect ratio and as big as it can be.
  10. Pseudo elements, promise inspection, raw headers, and much more – Firefox Developer Edition 36

    Firefox 36 was just uplifted to the Developer Edition channel, so let’s take a look at the most important Developer Tools changes in this release. We will also cover some changes from Firefox 35 since it was released shortly before the initial Developer Edition announcement. There is a lot to talk about, so let’s get right to it.


    You can now inspect ::before and ::after pseudo elements.  They behave like other elements in the markup tree and inspector sidebars. (35, development notes)


    There is a new “Show DOM Properties” context menu item in the markup tree. (35, development notes, documentation about this feature on MDN)


    The box model highlighter now works on remote targets, so there is a full-featured highlighter even when working with pages on Firefox for Android or apps on Firefox OS. (36, development notes, and technical documentation for building your own custom highlighter)

    Shadow DOM content is now visible in the markup tree; note that you will need to set dom.webcomponents.enabled to true to test this feature (36, development notes, and see bug 1053898 for more work in this space).

    We borrowed a useful feature from Firebug and are now allowing more paste options when right clicking a node in the markup tree.  (36, development notes, documentation about this feature on MDN)


    Some more changes to the Inspector included in Firefox 35 & 36:

    • Deleting a node now selects the previous sibling instead of the parent (36, development notes)
    • There is higher contrast for the currently hovered node in the markup view (36, development notes)
    • Hover over a CSS selector in the computed view to highlight all the nodes that match that selector on the page. (35, development notes)

    Debugger / Console

    DOM Promises are now inspectable. You can inspect the promises state and value at any moment. (36, development notes)


    The debugger now recognizes and works with eval’ed sources. (36, development notes)

    Eval’ed sources support the //# sourceURL=path.js syntax, which will make them appear as a normal file in the debugger and in stack traces reported by Error.prototype.stack. See this post: for much more information. (36, development notes,  more development notes)

    Console statements now include the column number they originated from. (36, development notes)


    You are now able to connect to Firefox for Android from the WebIDE.  See documentation for debugging firefox for android on MDN.  (36, development notes).

    We also made some changes to improve the user experience in the WebIDE:

    • Bring up developer tools by default when I select a runtime app / tab (35, development notes)
    • Re-select project on connect if last project is runtime app (35, development notes)
    • Auto-select and connect to last used runtime if available (35, development notes)
    • Font resizing (36, development notes)
    • You can now adding a hosted app project by entering the base URL (eg: “”) instead of requiring the full path to the manifest.webapp file (35, development notes)

    Network Monitor

    We added a plain request/response headers view to make it easier to view and copy the raw headers on a request. (35, development notes)


    Here is a list of all the bugs resolved for Firefox 35 and all the bugs resolved for Firefox 36.

    Do you have feedback, bug reports, feature requests, or questions? As always, you can comment here, add/vote for ideas on UserVoice or get in touch with the team at @FirefoxDevTools on Twitter.