Montag, 3. November 2014

How SVG Fragment Identifiers Work




CSS-Tricks





How SVG Fragment Identifiers Work



I've talked a good bit about SVG's <use> around here and using it to build an icon system. The beauty of <use> is that you can reference just a part of some SVG defined elsewhere and draw just that part somewhere else. That ability allows you to build a whole system out of it, solving the "many images in one request, because that's super efficient" problem that we've solved in the past with CSS sprites and icon fonts.


But <use> means inline SVG. It doesn't help you when you want to use a part of a larger SVG in SVG-as-<img> or SVG-as-background-image. That's where fragment identifiers come in.



Getting the SVG Ready For It


One way to do this is to lay out the SVG (sprite, I guess, let's just call it a sprite) like a graphical "CSS" sprite.



We're specifically doing it this way, because we ultimately are going to shift some viewBox numbers around to only reveal a part of this image, just like we used to do with CSS sprites.


In this little mini demo, we're using three icons that are 32x32 each. So the document is 32x96. We could think of the viewBox shenanigans this way:



















Whole document viewBox0 0 32 96
Just show top icon viewBox0 0 32 32
Just show middle icon viewBox0 32 32 32
Just show bottom icon viewBox0 64 32 32

The viewBox attribute goes: left, top, width, height. Note that second attribute, the top, notching up by 32 each time. We're just showing a different part of the whole document.


Adding those special viewBox's into the SVG itself


You can drop those special, specific viewBox values into the SVG in a <view> element, that is specifically for this:


<view id="icon-clock-view" viewBox="0 0 32 32" />
<view id="icon-heart-view" viewBox="0 32 32 32" />
<view id="icon-arrow-right-view" viewBox="0 64 32 32" />

Now we'll be able to reference and use those values from elsewhere.


The <view> elements can be stand-alone like this, or they can actually wrap other elements, in which case that viewBox takes hold when the ID matches, so


<!-- this viewBox takes over if current fragment identifer is #match-me -->
<view id="match-me" viewBox="0 64 32 32">
<rect ...>
</view>

Demo of this kind of thing in the spec.


Syntax for HTML


To apply those special viewBox values to SVG-as-<img>, you could do it like this:


<!-- top icon -->
<img src="sprite.svg#svgView(viewBox(0, 0, 32, 32))" alt="">

Or, if you set up <view> elements already, you can just reference them by name:


<!-- middle icon -->
<img src="sprite.svg#icon-heart-view" alt="">

Syntax for CSS


You can declare a special viewBox right in the image path in the CSS:


.icon-clock {
background: url("sprite.svg#svgView(viewBox(0, 0, 32, 32))") no-repeat;
}

Or reference a <view> element if you have those set up:


.icon-clock {
background: url(sprite.svg#icon-clock-view) no-repeat;
}

Although... if you're using SVG through CSS this way and went through the trouble to set up the SVG all spaced out like this, you might wanna just use the CSS sprite technique and shift the background around:


.icon-heart {
background: url("sprite.svg") no-repeat;
background-size: 32px 96px;
background-position: 0 -32px;
}

I just wanna stack the icons on top of each other.


If the icons all have the same viewBox and you essentially just want to hide/show them as needed, this can get a little easier.


Design them all in the same space (or use a build tool that does it or whatever). Here, I'm putting each icon in it's own group with a unique ID.



The trick to making the hide/show work then is embedding some CSS that 1) hides everything 2) reveals the one with a matching fragment identifier. CSS is up for the job, because of the :target selector.


All together in the SVG:


<defs>
<style>
g {
display: none;
}
g:target {
display: inline;
}
</style>
</defs>

<g id="icon-clock">
<path d="M20.6,23.3L14,16.7V7.9h4v7.2l5.4,5.4L20.6,23.3z M16-0.1c-8.8,0-16,7.2-16,16s7.2,16,16,16s16-7.2,16-16S24.8-0.1,16-0.1z
M16,27.9c-6.6,0-12-5.4-12-12s5.4-12,12-12s12,5.4,12,12S22.6,27.9,16,27.9z"/>
</g>
<g id="icon-heart">
<path d="M32,11.2c0,2.7-1.2,5.1-3,6.8l0,0L19,28c-1,1-2,2-3,2s-2-1-3-2L3,18c-1.9-1.7-3-4.1-3-6.8C0,6.1,4.1,2,9.2,2
c2.7,0,5.1,1.2,6.8,3c1.7-1.9,4.1-3,6.8-3C27.9,1.9,32,6.1,32,11.2z"/>
</g>
<g id="icon-arrow-right">
<path d="M32,15.9l-16-16v10H0v12h16v10L32,15.9z"/>
</g>

