Mozilla

CSS Articles

Sort by:

View:

  1. 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 bloomberg.com'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 css-tricks.com 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.

  2. 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!

    Inspector

    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.

    cubic

    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.

    Console

    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.

    pseudo-array

    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.

  3. 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:

    2-inline-boxes

    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:

    line-boxes

    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:

    horizontal-padding

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

    vertical-padding

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

    vertical-border-padding

    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.

    layout-info

    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.

     

  4. 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.

    Introduction

    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:

    <ruby>
      <rb>とある<rb>科学<rb><rb>超電磁砲</rb>
      <rp></rp><rt>とある<rt>かがく<rt><rt>レールガン</rt><rp></rp>
    </ruby>

    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:

    <ruby><rt>Saki</rt></ruby>

    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:

    <ruby>
      <rb>とある<rb>科学<rb><rb>超電磁砲</rb>
      <rp></rp><rt>とある<rt>かがく<rt><rt>レールガン</rt><rp></rp>
      <rtc><rt>Toaru<rt>Kagaku<rt>no<rt>Rērugan</rt></rtc><rp></rp>
    </ruby>

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

    <ruby>
      <rb>とある<rb>科学<rb><rb>超電磁砲</rb>
      <rp></rp><rt>とある<rt>かがく<rt><rt>レールガン</rt><rp></rp>
      <rtc lang="en">A Certain Scientific Railgun</rtc><rp></rp>
    </ruby>

    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%;
    }
    <ruby>
      <rb>とある<rb>科学<rb><rb>超電磁砲</rb>
      <rp></rp><rt>とある<rt>かがく<rt><rt>レールガン</rt><rp></rp>
      <rtc lang="en">A Certain Scientific Railgun</rtc><rp></rp>
    </ruby>

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

  5. Introducing @counter-style

    Introduction

    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.

    @counter-style

    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.

    Examples

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

  6. 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">
      …
    </video>

    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';
      retrieveImage(requestObj,i-1);
    }
     
    function retrieveImage(requestObj,imageNo) {
      var request = new XMLHttpRequest();
      request.open('GET', requestObj, true);
      request.responseType = 'blob';
     
      request.onload = function() {
        var objectURL = URL.createObjectURL(request.response);
        thumbs[imageNo].setAttribute('src',objectURL);
        thumbs[imageNo].onclick = function() {
          ...
        }
      }
     
      request.send();
    }

    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.setAttribute('src',objectURL);
      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.setAttribute('src',objectURL);
      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.
  7. 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.

    Inspector

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

    before-after-inspection

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

    show-dom-properties

    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)

    paste-options

    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)

    promise-inspection

    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: http://fitzgeraldnick.com/weblog/59/ for much more information. (36, development notes,  more development notes)

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

    WebIDE

    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: “http://example.com”) 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)

    net-headers-raw

    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.

  8. WebIDE, Storage inspector, jQuery events, iframe switcher + more – Firefox Developer Tools Episode 34

    A new set of Firefox Developer Tools features has just been uplifted to the Aurora channel. These features are available right now in Aurora, and will be in the Firefox 34 release in November. This release brings new tools (storage inspector, WebIDE), an updated profiler, and handy enhancements to the existing tools:

    WebIDE

    WebIDE, a new tool for in-browser app development, has been enabled by default in this release. WebIDE lets you create a new Firefox OS app (which is just a web app) from a template, or open up the code for an already created app. From there you can edit the app’s files. It’s one click to run the app in a simulator and one more to debug it with the developer tools. Open WebIDE from Firefox’s “Web Developer” menu. (docs)

    Storage inspector

    There’s a new panel that shows the data your page has stored in cookies, localStorage, sessionStorage, and IndexedDB, which was created mostly by Girish Shama. Enable the Storage panel by checking off Settings > “Default Developer Tools” > “Storage”. The panel is read-only right now, with editing ability planned for a future release. (docs) (development notes) (UserVoice request)

    storage inspector

    jQuery events

    The event listener popup in the Inspector now supports jQuery. This means the popup will display the function you attached with e.g. jQuery.on(), and not the jQuery wrapper function itself. See this post for more info and how to add support for your preferred framework. (development notes)

    JQuery events

    Iframe switcher

    Change the frame you’re debugging using the new frame selection menu. Selecting a frame will switch all of the tools to debug that iframe, including the Inspector, Console, and Debugger. Add the frame selection button by checking off Settings > “Available Toolbox Buttons” > “Select an iframe”. (docs) (development notes)(UserVoice request)

    iframe selection

    Updated profiler

    An updated JavaScript profiler appears in the new “Performance” tab (formerly the “Profiler” tab). New to the profiler are a frame rate timeline and categories for frames like “network” and “graphics”. (docs) (development notes)

    new profiler

    console.table()

    Add a call to console.table() anywhere in your JavaScript to log data to the console using a table-like display. Log any object, array, Map, or Set. Sort a column in the table by clicking on its header. (docs) (development notes)

    console.table

    Selector preview

    Hover over a CSS selector in the Inspector or Style Editor to highlight all the nodes that match that selector on the page. (development notes)

    selector previews

    Other mentions

    • Persistent split console – The split console (opened by pressing ESC) will now open with the tools if you had it open the last time the tools were closed. (development notes)
    • Web audio – AudioParam connections – the Web Audio Editor now displays connections from AudioNodes to AudioParams. (development notes)

    Special thanks to the 41 contributors that added all the features and fixes in this release.

    Comment here, shoot feedback to @FirefoxDevTools on Twitter, or propose changes on the Developer Tools feedback channel. If you’d like to help out, check out the guide to getting involved.

  9. Single Div Drawings with CSS

    Why A Single Div?

    In May of 2013 I attended CSSConf and saw Lea Verou speak about the humble border-radius. It was an eye-opening talk and I realized there was much about CSS behavior I did not fully understand. This reminded me of my time as a fine arts student where I was constantly pushed to become a master of my chosen medium. As a web designer, CSS is my medium and so I challenged myself to learn all I could about it and to explore and experiment with its limits.

    But why a single div?

    When I was learning to paint, my class did these color mixing exercises where we created the many colors of the spectrum from only the three primary colors: red, yellow, and blue. The purpose of the exercise is to learn the behavior of the medium and the constraints show us the power of combination. You can certainly buy green paint, but you can also create green from blue and yellow. Restricting your available options forces you to re-evaluate the tools you already have.

    I decided to start a CSS drawing project, every few days illustrating something new with only CSS. To further challenge and explore what CSS is capable of, I gave myself the constraint of using only a single div in the markup. Instead of buying green paint (or adding another div), I’d need to stretch and combine CSS properties to achieve my goals.

    The Toolkit

    With only a single div and browser-supported CSS properties, it may seem like the tools are too limited. I found it’s not always what you have to work with, but how you look at them.

    Pseudo elements

    With one div in the HTML, I actually have three elements to work with because of CSS pseudo classes. So with div, div:before, and div:after, we can get something like this:

    pseudo elements

      div { background: red; }
      div:before { background: yellow; }
      div:after { background: blue; }

    It helps to think about these three elements as things that can come in sequence and as three stackable layers. So in my mind, it would usually look more like this:

    pseudo elements as layers

    Shapes

    With CSS and one element, we are afforded three basic shape types. We can use width and height properties to create squares/rectangles, border-radius to create circles/ellipses, and border to create triangles/trapezoids.

    css shapes

    There are others we can create with CSS, but most things can be simplified to some combination of these shapes. And these are the easiest to create and manipulate.

    Multiples of the same shape

    With multiple box-shadows, we can create many versions of the same shape in varying size, color, and blur. Offsetting them on the x- and y-axes gives us almost endless multiples.

    multiple box-shadows

    div {
        box-shadow: 170px 0 10px yellow,
                    330px 0 0 -20px blue,
                    330px 5px 5px -20px black;
    }

    We can even give our box-shadows box-shadows. Pay attention to the order they are declared. Again, It’s helpful to think of them as layers.

    Gradients

    Gradients can be used to add shading and depth by implying a light source. This makes the simple, flat shapes feel more realistic. Combining multiple background-images allows us to use many, layered gradients to achieve more complex shading and even more shapes.

    gradients

    div {
        background-image: linear-gradient(to right, gray, white, gray, black);
    }
     
    div:after {
        background-image: radial-gradient(circle, yellow 50%, transparent 50%),
                          linear-gradient(to right, blue, red);
    }

    Visualizing

    The most difficult part is visualizing how to piece these parts into a whole recognizable drawing. As much as I focus on the technical aspects of the drawings, this part of the process is critical. To help with this, I’ll often look at a photograph of the subject and break it up visually into pieces. Everything is a shape and everything is a color. I simplify the overall picture into smaller shapes or blocks of color I know can (or suspect can) be achieved with CSS.

    Demos

    Let’s take a closer look at two drawings and break down some of the pieces that make up the larger pictures. First up is the green crayon.

    A crayon is made up of two primary shapes: the rectangular body and the triangular drawing tip.

    crayon shapes

    I had to guarantee the following things to capture a realistic image:

    • the different color of the paper wrapper
    • the printed graphics and words on the wrapper
    • the shading that shows the roundness of the crayon
    • the glossiness that shows roundness and a light source

    So first, I created the main body of the crayon with the div and a background color, top-to-bottom gradient, and box-shadow to show some dimension:

    crayon body

    (Note, I’m using a mixin of black(a) and white(a) here in place of rgba)

    div {
        background: #237449;
        background-image: linear-gradient(to bottom,
                                      transparent 62%,
                                      black(.3) 100%);
        box-shadow: 2px 2px 3px black(.3);
    }

    Then I added a left-to-right linear-gradient to create the wrapper. It has an alpha value of .6 so some of that previous gradient shows through.

    crayon wrapper

    div {
        background-image: linear-gradient(to right,
                                      transparent 12px,
                                      rgba(41,237,133,.6) 12px,
                                      rgba(41,237,133,.6) 235px,
                                      transparent 235px);
    }

    Next I used the same left-to-right gradient technique to create the printed stripes on the crayon.

    crayon printing

    div {
        background-image: linear-gradient(to right,
                                      transparent 25px,
                                      black(.6) 25px,
                                      black(.6) 30px,
                                      transparent 30px,
                                      transparent 35px,
                                      black(.6) 35px,
                                      black(.6) 40px,
                                      transparent 40px,
                                      transparent 210px,
                                      black(.6) 210px,
                                      black(.6) 215px,
                                      transparent 215px,
                                      transparent 220px,
                                      black(.6) 220px,
                                      black(.6) 225px,
                                      transparent 225px);
    }

    And for the printed ellipse, a radial-gradient works great!

    crayon printing

    div {
        background-image: radial-gradient(ellipse at top,
                                      black(.6) 50px,
                                      transparent 54px);
    }

    I have it broken up to demonstrate each piece, but keep in mind the background-image would actually look like this:

    div {
                          // ellipse printed on wrapper
        background-image: radial-gradient(ellipse at top,
                                      black(.6) 50px,
                                      transparent 54px),
                          // printed stripes
                          linear-gradient(to right,
                                      transparent 25px,
                                      black(.6) 25px,
                                      black(.6) 30px,
                                      transparent 30px,
                                      transparent 35px,
                                      black(.6) 35px,
                                      black(.6) 40px,
                                      transparent 40px,
                                      transparent 210px,
                                      black(.6) 210px,
                                      black(.6) 215px,
                                      transparent 215px,
                                      transparent 220px,
                                      black(.6) 220px,
                                      black(.6) 225px,
                                      transparent 225px),
                          // wrapper
                          linear-gradient(to right,
                                      transparent 12px,
                                      rgba(41,237,133,.6) 12px,
                                      rgba(41,237,133,.6) 235px,
                                      transparent 235px),
                          // crayon body shading
                          linear-gradient(to bottom,
                                      transparent 62%,
                                      black(.3) 100%)
    }

    So after completing the div, I moved on to the :before pseudo element to create the crayon’s triangular tip. Using solid and transparent borders, I made a triangle and positioned it next to the div I just drew.

    triangle crayon tip

    div:before {
        height: 10px;
        border-right: 48px solid #237449;
        border-bottom: 13px solid transparent;
        border-top: 13px solid transparent;
    }

    It looks a little flat next to the crayon’s body, but it will be fixed with the :after pseudo element. With this, I added a top-to-bottom linear-gradient to create a reflective gloss effect that spans the width of the crayon.

    crayon gloss

    div:after {
        background-image: linear-gradient(to bottom,
                                        white(0) 12px,
                                        white(.2) 17px,
                                        white(.2) 19px,
                                        white(0) 24px);
    }

    This adds even more dimension and realism and helps with that flat triangle. As a finishing touch, I added some text content to the :after and positioned it as another printed element on the crayon’s wrapper.

    crayon color label

    div:after {
        content: 'green';
        font-family: Arial, sans-serif;
        font-size: 12px;
        font-weight: bold;
        color: black(.3);
        text-align: right;
        padding-right: 47px;
        padding-top: 17px;
    }

    And that’s it!

    Let’s take a look at another one

    The crayon is a good example of using background-image and gradients to produce realistic results. Here’s an example that shows the power of multiple box-shadows: a single div camera.

    Here’s the body of the camera, created with background-image and border-image.

    camera body

    Here’s a gif illustrating the :before pseudo element (the black rectangle) and the many details created with its box-shadows.

    camera rectangle

    div:before {
        background: #333;
        box-shadow: 0 0 0 2px #eee,
                    -1px -1px 1px 3px #333,
                    -95px 6px 0 0 #ccc,
                    30px 3px 0 12px #ccc,
                    -18px 37px 0 46px #ccc,
     
                    -96px -6px 0 -6px #555,
                    -96px -9px 0 -6px #ddd,
     
                    -155px -10px 1px 3px #888,
                    -165px -10px 1px 3px #999,
                    -170px -10px 1px 3px #666,
                    -162px -8px 0 5px #555,
     
                    85px -4px 1px -3px #ccc,
                    79px -4px 1px -3px #888,
                    82px 1px 0 -4px #555;
    }

    Similarly, here’s the :after (the grey circle) and its several box-shadow details.

    camera circle

    div:after {
        background: linear-gradient(45deg, #ccc 40%, #ddd 100%);
        border-radius: 50%;
        box-shadow: 0 3px 2px #999,
                    1px -2px 0 white,
                    -1px -3px 2px #555,
                    0 0 0 15px #c2c2c2,
                    0 -2px 0 15px white,
                    -2px -5px 1px 17px #666,
                    0 10px 10px 15px black(.3),
     
                    -90px -51px 1px -43px #aaa,
                    -90px -50px 1px -40px #888,
                    -90px -51px 0 -34px #ccc,
                    -90px -50px 0 -30px #aaa,
                    -90px -48px 1px -28px black(.2),
     
                    -124px -73px 1px -48px #eee,
                    -125px -72px 0 -46px #666,
                    -85px -73px 1px -48px #eee,
                    -86px -72px 0 -46px #666,
                    42px -82px 1px -48px #eee,
                    41px -81px 0 -46px #777,
                    67px -73px 1px -48px #eee,
                    66px -72px 0 -46px #666,
     
                    -46px -86px 1px -45px #444,
                    -44px -87px 0 -38px #333,
                    -44px -86px 0 -37px #ccc,
                    -44px -85px 0 -34px #999,
     
                    14px -89px 1px -48px #eee,
                    12px -84px 1px -48px #999,
                    23px -85px 0 -47px #444,
                    23px -87px 0 -46px #888;
    }

    A little crazy, but as you can see, multiple box-shadows can add a lot of detail to a single div drawing.

    Biggest challenges

    Two of the biggest obstacles I came across were limitations around triangle shapes and the natural behavior of gradients.

    The trouble with triangles

    Because triangles are created using borders, it limits how much I can do with them. Adding gradients with border-image apply to all the borders, not just one side. Box-shadows apply to the shape of the box, not the triangle shape the border creates, so creating multiple triangle shapes can be difficult. Here’s an example of what that looks like:

    trouble with triangles

    div {
        border-left: 80px solid transparent;
        border-right: 80px solid transparent;
        border-bottom: 80px solid red;
    }
     
    div:before {
        border-left: 80px solid transparent;
        border-right: 80px solid transparent;
        border-bottom: 80px solid red;
        border-image: linear-gradient(to right, red, blue);
    }
     
    div:after {
        border-left: 80px solid transparent;
        border-right: 80px solid transparent;
        border-bottom: 80px solid red;
        box-shadow: 5px 5px 5px gray;
    }

    Layering gradients

    With gradients, their natural behavior is to fill the entire background. This can get a little tricky when layering multiple gradients on top of each other. It takes some extra time to think through transparency, z-index, and understanding what will and won’t be visible. By using this technique effectively, our drawings can have surprising detail.

    The Tardis is a good example of showing and hiding gradients to create a detailed picture. Here’s the drawing mid-process that shows some of the top-to-bottom gradients that span the entire width of the container.

    single div tardis in-process

    Using left-to-right and right-to-left gradients, I was able to cover parts of the gradient and leave some parts exposed.

    single div tardis in-process

    The resulting drawing appears to have many shapes making up the front facade of the Tardis, but it’s strategically layered linear-gradients. Sometimes you have to fake it.

    See them in action

    One awesome thing that popped up because of this project is a really cool and useful Chrome browser extension by Rafael Carício called CSS Gradient Inspector. It extends the developer tools to inspect and toggle on/off each element’s gradients as if they were layers. (It’s very helpful with everyday projects, too.)

    I’m super excited to see designers and developers experimenting and riffing on these drawings with animations and JavaScript functionality. Check out the site and play around with the CSS yourself at a.singlediv.com or on GitHub!

  10. Live Editing Sass and Less in the Firefox Developer Tools

    Sass and Less are expressive languages that compile into CSS. If you’re using Sass or Less to generate your CSS, you might want to debug the source that you authored and not the generated CSS. Luckily you can now do this in the Firefox 29 developer tools using source maps.

    The Firefox developer tools use source maps to show the line number of rules in the original source, and let you edit original sources in the Style Editor. Here’s how to use the feature:

    1. Generate the source map

    When compiling a source to CSS, use the option to generate a sourcemap for each style sheet. To do this you’ll need Sass 3.3+ or Less 1.5+.

    Sass

    sass index.scss:index.css --sourcemap

    Less

    lessc index.less index.css --source-map

    This will create a .css.map source map file for each CSS file, and add a comment to the end of your CSS file with the location of the sourcemap: /*# sourceMappingURL=index.css.map */. The devtools will use this source map to map locations in the CSS style sheet to locations in the original source.

    2. Enable source maps in developer tools

    Right-click anywhere on the inspector’s rule view or in the Style Editor to get a context menu. Check off the Show original sources option:

    Enabling source maps in devtools

    Now CSS rule links will show the location in the original file, and clicking these links will take you to the source in the Style Editor:

    Original source showing in Style Editor

    3. Set up file watching

    You can edit original source files in Style Editor tool, but order to see the changes apply to the page, you’ll have to watch for changes to your preprocessed source and regenerate the CSS file each time it changes. To set watching up:

    Sass

    sass index.scss:index.css --sourcemap --watch

    Less

    For Less, you’ll have to set up another service to do the watching, like grunt.

    4. Save the original source

    Save the original source to your local file system by hitting the Save link or Cmd/Ctrl-S:

    Saving source to disk

    Saving source to disk

    The devtools will infer the location of the generated CSS file locally and watch that file for changes to update the live style sheet on the page.

    Now when you edit an original source and save it, the page’s style will update and you’ll get immediate feedback on your Sass or Less changes.

    The source has to be saved to disk and file watching set up in order for style changes to take effect.