Mark Otto "derping around with measuring CSS performance". Nothing looks particularly concerning to me, to the point where I would change how I do things. The most surprising numbers were in background vs background-color, but Paul Irish debunks that a bit.
There must be something in the water as Ben Frain has dug in a little bit on CSS performance as well. I like Ben's soundbite:
With CSS, architecture is outside the braces; performance is inside
It's worth noting that the srcset attribute for the img element has landed in Chrome (still one version upstream from stable at this second). Their example: <img alt="A rad wolf." src="pic1x.jpg" srcset="pic1x.jpg 1x, pic2x.jpg 2x, pic4x.jpg 4x"> And:
Stay tuned for the element
We needed this. The fight was arduous. The solution is good. Other browsers will be on the way. This is notable as once a browser supports something, the tendency is for it to always be supported. Plus now polyfills can be true polyfills.
Bennett Feely has been doing a good job of showing people the glory of CSS blend modes. There are lots of designerly effects that we're used to seeing in static designs (thanks to Photoshop) that we don't see on the web much, with dynamic content. But that will change as CSS blend modes get more support. I'd like to look at the different ways of doing it, since it's not exactly cut and dry.
CSS Multiple Backgrounds Blend Modes
You can blend background-images together, or blend them with background-color. It's a simple as:
Multiply is a nice and useful one, but there is also: screen, overlay, darken, lighten, color-dodge, color-burn, hard-light, soft-light, difference, exclusion, hue, saturation, color, and luminosity. And also normal which reset it.
Adobe (who works on the spec for this stuff, of course) created this Pen for playing with the different possiblities here:
Here's another, which cleverly re-combines a color image separated into Cyan / Magenta / Yellow / Black parts (CMYK). You know that's how offset lithography works in print, right? =)
Blending backgrounds together is pretty cool, but personally I'm less excited about that than I am about blending arbitrary HTML elements together. Like a <h1> title over a background, for example. Or even text over text.
I saw this at an airport the other day and snapped a pic because I thought it looked neat and figured I could figure out how to do it on the web:
My first attempt to recreate it, I used opacity. But opacity really dulls the colors and doesn't make those overlapping bits have the extra darkness they should have. CJ Gammon showed me there is a blending property precicely for this purpose: mix-blend-mode.
The DOM blend mode stuff is most interesting to me, but it should be noted that <canvas> has blend modes as well and it has a bit deeper support (see below for all that).
You set it on the canvas context. So like:
var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d');
ctx.globalCompositeOperation = 'multiply';
That value can be any of those I listed above. Here's a simple demo:
As you might suspect, SVG does have its own mechanism for doing this. One way to do it is to define it within the <svg> itself, and it's fairly complicated:
The good news is that mix-blend-mode will work on inline SVG. So if you're using SVG that way, you can target the shapes themselves with classes or whatever and give them whatever blend mode you want.
For canvas: Firefox 20+, Chrome 30+, Safari 6.1+, Opera 17+, iOS 7+, Android 4.4+. Worst bad news: No IE.
For HTML/CSS: Firefox 30+, Chrome 35+, Safari 6.1 (apparently not 7?). Not quite as supported as canvas.
At this second, for Chrome, you'll have to run Canary, go to chrome://flags/ and enable "experimental Web Platform features".
This actually it a bit more complicated, so if you really want to dig in and know about support, check out the Support Matrix from Adobe.
Progressive Enhancement
What is nice about blending is that the whole point is designerly effects. If they aren't supported, you can take care to make sure the fallback is still readable. E.g. the whole idea of progressive enhancement.
It is entirely possible—nay, desirable—to use features long before they are supported in every browser. That’s how we move the web forward.
So one way to do support is to look at the design in a non-supporting browser and if it is still readable/usable, you're good, no further action required.
If the result ends up unreadable/unusable, you could tweak things around until they are, or run a test to determine support and do something specific in the case of non-support.
To test for support, I guess you could do test for the property you want to use:
var supportsMixBlendMode = window.getComputedStyle(document.body).mixBlendMode;
var supportsBackgroundBlendMode = window.getComputedStyle(document.body).backgroundBlendMode;
If the returned value is "normal" (or anything other than undefined) support is there, otherwise not. Then probably apply a class to the <html> element so you can know that and use it anywhere in your CSS to adjust things, Modernizr style. Perhaps they'll even do a test for it in the future.
Unless it's not that simple in which case let me know.
While em is relative to the font-size of its direct or nearest parent, rem is only relative to the html (root) font-size.
Jeremy tends to favor em, because of the ability to control an area of a design. As in, scale the type in that specific area relatively. I have tended to like rem because of the ability to scale type across the entire page easily, but I've gotten into issues where that wasn't good enough control so I could see moving back to em for that reason.
You've probably seen this pattern going around. It's an input that appears as if it has placeholder text in it, but when you click/tap into that input, that text moves out of the way and allows you to type there. It's rather clever, I think. Brad Frost has a really good post on it, detailing the pros and cons and such.
Many of the demos I've seen involve JavaScript. The other day I was checking out at Nest.com, saw their technique for it, and I thought of a way I could pull that off without JavaScript. So here we are.
It's not quite as sexy as the Nest ones, were the text is fading out as the label is sliding up. Certainly possible with some JavaScript, but we're going to stick with pure CSS here. Still might be possible though. I'll leave that challenge up to you.
Some Quick Reminders
There are two reasons you might consider doing this:
It might be able to save space. Because the input and label are combined, it takes up less space. When an input is in focus, you do still need to show both the label and input, but you can get that space by either using some of the space the input was already using, or by growing the area temporarily only for the focused input.
It makes the input one big button. Not that inputs aren't already, and not that labels aren't when they have a proper for attribute, but there is something kinda nice about a big rectangle that tells you what it wants that you click/tap. Might make for a nice experience particularly on mobile.
I'd say, generally, that always-visible labels are probably "better" - but this is a clever idea and done right, may be useful occasionally. There is always a risk of screwing this up and hurting accessibility too, so take care. One downside to this pattern: we can't use placeholder in addition to the label, which can be helpful (e.g. a label of "Phone Number" and a placeholder hint of "(555) 555-5555").
The Trick (1 of 3) - The label is the placeholder
There is a <div> that contains both the <label> and <input> (which you need to do anyway because inputs within forms need to be in block level elements) that has relative positioning. That allows absolute positioning within it, which means we can position the label and input on top of each other. If we do that with the input on top, but with a transparent background, you'll be able to see the label right underneath it while still being able click into it.
form > div { position: relative; } form > div > label { position: absolute; }
The Trick (2 of 3) - the :focus state and the adjacent sibling combinator
The source order of the <label> and <input> wouldn't matter much here, since semantically they are tied together with the for attribute. But if we put the input first, that means we can leverage it's :focus state and an adjacent sibling combinator (+) to affect the label when it is focused. Similar in concept to the checkbox hack.
input:focus + label { /* do something with the label */ }
You can do whatever you want with the label. Just find a cool place to move it and style it that is out of the way of typing in the input. My example had two possibilities: one was making it smaller and moving toward the bottom of the input, the other was moving it to the far right side.
Once there is actual text in the input, and the input goes back out of focus, it would be very weird (bad) to see the label and the input text on top of each other. Fortunately in CSS there is a :valid selector that works on inputs when they are in a valid state. That valid state can be "any text at all", assuming the only thing that makes it valid is having any value at all, which can be achieved like:
<input type="text" required>
Then remember the only reason you could see the label at all was because the input has a transparent background. To hide it, we can use an opaque background instead:
form input:valid { background: white; }
The rest of this is just fiddling around with design details until you have it just how you like it.
The following is a guest post by by Parker Bennett. While icon fonts are efficient and easy to use and scaleable and all that, one of the classic "strikes" against them is that the icon can only be one color. Parker has a brand new project that solves that issue in a simple and clever way. I'll let him introduce it for you.
Even though the future of icons will likely be SVG, here in the present, icon fonts still offer a compelling alternative — with super easy styling of color, size, text-shadows, hover effects and more using just CSS. Icon fonts are still awesome.
One big advantage SVG has over icon fonts is full color. But icon fonts don’t have to be limited to just a single color. By overlapping two or more elements we can create unique “multi-color” icons with a contemporary flat look. If you’ve ever done any two-color or screen printing, it’s a similar idea.
For each color, we use a separate pseudo element, then use absolute positioning to stack them on top of each other. (If you want more than two colors, it will cost you a non-semantic span.)
/* @font-face to load icon font... */
/* horizontal button row: inline-block vs float makes positioning easier using text-align */
/* any class that starts with "st-icon-" */ [class^="st-icon-"] { display: inline-block; vertical-align: top; white-space: nowrap; /* child elements absolute */ position: relative; /* remove inline-block white-space */ margin-right: -.16em; /* 5px */ /* if not already universally applied */ -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; /* padding here for text, icons replicate this using size and position:absolute - padding makes touch-target bigger */ padding: 0.143em; /* units used in font: 1em = 2048, icons 2400 wide, so icons are 1.171875em (2400/2048). Add padding x2 to get size: */ height: 1.45788em; width: 1.45788em; font-size: 1.815em; /* text hidden old-school */ text-align: left; text-indent: -9999px; }
/* position:absolute stacks pseudo elements - extra <span> in markup = 2 extra pseudo elements */ [class^="st-icon-"]:before, [class^="st-icon-"]:after, [class^="st-icon-"] span:before, [class^="st-icon-"] span:after { display: block; position: absolute; white-space: normal; /* match padding above */ top: 0.143em; left: 0.143em; /* undo text hidden */ text-indent: 0; /* inherits size from parent, ems cascade */ font-size: 1em; font-family: "Stackicons-Social"; font-weight: 400 !important; font-style: normal !important; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; font-smoothing: antialiased; /* screenreaders */ speak: none; /* transitions here */ }
.st-icon-amazon:before { /* character code - unicode private use area */ content: "\e079"; /* black "a" */ color: black; }
Using rgba values, we can even do some color mixing to give us more colors. If we really want to push the limits, we can use -webkit-background-clip: text to give icons a -webkit-linear-gradient background.
Yes, it’s a bit on the hacky side: It takes some design forethought, and the ability to generate an icon font. There are more moving parts to manage. But it also offers a lot of flexibility, especially using Sass variables.
Stackicons This :hover effect would be hard to do in SVG
Stackicons-Social
To show how it works, I made a free, open source icon font, Stackicons-Social, and created a Sass “Construction Kit” to generate the CSS for both single color icons and “multi-color” versions of over 60 social brands.
I also created a range of button shapes in the font, from square to circle (plus icon-only), and have classes that override the shape on the fly. Want circular icons? Just add the .st-shape-circle class. iOS style? .st-shape-rounded3.
Behind the scenes, there is a group of .scss _partial files that Sass compiles. If you’re comfortable using Sass you can customize things extensively just by changing variables in this "construction kit":
fonts-stackicons-social - Path to stackicons-social font.
colors-social–2014 - Color variables for social brands.
unicodes-stackicons-social - Font unicode characters abstracted into variables.
construction-kit-stackicons-social - This is where we generate default values for icon size, margin, padding, shape, color, hover-style, etc. (Play here.)
css-defaults-stackicons-social - This does the CSS grunt work to create each .st-icon-($brand) class.*
override-shapes-stackicons-social - Let’s you override the button shape on single-color icons using classes: st-shape-square to st-shape-circle, plus st-shape-icon.*
override-colors-stackicons-social - Some examples of “color-styles” for single-color icons to demo different options. Lots of extra CSS, so it’s commented out by default.*
multi-color-kit-stackicons-social.scss - Like “construction-kit” above, but for the .st-multi-color class: generates default shape, color-style, etc.
multi-color-css-stackicons-social.scss - Like “css-defaults” above, this does the CSS grunt work to generate each multi-color .st-icon-($brand) class.*
multi-color-override-shapes-stackicons-social - This allows you to change icon shapes using classes on multi-color icons.*
* Because Sass doesn’t allow us to use variables within variables, this uses a lot of @if statements to generate the .st-icon-($brand) classes. Ugly, but marginally maintainable. There are several @each statements, listing the brands to output. Ideally, you would go through and edit these lists to limit the CSS output to only the brands you need.
Rolling Your Own
There are some great free resources for creating icon fonts, including icomoon.io and fontello.com. I use Adobe Illustrator and Glyphs on the Mac. (Glyphs Mini is a lower cost option that limits the units per em to 1000. They also offer student pricing.) To generate the web font versions, I recommend FontPrep, which Brian Gonzalez just made open source. FontSquirrel is another good free option. (If you’re interested in more workflow details, let me know in the comments.)