Browser Support


Can I Use tracks support for fragment identifier. Unfortunately it's not quite as simple as works-or-not, because depending on the browser it might work in HTML and not CSS or have quirks.


Here's my test page:


See the Pen SVG Fragment Identifiers in HTML and CSS by Chris Coyier (@chriscoyier) on CodePen.


I haven't made super detailed browser support notes for this, but here's the highlights:



  • Firefox does everything right.

  • IE 11 does everything right. IE 9 & 10 are a little weird with background-position (squishing) but otherwise works with all.

  • Current versions of Chrome/Safari/Opera (38/8/25) handle all the HTML <img> techniques well, but none of the CSS techniques, including the background-position one. Pre-Blink Opera was the same, interestingly enough.

  • The only thing iOS 8.1 can handle is <img> referencing a <view>.

  • The only thing Android 4.4 gets right is background-position (the one that's not really using fragment identifiers at all). Android 5 matches current Chrome/Safari/Opera as above.


Linkage!





How SVG Fragment Identifiers Work is a post from CSS-Tricks








Samstag, 1. November 2014

Sponsor: Wufoo




CSS-Tricks





Sponsor: Wufoo



I'm posting this just as a big ol' high five to Wufoo for being a long time sponsor of CSS-Tricks.


Wufoo is a web app for building web forms. Things like contact forms, conference registration forms, t-shirt selling forms, wedding RSVP's, you name it. You put the forms on your own site (if you like). They work on small screens. They don't get spammed. They save their data forever. They can be multi-page and use logic. Everything you need a form to do.


As many of you also know, I was a somewhat early employee of Wufoo back in the day. I'm still quite proud of the work we did at Wufoo and I'm happy with Wufoo today. I use the crap out of Wufoo. Every single day, it powers nearly every single form on all the sites I work on, and a bunch more that I built a long time ago and are just quietly still working great. It's reliable, feature-rich software that just does what it does very well.


Direct Link to ArticlePermalink



Sponsor: Wufoo is a post from CSS-Tricks








Freitag, 31. Oktober 2014

Taking Control of the CSS/JS that WordPress Plugins Load




CSS-Tricks





Taking Control of the CSS/JS that WordPress Plugins Load



The other day on ShopTalk a question we got led us down a short tangent on WordPress plugins, the resources they load, and what that would look like in a perfect world. I ended up writing up some thoughts on it and getting some feedback. I think it came to a somewhat satisfying conclusion so I figured I write it up.



How Some Plugins Work Now


Let's take a real-world example. The WP-Polls plugin. I think it's a nice plugin. Does a good job with polls. I use it here on CSS-Tricks.


To put those polls on your site, it needs some JavaScript to handle the functionality (i.e. voting and seeing results without a page refresh) and CSS to style the poll widget (the results bars and whatnot).


The way that it adds that CSS is by injecting a stylesheet via the wp_head() hook, putting this in the <head>:


<link rel='stylesheet' id='wp-polls-css'  href='http://example.com/wp-content/plugins/wp-polls/polls-css.css?ver=2.67' type='text/css' media='all' />

The way it adds that JavaScript is by injecting a script via the wp_footer() hook, putting this near the bottom of the document:


<script type='text/javascript' src='http://example.com/wp-content/plugins/wp-polls/polls-js.js?ver=2.67'></script>

That makes sense. That's what they need to do to make this plugin work. Plugin authors need to make sure their plugins are easy to use and work.


As a performance-concerned developer, I want to concatenate scripts and styles.


Now we have these two single-purpose resources being loaded on the page. When you look into web performance and how to make websites faster, some of the first advice you hear is to concatenate resources. Very good rule of thumb: the less resources a website needs to load, the faster it will be.


Concatenating resources isn't some obscure thing only the most elite websites need to worry about. It's an every website problem. People have tackled this problem in a million ways. CSS sprites were all about concatenating image resources. Icon fonts and SVG sprites are solving that same problem. CSS preprocessors help you concatenate your stylesheets. The Rails Asset Pipeline helps you concatenate resources. There are Grunt and Gulp plugins galore that are designed for this.


But we're in WordPress land here, so we solutions for that.


Should plugins themselves help?


The first idea I thought of was that plugins should allow us to dequeue anything they enqueue from UI they add to the plugin itself. Even go so far as to provide the resources they would have loaded for you in a textarea for easy copy-and-pasting into your own system.


I now think that was a little misguided. It would take a major movement in the WordPress plugins world to get this going. Even if that happened, that's a lot of duplicate effort, and this issue can be handled more efficiently.


Solution #1: Use a Plugin


The plugin MinQueue offers a solution I like. It doesn't do anything automatically, it allows you to configure what resources you want concatenated and in what order.


With the plugin active, in the Admin Bar on the front end you'll see a little helper link you can click.



In our demo, I know I want to concatenate our theme's CSS and WP-Polls CSS together. So I take those names from the helper and put them into a new "queue" in the plugin settings.



Now neither of those CSS files loads individually anymore. MinQueue creates a combined (and cached) version and serves that:


<link rel='stylesheet' id='minqueue-117c22aa-ebc80003-css'  href='http://example.com/wp-content/uploads/minqueue-cache/minqueue-117c22aa-ebc80003.css' type='text/css' media='all' />

You can create multiple "queues", which gives you a good amount of control. For instance, perhaps a subsection of your site loads different resources, those could be combined separately if you wish, it's not required you concatenate them with the main group.


Note that this means you'll need to enqueue your theme's stylesheet, but that's pretty easy.


Also note the popular W3 Total Cache does concatenation too, but I find it a bit more confusing. You add stylesheets via URL's and it seems a bit more basic and easy to break.


Solution #2: Manually dequeue assets and concatenate yourself


Plugins that add resources do it through wp_enqueue_script and wp_enqueue style. You can dig through their plugin code and find where they do that, so you can see what name they applied when they did it. Then, in your own theme's functions.php file (or custom functionality plugin), you dequeue them.


Justin Tadlock has a post about this can you can read. Simple example of dequeuing one stylesheet:


add_action('wp_print_styles', 'my_deregister_styles', 100);

function my_deregister_styles() {
wp_deregister_style('name-of-style');
}

Now it's on you to go find that resource and concatenate it into the CSS you are still loading on the page yourself. Perhaps you're using a CSS preprocessor and you can @import it. Perhaps you're using a task running like Grunt can can add it to the list to files to go get and concatenate. Or go fully manual and just copy and paste it's contents into your own stylesheet (just be aware if you do this you don't get updates when the plugin updates).


Solution #3: Use a plugin to dequeue assets and concatenate yourself


While I'm capable of digging through a plugin's code to find instances of enqueuing resources, that doesn't seem like a fantastic approach to me. I'd rather do it programmatically, making it easier and reducing human error.


During the earlier discussions happening around this, Nate Wright of Theme of the Crop cooked up a brand new plugin for this called Asset Queue Manager. It has a UI you use (from the front end) for you to easily dequeue assets.


From the front end of the site, you click a link in the Admin Bar to reveal a dropdown of all the enqueued assets on that page.



There is a button for dequeuing that asset. The plugin will keep that asset dequeued until you say otherwise. Now again it's on you to go concatenate that into your stylesheets however you wish. There is another button there that links directly to the resource, making it super easy to find. Pretty cool!


Conclusion


There are plenty of ways to wrangle control of the CSS and JavaScript that WordPress plugins can load. You can and should do this, with the urgency increasing for each unconcatenated resource.


How many resources files of each type OK to load? One, Two or Three.




Taking Control of the CSS/JS that WordPress Plugins Load is a post from CSS-Tricks








Donnerstag, 30. Oktober 2014

The Specificity Graph




CSS-Tricks





The Specificity Graph



Harry Roberts, on charting CSS selector specificity across entire codebases:


A spiky graph is a bad graph.


I would think if you went 100% on a methodology that encouraged class names for everything, your chart would be damn near flat. I wonder if that's a worthy goal. Something to draw a line in the sand on, for the good of a project.


Direct Link to ArticlePermalink



The Specificity Graph is a post from CSS-Tricks








Dienstag, 28. Oktober 2014

Shape Blobbing in CSS




CSS-Tricks





Shape Blobbing in CSS



We just covered shape morphing in SVG, where shapes change from one to another. Let's look at shapes that blob into each other! You know, that gooey squishy blobby effect like droplets of mercury on a surface.




I'm not sure who first discovered this was possible on the web, but the first place I ever saw it was a demo by Lucas Bebber:


See the Pen Gooey Pagination by Lucas Bebber (@lbebber) on CodePen.


And then again by Felix Hornoiu (low framerate GIF for web practicality):


Demo from here.

The trick is fairly simple, use filter to BOTH add blur and contrast to an element


The blur obvious makes the element blurry, the contrast fights against the blur, preferring stark changes in color. If you contrast enough, you're left with a (fairly) sharp looking shape again.



The fancy parts comes from the fact that when two blurred (yet forced to look non-blurry) elements come near each other, their would-be blurs create enough would-be color contrast that the shapes actually appear to connect.


Demo from here.

I find it easier to get working if you blur the shapes but add contrast to the whole area. Like:


.stage {
/* must be explicit, for contrast to work */
background: white;

/* weirdness happens when edges hit, also consider hiding overflow */
padding: 30px;

-webkit-filter: contrast(20);
filter: contrast(20);
}
.dot {
border-radius: 50%;
width: 50px;
height: 50px;

/* needs to be very contrasty color. E.g. light gray on white won't work */
background: black;

-webkit-filter: blur(15px);
filter: blur(15px);
}

And then the fun happens when you add animation to blob those suckers all around. Here's a demo where you can play with the values, including brightness which affects the blur:


See the Pen Blobbing Playground by Chris Coyier (@chriscoyier) on CodePen.


Browser Support


Not just WebKit/Blink anymore! Firefox 35 will be supporting filters without any flag or anything. Aurora, their beta-beta, is in v35 right now and I popped it open in that and it works great.


So... current Chrome / Safari / Opera / Firefox / iOS / Android. Not bad. Just no IE.


Predictions of Exclaimed Things


It's not practical!!! Go to bed.


It makes my fan spin like crazy!!! Yeah my demo with tons of elements interacting makes my CPU pretty busy as well. The more chill demos with just two circles bumping into each other are fine though. Use decision making skills.


There are better ways to do this!!! Awesome.




Shape Blobbing in CSS is a post from CSS-Tricks








Montag, 27. Oktober 2014

Datalists for Different Input Types




CSS-Tricks





Datalists for Different Input Types



I saw an HTML5 date input the other day, which had the dropdown arrow on the right, which I've grown accustom to clicking to reveal a calendar datepicker in which to choose a date.


Typically, that looks like this:



<input type="date" />

I've seen variations on this before, like when you use a week input instead of date:


<input type="week" />

But I hadn't seen this before:



Turns out that's what you get when you apply a <datalist> to an input of that type! Who knew!


The format is like this:


<input type="date" list="days">
<datalist id="days">
<option label="Chris' Birthday">1980-08-26</option>
<option label="Apollo 11 Moon Landing">1969-07-20</option>
<option label="DDay">1944-06-06</option>
</datalist>

The values for each of the options just need to be valid values for the input, otherwise they just don't show up.


Browser Support


As far as I understand it, the spec doesn't dictate any particular UI requirements for HTML5 input types. If a browser wants to build a datepicker thingy, great, but not doing it doesn't violate the spec. Thus, this additional UI nicety also isn't required. I just mention that because lack of "support" here doesn't indicate a browser is doing a bad job.


These fancy datalist inputs appear to largely be a Blink thing.


A quick check around the latest version of browsers, just testing input type="date" with a datalist:


Chrome 38 = works

Opera 23 = works

Safari 8.0 = doesn't support input type="date"

Firefox 32 = doesn't support input type="date"

Internet Explorer 11 = doesn't support input type="date"

iOS 8.1 = date works / datalist doesn't (see screenshot)

Android 5 = works (see screenshot)

Opera Mobile 11.5 = date works / datalist doesn't


"Support" again meaning "doesn't do anything special for" - but falls back to a useable text input.


iOS 8.1 - you get the date controls but nothing special for the datalist.

Android 5

Here's the rub with features like this. If it's just a little nicety you can provide, but not crucial, just use it and think of it as progressive enhancement. If it's totally vital that all users to your site need UI for choosing recommended options and you support browsers that don't support this, you'll need either a polyfill or a custom solution.

Other Types


Date doesn't get to have all the fun! While putting this together, I ran across Eiji Kitamura's comprehensive test page for all this. It's not just text and date inputs that datalist can work for, it's all the variety of date inputs as well as color and range!


type="range"


Opera 23. Shows little ticks, dragging across them, the rubber kinda "sticks" to each point as you pass.

Android 5

IE 10 - So this isn't entirely Blink...

Opera Mobile 11.5

type="color"


Android 5

A little dangerous on Opera Mobile 11.5. It supports the datalist, but ONLY those in the datalist, there is no way to activate a more generic color picker or manually type in another color.

It's fine in desktop Opera (23)



Datalists for Different Input Types is a post from CSS-Tricks








Samstag, 25. Oktober 2014

How SVG Shape Morphing Works




CSS-Tricks





How SVG Shape Morphing Works



While animating SVG with CSS is easy and comfortable, CSS can't animate all the SVG properties that are possible to animate. For instance, all the properties that define the actual shape of the elements aren't possible to change or animate in CSS. You can animate them through SMIL though. Sara Soueidan covers this in her guide to SMIL here on CSS-Tricks, but I thought I would shine a light on this particular ability.



Most important fact: the shapes need to have the same number of points


Otherwise, the animation will just fail. The shape won't disappear or anything, but it won't animate.


It's not extremely obvious how many points a shape has just by looking at the d (in the case of a path) or points attribute (in the case of a polygon) so you may just need to start in a vector editor program with a single shape and work from there.


1. Start with the most complicated shape


In this demo I'm going to morph from a star to a check. The star is more complex:



Save a copy of that SVG, then make a new copy for the next shape.


2. Make the next shape with those same points.


Drag the points around until you have your next shape.




3. Use the starting shape on the SVG shape element itself


<svg viewBox="0 0 194.6 185.1">

<polygon fill="#FFD41D" points=" ... shape 1 points ... ">

</polygon>

</svg>

4. Add an animation element that animates to the next shape


<svg viewBox="0 0 194.6 185.1">

<polygon fill="#FFD41D" points=" ... shape 1 points ... ">

<animate attributeName="points" dur="500ms" to=" ... shape 2 points ... />

</polygon>

</svg>

That animation will run immediately, so we'll need to fix that up a bit.


5. Trigger the animations as needed


SMIL has the ability to handle interactions like clicks and hovers, so long as all that happens within the SVG itself. For instance, you could begin the animation when it's clicked on, like:


<polygon id="shape" points=" ... shape 1 points ... ">

<animate begin="shape.click" attributeName="points" dur="500ms" to=" ... shape 2 points ... />

</polygon>

That's pretty neat, but it's a little limiting since you can only handle clicks from other elements right in that same SVG. Perhaps this SVG is just a part of a <button> and you want to run the animation on any click on that button.


First give the animation an ID so we can find it with JavaScript, and then prevent it from running with:


<animate id="animation-to-check" begin="indefinite" ... />

Now you can get a reference to that animation and kick if off how you like:


animationToCheck = document.getElementById("animation-to-check");

// run this on a click or whenever you want
animationToCheck.beginElement();

Demo


This demo actually has four animations. One to morph the star to a check, one to change the color, and then both those same animations in reverse. Clicking the button checks the state of the button and then runs the appropriate ones.


See the Pen Shape Morph Button by Chris Coyier (@chriscoyier) on CodePen.


Would be pretty cool for charts, like this old Raphael demo:





How SVG Shape Morphing Works is a post from CSS-Tricks