{"rowid": 271, "title": "Creating Custom Font Stacks with Unicode-Range", "contents": "Any web designer or front-end developer worth their salt will be familiar with the CSS @font-face rule used for embedding fonts in a web page. We\u2019ve all used it \u2014 either directly in our code ourselves, or via one of the web font services like Fontdeck, Typekit or Google Fonts.\n\nIf you\u2019re like me, however, you\u2019ll be used to just copying and pasting in a specific incantation of lines designed to get different formats of fonts working in different browsers, and may not have really explored all the capabilities of @font-face properties as defined by the spec.\n\nOne such property \u2014 the unicode-range descriptor \u2014 sounds pretty dull and is easily overlooked. It does, however, have some fairly interesting possibilities when put to use in creative ways.\n\nUnicode-range\n\nThe unicode-range descriptor is designed to help when using fonts that don\u2019t have full coverage of the characters used in a page. By adding a unicode-range property to a @font-face rule it is possible to specify the range of characters the font covers. \n\n@font-face {\n font-family: BBCBengali;\n src: url(fonts/BBCBengali.ttf) format(\"opentype\");\n unicode-range: U+00-FF;\n}\n\nIn this example, the font is to be used for characters in the range of U+00 to U+FF which runs from the unexciting control characters at the start of the Unicode table (symbols like the exclamation mark start at U+21) right through to \u00ff at U+FF \u2013 the extent of the Basic Latin character range.\n\nBy adding multiple @font-face rules for the same family but with different ranges, you can build up complete coverage of the characters your page uses by using different fonts.\n\nWhen I say that it\u2019s possible to specify the range of characters the font covers, that\u2019s true, but what you\u2019re really doing with the unicode-range property is declaring which characters the font should be used for. This becomes interesting, because instead of merely working with the technical constraints of available characters in a given font, we can start picking and choosing characters to use and selectively mix fonts together.\n\nThe best available ampersand\n\nA few years back, Dan Cederholm wrote a post encouraging designers to use the best available ampersand. Dan went on to outline how this can be achieved by wrapping our ampersands in a element with a class applied:\n\n&\n\nA CSS rule can then be written to select the and apply a different font:\n\nspan.amp {\n font-family: Baskerville, Palatino, \"Book Antiqua\", serif;\n}\n\nThat\u2019s a perfectly serviceable technique, but the drawbacks are clear \u2014 you have to add extra markup which is borderline presentational, and you also have to be able to add that markup, which isn\u2019t always possible when working with a CMS.\n\nPerhaps we could do this with unicode-range.\n\nA better best available ampersand\n\nThe Unicode code point for an ampersand is U+26, so the ampersand font stack above can be created like so:\n\n@font-face {\n font-family: 'Ampersand';\n src: local('Baskerville'), local('Palatino'), local('Book Antiqua');\n unicode-range: U+26;\n}\n\nWhat we\u2019ve done here is specify a new family called Ampersand and created a font stack for it with the user\u2019s locally installed copies of Baskerville, Palatino or Book Antiqua. We\u2019ve then limited it to a single character range \u2014 the ampersand. Of course, those don\u2019t need to be local fonts \u2014 they could be web font files, too. If you have a font with a really snazzy ampersand, go for your life.\n\nWe can then use that new family in a regular font stack.\n\nh1 {\n font-family: Ampersand, Arial, sans-serif;\n}\n\nWith this in place, any

elements in our page will use the Ampersand family (Baskerville, Palatino or Book Antiqua) for ampersands, and Arial for all other characters. If the user doesn\u2019t have any of the Ampersand family fonts available, the ampersand will fall back to the next item in the font stack, Arial.\n\nYou didn\u2019t think it was that easy, did you?\n\nOh, if only it were so. The problem comes, as ever, with the issue of browser support. The unicode-range property has good support in WebKit browsers (like Safari and Chrome, and the browsers on most popular smartphone platforms) and in recent versions of Internet Explorer. The big stumbling block comes in the form of Firefox, which has no support at all.\n\nIf you\u2019re familiar with how CSS works when it comes to unsupported properties, you\u2019ll know that if a browser encounters a property it doesn\u2019t implement, it just skips that declaration and moves on to the next. That works perfectly for things like border-radius \u2014 if the browser can\u2019t round off the corners, the declaration is skipped and the user sees square corners instead. Perfect.\n\nLess perfect when it comes to unicode-range, because if no range is specified then the default is that the font is applied for all characters \u2014 the whole range. If you\u2019re using a fancy font for flamboyant ampersands, you probably don\u2019t want that applied to all your text if unicode-range isn\u2019t supported. That would be bad. Really bad.\n\nEnsuring good fallbacks\n\nAs ever, the trick is to make sure that there\u2019s a sensible fallback in place if a browser doesn\u2019t have support for whatever technology you\u2019re trying to use. This is where being a super nerd about understanding the spec you\u2019re working with really pays off.\n\nWe can make use of the rules of the CSS cascade to make sure that if unicode-range isn\u2019t supported we get a sensible fallback font. What would be ideal is if we were able to follow up the @font-face rule with a second rule to override it if Unicode ranges aren\u2019t implemented.\n\n@font-face {\n font-family: 'Ampersand';\n src: local('Baskerville'), local('Palatino'), local('Book Antiqua');\n unicode-range: U+26;\n}\n@font-face {\n font-family: 'Ampersand';\n src: local('Arial');\n}\n\nIn theory, this code should make sense for all browsers. For those that support unicode-range the two rules become cumulative. They specify different ranges for the same family, and in WebKit browsers this has the expected result of using Arial for most characters, but Baskerville and friends for the ampersand. For browsers that don\u2019t have support, the second rule should just supersede the first, setting the font to Arial. \n\nUnfortunately, this code causes current versions of Firefox to freak out and use the first rule, applying Baskerville to the entire range. That\u2019s both unexpected and unfortunate. Bad Firefox. On your rug.\n\nIf that doesn\u2019t work, what can we do? Well, we know that if given a unicode-range Firefox will ignore the range and apply the font to all characters. That\u2019s really what we\u2019re trying to achieve. So what if we specified a range for the fallback font, but made sure it only covers some obscure high-value Unicode character we\u2019re never going to use in our page? Then it wouldn\u2019t affect the outcome for browsers that do support ranges.\n\n@font-face {\n font-family: 'Ampersand';\n src: local('Baskerville'), local('Palatino'), local('Book Antiqua');\n unicode-range: U+26;\n}\n@font-face {\n /* Ampersand fallback font */\n font-family: 'Ampersand';\n src: local('Arial');\n unicode-range: U+270C;\n}\n\nBy specifying a range on the fallback font, Firefox appears to correctly override the first based on the cascade sort order. Browsers that do support ranges take the second rule in addition, and apply Arial for that obscure character we\u2019re not using in any of our pages \u2014 U+270C.\n\nSo we get our nice ampersands in browsers that support unicode-range and, thanks to our styling of an obscure Unicode character, the font falls back to a perfectly acceptable Arial in browsers that do not offer support. Perfect!\n\nThat obscure character, my friends, is what Unicode defines as the VICTORY HAND.\n\n\u270c\n\nSo, how can we use this?\n\nAmpersands are a neat trick, and it works well in browsers that support ranges, but that\u2019s not really the point of all this. Styling ampersands is fun, but they\u2019re only really scratching the surface. Consider more involved examples, such as substituting a different font for numerals, or symbols, or even caps. Things certainly begin to get a bit more interesting.\n\nHow do you know what the codes are for different characters? Richard Ishida has a handy online conversion tool available where you can type in the characters and get the Unicode code points out the other end.\n\nOf course, the fact remains that browser support for unicode-range is currently limited, so any application needs to have fallbacks that you\u2019re still happy for a significant proportion of your visitors to see. In some cases, such as dedicated pages for mobile devices in an HTML-based phone app, this is immediately useful as support in WebKit browsers is already very good. In other cases, you\u2019ll have to use your own best judgement based on your needs and audience.\n\nOne thing to keep in mind is that if you\u2019re using web fonts, the entire font will be downloaded even if only one character is used. That said, the font shouldn\u2019t be downloaded if none of the characters within the Unicode range are present in a given page.\n\nAs ever, there are pros and cons to using unicode-range as well as varied but increasing support in browsers. It remains a useful tool to understand and have in your toolkit for when the right moment comes along.", "year": "2011", "author": "Drew McLellan", "author_slug": "drewmclellan", "published": "2011-12-01T00:00:00+00:00", "url": "https://24ways.org/2011/creating-custom-font-stacks-with-unicode-range/", "topic": "code"} {"rowid": 276, "title": "Your jQuery: Now With 67% Less Suck", "contents": "Fun fact: more websites are now using jQuery than Flash.\n\njQuery is an amazing tool that\u2019s made JavaScript accessible to developers and designers of all levels of experience. However, as Spiderman taught us, \u201cwith great power comes great responsibility.\u201d The unfortunate downside to jQuery is that while it makes it easy to write JavaScript, it makes it easy to write really really f*&#ing bad JavaScript. Scripts that slow down page load, unresponsive user interfaces, and spaghetti code knotted so deep that it should come with a bottle of whiskey for the next sucker developer that has to work on it. \n\nThis becomes more important for those of us who have yet to move into the magical fairy wonderland where none of our clients or users view our pages in Internet Explorer. The IE JavaScript engine moves at the speed of an advancing glacier compared to more modern browsers, so optimizing our code for performance takes on an even higher level of urgency.\n\nThankfully, there are a few very simple things anyone can add into their jQuery workflow that can clear up a lot of basic problems. When undertaking code reviews, three of the areas where I consistently see the biggest problems are: inefficient selectors; poor event delegation; and clunky DOM manipulation. We\u2019ll tackle all three of these and hopefully you\u2019ll walk away with some new jQuery batarangs to toss around in your next project.\n\nSelector optimization\n\nSelector speed: fast or slow?\n\nSaying that the power behind jQuery comes from its ability to select DOM elements and act on them is like saying that Photoshop is a really good tool for selecting pixels on screen and making them change color \u2013 it\u2019s a bit of a gross oversimplification, but the fact remains that jQuery gives us a ton of ways to choose which element or elements in a page we want to work with. However, a surprising number of web developers are unaware that all selectors are not created equal; in fact, it\u2019s incredible just how drastic the performance difference can be between two selectors that, at first glance, appear nearly identical. For instance, consider these two ways of selecting all paragraph tags inside a
with an ID.\n\n$(\"#id p\");\n\n$(\"#id\").find(\"p\");\n\nWould it surprise you to learn that the second way can be more than twice as fast as the first? Knowing which selectors outperform others (and why) is a pretty key building block in making sure your code runs well and doesn\u2019t frustrate your users waiting for things to happen.\n\nThere are many different ways to select elements using jQuery, but the most common ways can be basically broken down into five different methods. In order, roughly, from fastest to slowest, these are:\n\n\n\t$(\"#id\"); \nThis is without a doubt the fastest selector jQuery provides because it maps directly to the native document.getElementbyId() JavaScript method. If possible, the selectors listed below should be prefaced with an ID selector in conjunction with jQuery\u2019s .find() method to limit the scope of the page that has to be searched (as in the $(\"#id\").find(\"p\") example shown above).\n\t$(\"p\");, $(\"input\");, $(\"form\"); and so on\nSelecting elements by tag name is also fast, since it maps directly to the native document.getElementsByTagname() method.\n\t$(\".class\"); \nSelecting by class name is a little trickier. While still performing very well in modern browsers, it can cause some pretty significant slowdowns in IE8 and below. Why? IE9 was the first IE version to support the native document.getElementsByClassName() JavaScript method. Older browsers have to resort to using much slower DOM-scraping methods that can really impact performance.\n\t$(\"[attribute=value]\");\nThere is no native JavaScript method for this selector to use, so the only way that jQuery can perform the search is by crawling the entire DOM looking for matches. Modern browsers that support the querySelectorAll() method will perform better in certain cases (Opera, especially, runs these searches much faster than any other browser) but, generally speaking, this type of selector is Slowey McSlowersons.\n\t$(\":hidden\");\nLike attribute selectors, there is no native JavaScript method for this one to use. Pseudo-selectors can be painfully slow since the selector has to be run against every element in your search space. Again, modern browsers with querySelectorAll() will perform slightly better here, but try to avoid these if at all possible. If you must use one, try to limit the search space to a specific portion of the page: $(\"#list\").find(\":hidden\");\n\n\nBut, hey, proof is in the performance testing, right? It just so happens that said proof is sitting right here. Be sure to notice the class selector numbers beside IE7 and 8 compared to other browsers and then wonder how the people on the IE team at Microsoft manage to sleep at night. Yikes.\n\nChaining\n\nAlmost all jQuery methods return a jQuery object. This means that when a method is run, its results are returned and you can continue executing more methods on them. Rather than writing out the same selector multiple times over, just making a selection once allows multiple actions to be run on it.\n\nWithout chaining\n\n$(\"#object\").addClass(\"active\");\n$(\"#object\").css(\"color\",\"#f0f\");\n$(\"#object\").height(300);\n\nWith chaining\n\n$(\"#object\").addClass(\"active\").css(\"color\", \"#f0f\").height(300);\n\nThis has the dual effect of making your code shorter and faster. Chained methods will be slightly faster than multiple methods made on a cached selector, and both ways will be much faster than multiple methods made on non-cached selectors. Wait\u2026 \u201ccached selector\u201d? What is this new devilry? \n\nCaching\n\nAnother easy way to speed up your code that seems to be a mystery to developers is the idea of caching your selectors. Think of how many times you end up writing the same selector over and over again in any project. Every $(\".element\") selector has to search the entire DOM each time, regardless of whether or not that selector had been previously run. Running the selection once and then storing the results in a variable means that the DOM only has to be searched once. Once the results of a selector have been cached, you can do anything with them.\n\nFirst, run your search (here we\u2019re selecting all of the
  • elements inside
      ): \n\nvar blocks = $(\"#blocks\").find(\"li\");\n\nNow, you can use the blocks variable wherever you want without having to search the DOM every time.\n\n$(\"#hideBlocks\").click(function() {\n blocks.fadeOut();\n});\n$(\"#showBlocks\").click(function() {\n blocks.fadeIn();\n});\n\nMy advice? Any selector that gets run more than once should be cached. This jsperf test shows just how much faster a cached selector runs compared to a non-cached one (and even throws some chaining love in to boot).\n\nEvent delegation\n\nEvent listeners cost memory. In complex websites and apps it\u2019s not uncommon to have a lot of event listeners floating around, and thankfully jQuery provides some really easy methods for handling event listeners efficiently through delegation.\n\nIn a bit of an extreme example, imagine a situation where a 10\u00d710 cell table needs to have an event listener on each cell; let\u2019s say that clicking on a cell adds or removes a class that defines the cell\u2019s background color. A typical way that this might be written (and something I\u2019ve often seen during code reviews) is like so:\n\n$('table').find('td').click(function() {\n $(this).toggleClass('active');\n});\n\njQuery 1.7 has provided us with a new event listener method, .on(). It acts as a utility that wraps all of jQuery\u2019s previous event listeners into one convenient method, and the way you write it determines how it behaves. To rewrite the above .click() example using .on(), we\u2019d simply do the following:\n\n$('table').find('td').on('click',function() {\n $(this).toggleClass('active');\n});\n\nSimple enough, right? Sure, but the problem here is that we\u2019re still binding one hundred event listeners to our page, one to each individual table cell. A far better way to do things is to create one event listener on the table itself that listens for events inside it. Since the majority of events bubble up the DOM tree, we can bind a single event listener to one element (in this case, the ) and wait for events to bubble up from its children. The way to do this using the .on() method requires only one change from our code above:\n\n$('table').on('click','td',function() {\n $(this).toggleClass('active');\n});\n\nAll we\u2019ve done is moved the td selector to an argument inside the .on() method. Providing a selector to .on() switches it into delegation mode, and the event is only fired for descendants of the bound element (table) that match the selector (td). With that one simple change, we\u2019ve gone from having to bind one hundred event listeners to just one. You might think that the browser having to do one hundred times less work would be a good thing and you\u2019d be completely right. The difference between the two examples above is staggering.\n\n(Note that if your site is using a version of jQuery earlier than 1.7, you can accomplish the very same thing using the .delegate() method. The syntax of how you write the function differs slightly; if you\u2019ve never used it before, it\u2019s worth checking the API docs for that page to see how it works.)\n\nDOM manipulation\n\njQuery makes it very easy to manipulate the DOM. It\u2019s trivial to create new nodes, insert them, remove other ones, move things around, and so on. While the code to do this is simple to write, every time the DOM is manipulated, the browser has to repaint and reflow content which can be extremely costly. This is no more evident than in a long loop, whether it be a standard for() loop, while() loop, or jQuery $.each() loop.\n\nIn this case, let\u2019s say we\u2019ve just received an array full of image URLs from a database or Ajax call or wherever, and we want to put all of those images in an unordered list. Commonly, you\u2019ll see code like this to pull this off:\n\nvar arr = [reallyLongArrayOfImageURLs]; \n $.each(arr, function(count, item) {\n var newImg = '
    • ';\n $('#imgList').append(newImg);\n });\n\nThere are a couple of problems with this. For one (which you should have already noticed if you\u2019ve read the earlier part of this article), we\u2019re making the $(\"#imgList\") selection once for each iteration of our loop. The other problem here is that each time the loop iterates, it\u2019s adding a new
    • to the DOM. Each of those insertions is going to be costly, and if our array is quite large then this could lead to a massive slowdown or even the dreaded \u2018A script is causing this page to run slowly\u2019 warning.\n\nvar arr = [reallyLongArrayOfImageURLs],\n tmp = ''; \n$.each(arr, function(count, item) {\n tmp += '
    • ';\n});\n$('#imgList').append(tmp);\n\nAll we\u2019ve done here is create a tmp variable that each
    • is added to as it\u2019s created. Once our loop has finished iterating, that tmp variable will contain all of our list items in memory, and can be appended to our
        all in one go. Browsers work much faster when working with objects in memory rather than on screen, so this is a much faster, more CPU-cycle-friendly method of building a list.\n\nWrapping up\n\nThese are far from being the only ways to make your jQuery code run better, but they are among the simplest ones to implement. Though each individual change may only make a few milliseconds of difference, it doesn\u2019t take long for those milliseconds to add up. Studies have shown that the human eye can discern delays of as few as 100ms, so simply making a few changes sprinkled throughout your code can very easily have a noticeable effect on how well your website or app performs. Do you have other jQuery optimization tips to share? Leave them in the comments and help make us all better.\n\nNow go forth and make awesome!", "year": "2011", "author": "Scott Kosman", "author_slug": "scottkosman", "published": "2011-12-13T00:00:00+00:00", "url": "https://24ways.org/2011/your-jquery-now-with-less-suck/", "topic": "code"} {"rowid": 283, "title": "CSS3 Patterns, Explained", "contents": "Many of you have probably seen my CSS3 patterns gallery. It became very popular throughout the year and it showed many web developers how powerful CSS3 gradients really are. But how many really understand how these patterns are created? The biggest benefit of CSS-generated backgrounds is that they can be modified directly within the style sheet. This benefit is void if we are just copying and pasting CSS code we don\u2019t understand. We may as well use a data URI instead.\n\nImportant note\n\nIn all the examples that follow, I\u2019ll be using gradients without a vendor prefix, for readability and brevity. However, you should keep in mind that in reality you need to use all the vendor prefixes (-moz-, -ms-, -o-, -webkit-) as no browser currently implements them without a prefix. Alternatively, you could use -prefix-free and have the current vendor prefix prepended at runtime, only when needed.\n\nThe syntax described here is the one that browsers currently implement. The specification has since changed, but no browser implements the changes yet. If you are interested in what is coming, I suggest you take a look at the dev version of the spec.\n\nIf you are not yet familiar with CSS gradients, you can read these excellent tutorials by John Allsopp and return here later, as in the rest of the article I assume you already know the CSS gradient basics:\n\n\n\tCSS3 Linear Gradients\n\tCSS3 Radial Gradients\n\n\nThe main idea\n\nI\u2019m sure most of you can imagine the background this code generates:\n\nbackground: linear-gradient(left, white 20%, #8b0 80%);\n\nIt\u2019s a simple gradient from one color to another that looks like this:\n\n See this example live\n\nAs you probably know, in this case the first 20% of the container\u2019s width is solid white and the last 20% is solid green. The other 60% is a smooth gradient between these colors. Let\u2019s try moving these color stops closer to each other:\n\nbackground: linear-gradient(left, white 30%, #8b0 70%);\n\n See this example live\n\nbackground: linear-gradient(left, white 40%, #8b0 60%);\n\n See this example live\n\nbackground: linear-gradient(left, white 50%, #8b0 50%);\n\n See this example live\n\nNotice how the gradient keeps shrinking and the solid color areas expanding, until there is no gradient any more in the last example. We can even adjust the position of these two color stops to control where each color abruptly changes into another:\n\nbackground: linear-gradient(left, white 30%, #8b0 30%);\n\n See this example live\n\nbackground: linear-gradient(left, white 90%, #8b0 90%);\n\n See this example live\n\nWhat you need to take away from these examples is that when two color stops are at the same position, there is no gradient, only solid colors. Even without going any further, this trick is useful for a number of different use cases like faux columns or the effect I wanted to achieve in my homepage or the -prefix-free page where the background is only shown on one side and hidden on the other:\n\n\n\nCombining with background-size\n\nWe can do wonders, however, if we combine this with the CSS3 background-size property:\n\nbackground: linear-gradient(left, white 50%, #8b0 50%);\nbackground-size: 100px 100px;\n\n See this example live\n\nAnd there it is. We just created the simplest of patterns: (vertical) stripes. We can remove the first parameter (left) or replace it with top and we\u2019ll get horizontal stripes. However, let\u2019s face it: Horizontal and vertical stripes are kinda boring. Most stripey backgrounds we see on the web are diagonal. So, let\u2019s try doing that.\n\nOur first attempt would be to change the angle of the gradient to something like 45deg. However, this results in an ugly pattern like this: \n\n See this example live\n\nBefore reading on, think for a second: why didn\u2019t this produce the desired result? Can you figure it out?\n\nThe reason is that the gradient angle rotates the gradient inside each tile, not the tiled background as a whole. However, didn\u2019t we have the same problem the first time we tried to create diagonal stripes with an image? And then we learned that every stripe has to be included twice, like so:\n\n\n\nSo, let\u2019s try to create that effect with CSS gradients. It\u2019s essentially what we tried before, but with more color stops:\n\nbackground: linear-gradient(45deg, white 25%,\n #8b0 25%, #8b0 50%, \n white 50%, white 75%, \n #8b0 75%);\nbackground-size:100px 100px;\n\n See this example live\n\nAnd there we have our stripes! An easy way to remember the order of the percentages and colors it is that you always have two of the same in succession, except the first and last color.\n\nNote: Firefox for Mac also needs an additional 100% color stop at the end of any pattern with more than two stops, like so: ..., white 75%, #8b0 75%, #8b0). The bug was reported in February 2011 and you can vote for it and track its progress at Bugzilla.\n\nUnfortunately, this is essentially a hack and we will realize that if we try to change the gradient angle to 60deg:\n\n See this example live\n\nNot that maintainable after all, eh? Luckily, CSS3 offers us another way of declaring such backgrounds, which not only helps this case but also results in much more concise code:\n\nbackground: repeating-linear-gradient(60deg, white, white 35px, #8b0 35px, #8b0 70px);\n\n See this example live\n\nIn this case, however, the size has to be declared in the color stop positions and not through background-size, since the gradient is supposed to cover the entire container. You might notice that the declared size is different from the one specified the previous way. This is because the size of the stripes is measured differently: in the first example we specify the dimensions of the tile itself; in the second, the width of the stripes (35px), which is measured diagonally.\n\nMultiple backgrounds\n\nUsing only one gradient you can create stripes and that\u2019s about it. There are a few more patterns you can create with just one gradient (linear or radial) but they are more or less boring and ugly. Almost every pattern in my gallery contains a number of different backgrounds. For example, let\u2019s create a polka dot pattern:\n\nbackground: radial-gradient(circle, white 10%, transparent 10%),\nradial-gradient(circle, white 10%, black 10%) 50px 50px;\nbackground-size:100px 100px;\n\n See this example live\n\nNotice that the two gradients are almost the same image, but positioned differently to create the polka dot effect. The only difference between them is that the first (topmost) gradient has transparent instead of black. If it didn\u2019t have transparent regions, it would effectively be the same as having a single gradient, as the topmost gradient would obscure everything beneath it.\n\nThere is an issue with this background. Can you spot it?\n\nThis background will be fine for browsers that support CSS gradients but, for browsers that don\u2019t, it will be transparent as the whole declaration is ignored. We have two ways to provide a fallback, each for different use cases. We have to either declare another background before the gradient, like so:\n\nbackground: black;\nbackground: radial-gradient(circle, white 10%, transparent 10%),\nradial-gradient(circle, white 10%, black 10%) 50px 50px;\nbackground-size:100px 100px;\n\nor declare each background property separately:\n\nbackground-color: black;\nbackground-image: radial-gradient(circle, white 10%, transparent 10%),\nradial-gradient(circle, white 10%, transparent 10%);\nbackground-size:100px 100px;\nbackground-position: 0 0, 50px 50px;\n\nThe vigilant among you will have noticed another change we made to our code in the last example: we altered the second gradient to have transparent regions as well. This way background-color serves a dual purpose: it sets both the fallback color and the background color of the polka dot pattern, so that we can change it with just one edit. Always strive to make code that can be modified with the least number of edits. You might think that it will never be changed in that way but, almost always, given enough time, you\u2019ll be proved wrong.\n\nWe can apply the exact same technique with linear gradients, in order to create checkerboard patterns out of right triangles:\n\nbackground-color: white;\nbackground-image: linear-gradient(45deg, black 25%, transparent 25%, transparent 75%, black 75%), \nlinear-gradient(45deg, black 25%, transparent 25%, transparent 75%, black 75%);\nbackground-size:100px 100px;\nbackground-position: 0 0, 50px 50px;\n\n See this example live\n\nUsing the right units\n\nDon\u2019t use pixels for the sizes without any thought. In some cases, ems make much more sense. For example, when you want to make a lined paper background, you want the lines to actually follow the text. If you use pixels, you have to change the size every time you change font-size. If you set the background-size in ems, it will naturally follow the text and you will only have to update it if you change line-height.\n\nIs it possible?\n\nThe shapes that can be achieved with only one gradient are:\n\n\n\tstripes\n\tright triangles\n\tcircles and ellipses\n\tsemicircles and other shapes formed from slicing ellipses horizontally or vertically\n\n\nYou can combine several of them to create squares and rectangles (two right triangles put together), rhombi and other parallelograms (four right triangles), curves formed from parts of ellipses, and other shapes.\n\nJust because you can doesn\u2019t mean you should\n\nTechnically, anything can be crafted with these techniques. However, not every pattern is suitable for it. The main advantages of this technique are:\n\n\n\tno extra HTTP requests\n\tshort code\n\thuman-readable code (unlike data URIs) that can be changed without even leaving the CSS file.\n\n\nComplex patterns that require a large number of gradients are probably better left to SVG or bitmap images, since they negate almost every advantage of this technique:\n\n\n\tthey are not shorter\n\tthey are not really comprehensible \u2013 changing them requires much more effort than using an image editor\n\n\nThey still save an HTTP request, but so does a data URI.\n\nI have included some very complex patterns in my gallery, because even though I think they shouldn\u2019t be used in production (except under very exceptional conditions), understanding how they work and coding them helps somebody understand the technology in much more depth.\n\nAnother rule of thumb is that if your pattern needs shapes to obscure parts of other shapes, like in the star pattern or the yin yang pattern, then you probably shouldn\u2019t use it. In these patterns, changing the background color requires you to also change the color of these shapes, making edits very tedious.\n\nIf a certain pattern is not practicable with a reasonable amount of CSS, that doesn\u2019t mean you should resort to bitmap images. SVG is a very good alternative and is supported by all modern browsers.\n\nBrowser support\n\nCSS gradients are supported by Firefox 3.6+, Chrome 10+, Safari 5.1+ and Opera 11.60+ (linear gradients since Opera 11.10). Support is also coming in Internet Explorer when IE10 is released. You can get gradients in older WebKit versions (including most mobile browsers) by using the proprietary -webkit-gradient(), if you really need them.\n\nEpilogue\n\nI hope you find these techniques useful for your own designs. If you come up with a pattern that\u2019s very different from the ones already included, especially if it demonstrates a cool new technique, feel free to send a pull request to the github repo of the patterns gallery. Also, I\u2019m always fascinated to see my techniques put in practice, so if you made something cool and used CSS patterns, I\u2019d love to know about it!\n\nHappy holidays!", "year": "2011", "author": "Lea Verou", "author_slug": "leaverou", "published": "2011-12-16T00:00:00+00:00", "url": "https://24ways.org/2011/css3-patterns-explained/", "topic": "code"} {"rowid": 288, "title": "Displaying Icons with Fonts and Data- Attributes", "contents": "Traditionally, bitmap formats such as PNG have been the standard way of delivering iconography on websites. They\u2019re quick and easy, and it also ensures they\u2019re as pixel crisp as possible. Bitmaps have two drawbacks, however: multiple HTTP requests, affecting the page\u2019s loading performance; and a lack of scalability, noticeable when the page is zoomed or viewed on a screen with a high pixel density, such as the iPhone 4 and 4S.\n\nThe requests problem is normally solved by using CSS sprites, combining the icon set into one (physically) large image file and showing the relevant portion via background-position. While this works well, it can get a bit fiddly to specify all the positions. In particular, scalability is still an issue. A vector-based format such as SVG sounds ideal to solve this, but browser support is still patchy.\n\n\n\nThe rise and adoption of web fonts have given us another alternative. By their very nature, they\u2019re not only scalable, but resolution-independent too. No need to specify higher resolution graphics for high resolution screens! \n\nThat\u2019s not all though:\n\n\n\tBrowser support: Unlike a lot of new shiny techniques, they have been supported by Internet Explorer since version 4, and, of course, by all modern browsers. We do need several different formats, however!\n\tDesign on the fly: The font contains the basic graphic, which can then be coloured easily with CSS \u2013 changing colours for themes or :hover and :focus styles is done with one line of CSS, rather than requiring a new graphic. You can also use CSS3 properties such as text-shadow to add further effects. Using -webkit-background-clip: text;, it\u2019s possible to use gradient and inset shadow effects, although this creates a bitmap mask which spoils the scalability.\n\tSmall file size: specially designed icon fonts, such as Drew Wilson\u2019s Pictos font, can be as little as 12Kb for the .woff font. This is because they contain fewer characters than a fully fledged font. You can see Pictos being used in the wild on sites like Garrett Murray\u2019s Maniacal Rage.\n\n\nAs with all formats though, it\u2019s not without its disadvantages: \n\n\n\tIcons can only be rendered in monochrome or with a gradient fill in browsers that are capable of rendering CSS3 gradients. Specific parts of the icon can\u2019t be a different colour.\n\tIt\u2019s only appropriate when there is an accompanying text to provide meaning. This can be alleviated by wrapping the text label in a tag (I like to use rather than , due to the fact that it\u2019s smaller and isn\u2019 t being used elsewhere) and then hiding it from view with text-indent:-999em.\n\tCreating an icon font can be a complex and time-consuming process. While font editors can carry out hinting automatically, the best results are achieved manually.\n\tUnless you\u2019re adept at creating your own fonts, you\u2019re restricted to what is available in the font. However, fonts like Pictos will cover the most common needs, and icons are most effective when they\u2019re using familiar conventions.\n\n\nThe main complaint about using fonts for icons is that it can mean adding a meaningless character to our markup. The good news is that we can overcome this by using one of two methods \u2013 CSS generated content or the data-icon attribute \u2013 in combination with the :before and :after pseudo-selectors, to keep our markup minimal and meaningful. \n\nOur simple markup looks like this:\n\nView Basket\n\nNote the multiple class attributes. Next, we\u2019ll import the Pictos font using the @font-face web fonts property in CSS:\n\n@font-face {\n font-family: 'Pictos';\n src: url('pictos-web.eot');\n src: local('\u263a'), \n url('pictos-web.woff') format('woff'), \n url('pictos-web.ttf') format('truetype'),\n url('pictos-web.svg#webfontIyfZbseF') format('svg');\n}\n\nThis rather complicated looking set of rules is (at the time of writing) the most bulletproof way of ensuring as many browsers as possible load the font we want. We\u2019ll now use the content property applied to the :before pseudo-class selector to generate our icon. Once again, we\u2019ll use those multiple class attribute values to set common icon styles, then specific styles for .basket. This helps us avoid repeating styles:\n\n.icon {\n font-family: 'Pictos';\n font-size: 22px:\n}\n\n.basket:before {\n content: \"$\";\n}\n\nWhat does the :before pseudo-class do? It generates the dollar character in a browser, even when it\u2019s not present in the markup. Using the generated content approach means our markup stays simple, but we\u2019ll need a new line of CSS, defining what letter to apply to each class attribute for every icon we add.\n\ndata-icon is a new alternative approach that uses the HTML5 data- attribute in combination with CSS attribute selectors. This new attribute lets us add our own metadata to elements, as long as its prefixed by data- and doesn\u2019t contain any uppercase letters. In this case, we want to use it to provide the letter value for the icon. Look closely at this markup and you\u2019ll see the data-icon attribute.\n\nView Basket\n\n\n\nWe could add others, in fact as many as we like.\n\nFavourites\nHistory\nLocation\n\n\n\nThen, we need just one CSS attribute selector to style all our icons in one go:\n\n.icon:before {\n content: attr(data-icon);\n /* Insert your fancy colours here */\n }\n\nBy placing our custom attribute data-icon in the selector in this way, we can enable CSS to read the value of that attribute and display it before the element (in this case, the anchor tag). It saves writing a lot of CSS rules. I can imagine that some may not like the extra attribute, but it does keep it out of the actual content \u2013 generated or not.\n\n\n\n\n\nThis could be used for all manner of tasks, including a media player and large simple illustrations. See the demo for live examples. Go ahead and zoom the page, and the icons will be crisp, with the exception of the examples that use -webkit-background-clip: text as mentioned earlier.\n\nFinally, it\u2019s worth pointing out that with both generated content and the data-icon method, the letter will be announced to people using screen readers. For example, with the shopping basket icon above, the reader will say \u201cdollar sign view basket\u201d. As accessibility issues go, it\u2019s not exactly the worst, but could be confusing. You would need to decide whether this method is appropriate for the audience. Despite the disadvantages, icon fonts have huge potential.", "year": "2011", "author": "Jon Hicks", "author_slug": "jonhicks", "published": "2011-12-12T00:00:00+00:00", "url": "https://24ways.org/2011/displaying-icons-with-fonts-and-data-attributes/", "topic": "code"}