Web Standards

CSS Basics: The Second “S” in CSS

Css Tricks - Wed, 02/14/2018 - 4:14am

CSS is an abbreviation for Cascading Style Sheets.

While most of the discussion about CSS on the web (or even here on CSS-Tricks) is centered around writing styles and how the cascade affects them, what we don't talk a whole lot about is the sheet part of the language. So let's give that lonely second "S" a little bit of the spotlight and understand what we mean when we say CSS is a style sheet.

The Sheet Contains the Styles

The cascade describes how styles interact with one another. The styles make up the actual code. Then there's the sheet that contains that code. Like a sheet of paper that we write on, the "sheet" of CSS is the digital file where styles are coded.

If we were to illustrate this, the relationship between the three sort of forms a cascade:

The sheet holds the styles.

There can be multiple sheets all continuing multiple styles all associated with one HTML document. The combination of those and the processes of figuring out what styles take precedence to style what elements is called the cascade (That first "C" in CSS).

The Sheet is a Digital File

The sheet is such a special thing that it's been given its own file extension: .css. You have the power to create these files on your own. Creating a CSS file can be done in any text editor. They are literally text files. Not "rich text" documents or Word documents, but plain ol' text.

If you're on Mac, then you can fire up TextEdit to start writing CSS. Just make sure it's in "Plain Text" mode.

If you're on Windows, the default Notepad app is the equivalent. Heck, you can type styles in just about any plain text editor to write CSS, even if that's not what it says it was designed to do.

Whatever tool you use, the key is to save your document as a .css file. This can usually be done by simply add that to your file name when saving. Here's how that looks in TextEdit:

Seriously, the choice of which text editor to use for writing CSS is totally up to you. There are many, many to choose from, but here are a few popular ones:

You might reach for one of those because they'll do handy things for you like syntax highlight the code (colorize different parts to help it be easier to understand what is what).

Hey look I made some files completely from scratch with my text editor:

Those files are 100% valid in any web browser, new or old. We've quite literally just made a website.

The Sheet is Linked Up to the HTML

We do need to connect the HTML and CSS though. As in make sure the styles we wrote in our sheet get loaded onto the web page.

A webpage without CSS is pretty barebones:

See the Pen Style-less Webpage by Geoff Graham (@geoffgraham) on CodePen.

Once we link up the CSS file, voila!

See the Pen Webpage With Styles by Geoff Graham (@geoffgraham) on CodePen.

How did that happen? if you look at the top of any webpage, there's going to be a <head> tag that contains information about the HTML document:

<!DOCTYPE html> <html> <head> <!-- a bunch of other stuff --> </head> <body> <!-- the page content --> </body> </html>

Even though the code inside the <head> might look odd, there is typically one line (or more, if we're using multiple stylesheets) that references the sheet. It looks something like this:

<head> <link rel="stylesheet" type="text/css" href="styles.css" /> </head>

This line tells the web browser as it reads this HTML file:

  1. I'd like to link up a style sheet
  2. Here's where it is located

You can name the sheet whatever you want:

  • styles.css
  • global.css
  • seriously-whatever-you-want.css

The important thing is to give the correct location of the CSS file, whether that's on your web server, a CDN or some other server altogether.

Here are a few examples:

<head> <!-- CSS on my server in the top level directory --> <link rel="stylesheet" type="text/css" href="styles.css"> <!-- CSS on my server in another directory --> <link rel="stylesheet" type="text/css" href="/css/styles.css"> <!-- CSS on another server --> <link rel="stylesheet" type="text/css" href="https://some-other-site/path/to/styles.css"> </head> The Sheet is Not Required for HTML

You saw the example of a barebones web page above. No web page is required to use a stylesheet.

Also, we can technically write CSS directly in the HTML using the HTML style attribute. This is called inline styling and it goes a little something like this if you imagine you're looking at the code of an HTML file:

<h1 style="font-size: 24px; line-height: 36px; color: #333333">A Headline</h1> <p style="font-size: 16px; line-height: 24px; color: #000000;">Some paragraph content.</p> <!-- and so on -->

While that's possible, there are three serious strikes against writing styles this way:

  1. If you decide to use a stylesheet later, it is extremely difficult to override inline styles with the styles in the HTML. Inline styles take priority over styles in a sheet.
  2. Maintaining all of those styles is tough if you need to make a "quick" change and it makes the HTML hard to read.
  3. There's something weird about saying we're writing CSS inline when there really is no cascade or sheet. All we're really writing are styles.

There is a second way to write CSS in the HTML and that's directly in the <head> in a <style> block:

<head> <style> h1 { color: #333; font-size: 24px; line-height: 36px; } p { color: #000; font-size: 16px; line-height: 24px; } </style> </head>

That does indeed make the HTML easier to read, already making it better than inline styling. Still, it's hard to manage all styles this way because it has to be managed on each and every webpage of a site, meaning one "quick" change might have to be done several times, depending on how many pages we're dealing with.

An external sheet that can be called once in the <head> is usually your best bet.

The Sheet is Important

I hope that you're starting to see the importance of the sheet by this point. It's a core part of writing CSS. Without it, styles would be difficult to manage, HTML would get cluttered, and the cascade would be nonexistent in at least one case.

The sheet is the core component of CSS. Sure, it often appears to play second fiddle to the first "S" but perhaps that's because we all have an quiet understanding of its importance.

Leveling Up

Now that you're equipped with information about stylesheets, here are more resources you jump into to get a deeper understanding for how CSS behaves:

CSS Basics: The Second “S” in CSS is a post from CSS-Tricks

UX Case Study: Talkspace Mobile App

Usability Geek - Tue, 02/13/2018 - 1:16pm
From all the digital innovations we are looking forward to seeing advance in 2018, perhaps none are more critical than telemedicine. Defined as the administration of critical medical services through...
Categories: Web Standards

Observable

Css Tricks - Tue, 02/13/2018 - 10:05am

Observable launched a couple of weeks ago. As far as I understand, it’s sort of like a mix between CodePen and Medium where you create "notebooks" for exploring data, making nifty visualizations.

Check out this collection of visualizations using map integrations as an example. The entries are not only nice demos of the libraries or technology being used (i.e. D3, Google Maps, Leaflet, etc.), but also make for some interesting infographics in themselves.

In a note about this interesting new format, founder Mike Bostock describes a notebook as “an interactive, editable document defined by code. It’s a computer program, but one that’s designed to be easier to read and write by humans.”

All of this stuff riffs on a lot of Mike’s previous work which is definitely worth exploring further if you’re a fan of complex visualizations on the web.

Direct Link to ArticlePermalink

Observable is a post from CSS-Tricks

CSS Grid Layout Module Level 2

Css Tricks - Tue, 02/13/2018 - 10:05am

The second iteration of CSS Grid is already in the works and the public editor's draft was released last week! While it is by no means the final W3C recommendation, this draft is the start of discussions around big concepts many of us have been wanting to see since the first level was released, including subgrids:

In some cases it might be necessary for the contents of multiple grid items to align to each other. A grid container that is itself a grid item can defer the definition of its rows and columns to its parent grid container, making it a subgrid. In this case, the grid items of the subgrid participate in sizing the grid of the parent grid container, allowing the contents of both grids to align.

The currently defined characters of subgrid items are particularly interesting because they illustrate the differences between a subgrid and its parent grid. For example:

The subgrid is always stretched in both dimensions in its subgridded dimension(s): the align-self/justify-self properties on it are ignored, as are any specified width/height constraints.

In addition to subgrids, aspect-ratio-controlled gutters and conformance are also defined in the draft and worth a read. It's great to see so much momentum around grids!

Direct Link to ArticlePermalink

CSS Grid Layout Module Level 2 is a post from CSS-Tricks

CSS Basics: Using Fallback Colors

Css Tricks - Tue, 02/13/2018 - 4:25am

Something you very much want to avoid in web design is unreadable text. That can happen when the background color of an element is too close or exactly the color of the text. For instance:

.header { background-color: white; color: white; }

Which could lead to text that's there, but invisible.

This is ... very bad.

You'd never do that on purpose of course! The trouble is it can sneak up on you. For one thing, the default background-color is transparent, so without setting any background the background of an element is probably white.

More commonly, you're using a background-image that makes the background a different color, and you're setting white text on top of that.

header { background-image: url(plants.jpg); color: white; }

Under perfect circumstances, this is all good:

But let's take a look at what it looks like while the website is loading over a very common "Slow 3G" internet connection:

There's no reason our dear visitor needs to wait to discover the incredible savings awaiting them this Sunday! Fortunately, a tiny bit of CSS solves this.

header { background-color: black; background-image: url(plants.jpg); color: white; }

The black background color will ensure the white text will be visible while the image loads (or if it never loads at all!). Getting slightly fancier, we could use a color used in the image. I like a little app called Frank DeLoupe for helping me pluck a color from anywhere on my screen. Then I'll use that color as the fallback color using the shorthand syntax for backgrounds:

header { background: #334C23 url(plants.jpg); color: white; }

Much much better.

This kind of thing takes very little effort, improves your design's resiliency and UX, and I think you'll find becomes are part of your CSS muscle memory the more you write CSS.

Another related topic here, since we're working with a photograph, is the idea of a "Progressive JPG." Photoshop has the ability to save a JPG in this format. This changes how the displays as it's coming across the network. Here's a comparison video:

A low-res version of the image loads into place first, and it becomes higher quality as more of the image loads.

Perhaps a more desirable loading experience, but not a replacement for a fallback color.

Leveling up!

Images are one of the heaviest parts of websites, and loading techniques for them are a big topic in web performance. Here are some more related to things to think about:

CSS Basics: Using Fallback Colors is a post from CSS-Tricks

Linkbait 36

QuirksBlog - Tue, 02/13/2018 - 12:32am

Facebook-bashing edition. (I’m merely quoting other people’s bashing, mind you.)

  • An overview of browser testing services because you deserve to test on IE9 and older Chromes.
  • Ada built a game in a week using tools currently available on the web. She wrote a report, and introduces many new tools in the process.
  • Bad if true: W3C uses browser detects.

    Are you aware that since Edge enabled Upgrade-Insecure-Request on our internal builds, we cannot reach any spec because we get redirected from https to http, which we upgrade to https, and loop? If we masquerade our user agent to Chrome's one all works fine.

  • Something that interests me a lot lately: Teaching CSS Grid to newcomers. Well, not specifically Grid in my case, but this article has some excellent ideas and notions about why techies find CSS so complicated, and how to explain it to them.

    Water, for explaining the cascading, global nature of CSS versus the modular, encapsulated nature of most traditional programming languages. Like, traditional programming paradigms treat functions discretely, like stones you can pick up, but CSS is like water, which flows and cannot be controlled, only shaped.

    And the author, Hui Jing Chen, is coming to speak at CSS Day, which is also kind of cool because I can quiz her in person.
  • High drama in time-honoured American fashion about Facebook having a terrible two years. Facebook once was Shiny and Golden; now it’s Hideous and Dark. The truth lies somewhere in the middle, but this article ignores that for obvious clickbait reasons.
    Much more important is the fact that Facebook-bashing has now reached serious momentum. I think that’s healthy. See also the next few items.
  • A study of fake news sites in France and Italy. It turns out the problem is somewhat less serious than was assumed; the fake news sites themselves see only very modest numbers of visitors (the most popular reached 3.5% of the online population). The real problem lies with Facebook, where some fake news items generate more interactions that real news items.
    Facebook is the problem (and Twitter, too, I suppose, but to a lesser degree). That’s something I already assumed, but it’s very good to have it confirmed by research.
    So what are we going to do about it? Block Facebook? It’s too early for that, but the option must be on some internal lists higher up in the EU. If Facebook refuses to take action, we should.
  • An anti-capitalist look at tech’s trust problem.

    But tech appears to have no net positive uses whatsoever. Can it?

    This is somewhat disingenious: we have become accustomed to tech benefits, and the problem is more that its rate of benefit production has fallen while we’ve become more aware of its drawbacks. Still, close off the Internet and you’ll have a much worse popular revolt on your hands.
    Don’t get me wrong — I think the tech giants being taken down a notch is a good thing, but as technologists we have to be careful to define what tech we need to ditch: ads and their tracking mechanisms, the artificial stupidity that selects your Facebook/Google news — as well as, on the non-tech side, the inability to pay for services such as Facebook and Twitter.

    Tech’s challenge was never to remake capitalism all over again?—?only harder, crueller, meaner, even more harmful. It was to shift beyond it.

    I don’t buy this — at least, not entirely. Big tech and the neoliberal movement were born simultaneously in the early nineties, and early tech served as a shining example of neoliberalism while gladly accepting the money. I don’t think tech was ever meant to shift beyond capitalism — the only example I can think of is everything on the web being free of charge, and that was the worst mistake tech ever made, causing, among other things, ad tracking and fake news spread by Facebook’s artificial stupidity.
    Still, food for thought.
  • Remember Facebook Instant Articles that was going to revolutionise news content online? It turns out that more than half of the original 2015 partners have meanwhile abandoned it — and these are not the smallest names in newspaper publishing, either. Apparently it doesn’t work. Also, Facebooks’s announce algorithm change I mentioned in 34 is not going to help here.
  • Unilever is threatening to pull its ads from Facebook and Google (Guardian; NRC) because those companies do not remove posts that “create division in society and promote anger and hate.”
    Unilever is in fact not the first food/personal care multinational to do so: big competitor Procter & Gamble did the same about a year ago. Also in that last article: the tech giants have a trust problem right now, while trust in traditional journalism is increasing.
  • How the EU is exporting its data and privacy regulations to the rest of the world. It’s the EU that’s setting the standard here; not the US, which is more meh about regulations and privacy, especially under the current administration.
    Having sane leaders is a major competitive advantage right now.
    On the other hand, the EU regulations are more-or-less forced onto some countries, who could do with a little less neocolonial paternalism. On the gripping hand, the most important quoted example of such countries, South Africa, is not one that has a great trust in its own government, with Zuma about to resign. So maybe an enforced bit of regulation would be good for it nonetheless?
    Conundrums, conundrums.
  • According to Google, 1% of publishers will be affected by the upcoming selective Chrome ad blocker. To be honest I didn’t know Google was working on this, and I think it’s a good idea — especially in order to force internet advertisers to adapt or die.
  • An older game, but a rather good one, on the evolution of trust. Makes you play the game in order to understand trust/distrust strategies.
  • How to build a horse with various programming languages. JavaScript: the backbone came out angular, so the horse is paralyzed. Perfect summary.
  • Your users are irrational. Interesting read about how people can trick our fast intuitive brain into doing things without thinking, or, even more interesting, how to get our fast intuitive brain to start up our slow logical brain. And how all that applies to designing websites or apps.
  • Something that interests me as a conference organiser: Name badges, the unsung conference heroes. We did some thinking about name badges years ago (see the summary), but this article contains several interesting new ideas, notably adding interests to the badge in order to facilitate conversations.
  • Have a tip for the next Linkbait? Or a comment on this one? Let me know (or here or here).

Quantitative And Qualitative Analytics: The Perfect Data Power Couple

Usability Geek - Mon, 02/12/2018 - 12:02pm
February is here and love is in the air. A new couple has made things “Facebook Official”, and I just cannot contain my excitement. They are setting the bar so high regarding commitment...
Categories: Web Standards

Web Animation Workshops Dates for 2018 Announced

Css Tricks - Mon, 02/12/2018 - 7:38am

"I'm getting a raise!"

This was my favorite quote from last year's Web Animation Workshops, as Val and I covered performance, tooling, and creating animations for SVG, CSS, JS and React.

Now we're gearing up for another round of Web Animation Workshops in 2018! But we're only offering two workshops this time since both of us have moved away from full-time consulting.

The aim of these workshops is to level up your animation skills in just two days and equip you with a full understanding of animation concepts without having to rely on copying and pasting code from other people in your web applications.

These are the dates and locations:

  • Chicago: March 19 - 20
  • Brighton, UK: July 9 - 10

We're already out of early bird tickets for Chicago and space is limited, so grab yours quickly before they sell out.

We'll see you there!

Direct Link to ArticlePermalink

Web Animation Workshops Dates for 2018 Announced is a post from CSS-Tricks

CSS Basics: The Syntax That Matters & The Syntax That Doesn’t

Css Tricks - Mon, 02/12/2018 - 4:28am

When you're starting to play around with CSS at the very beginning, like any other language, you have to get used to the syntax. Like any syntax, there are a bunch of little things you need to know. Some characters and the placement of them is very important and required for the CSS to work correctly. And some characters are more about clean looking code and generally followed standards but don't matter for the CSS to work.

First, so we have the terminology down:

A CSS ruleset consists of a selector and delcaration(s) wrapped in curly braces. Important: Braces

All CSS rulesets must have opening and closing curly braces:

braces.header { padding: 20px;}.header padding: 20px;}.header { padding: 20px;}.header padding: 20px;

If you miss the opening brace, CSS will keep reading as if the next bit of text is still part of the selector. Then it's likely to find a character like : which are invalid as part of a selector and break. Breaking likely means it will screw up itself and the next ruleset, and recover after that.

Missing a closing brace is a bit worse in that it's likely to mess up the rest of the entire CSS file unless it somehow finds a double closing brace and can resolve that first missing one.

Overall point: braces are very important!

Preprocessing languages like Sass and Less offer a syntax feature called nesting. This can be convenient, but note that when these preprocessors run and produce CSS, that nesting is removed because CSS by itself doesn't support that. If you copy nested CSS into regular CSS, you'll have problems with the braces.

Sometimes Important: Spaces

There are just a few places that spaces are important in CSS. One of the most imortant is in selectors. One space in a selector means you're selecting descendants of the previous part of the selector. The selector body p means "select p elements that are descendants of the body element". That space means a lot. Hopefully it's clearly different than bodyp which won't select anything (there is no <bodyp> element). But it's not different from body p. Multiple spaces mean the same as one space.

spacesbody ul libodyulli.header .title.header .title.header .title.header.title??=

You can't put spaces in properties, function names, or anywhere you name things. Adding spaces in those situations effectively changes the names, breaking them.

spaces-3background-image: url(tiger.jpg);background - image: url(tiger.jpg);background-image: url (tiger.jpg);@keyframes goRoundAndRound { }@keyframes go-round-and-round { }@keyframes go round and round { }:root { --theme main: red; --theme-second: red;}body { background: var(--theme main); background: var(--theme-second);}

Other than that, spacing doesn't matter much in CSS.

spaces_1.header { padding: 20px;}.header { padding:20px; } .header {padding: 20px; }.header{padding: 20px; }.header{ padding: 20px;}.header{padding:20px;}

I'd encourage you to be consistent with your spacing, and produce clean and readable CSS. You might want to reference some CSS style guides out there for some formatting best practices.

Even the !important rule in CSS, which comes after a the value in a delcaration like body { background: white !important; } doesn't have any spacing requirements. It could have any amount of space before it, or none.

The removing of space in CSS is actually a best practice for performance, so you might notice that when peeking at the raw CSS of websites in production.

You're better off leaving that minification of CSS to a tool that processes your CSS for you, leaving the original alone. We'll have to cover the options for that in other post.

Mostly Important: Semicolons

Each declaration in a ruleset (a property and value pair) ends in a semicolon. That semicolon is required, otherwise CSS will keep reading the next property as if it's part of the value of the previous declaration.

semicolons.header { padding: 20px; max-width: 600px; background: black; color: white}.header { padding: 20px; max-width: 600px background: black; color: white;}

You can leave off the semicolon on the last declaration in a ruleset. I'd warn that doing so manually will cause more trouble than it's worth, and best left to minification tools.

Important: Avoiding Stray Characters

This is important in any language. Every character in code matters, so random other characters will almost certainly break things.

extra-chars.header { padding: 20px;}.header { { padding: 20px;}.header { padding: ~20px;}.header { /padding: 20px;}

Not Important: Line Breaks

A line break is treated like any other white space in CSS, so feel free to use them as needed, as long as it doesn't break any other spacing rule like we talked about above.

line-breaks.bar { background-image: url(texture.png), url(tiger.jpg); }.button::after { content: ">";} .header { box-shadow: 0 0 5px rgba(0, 0, 0, 0.5), 20px 2px 5px -5px rgba(0, 0, 0, 0.5);}

All in all, CSS syntax isn't so hard. Good luck!

CSS Basics: The Syntax That Matters & The Syntax That Doesn’t is a post from CSS-Tricks

Stimulus

Css Tricks - Sat, 02/10/2018 - 1:32pm

A modest JavaScript framework for the HTML you already have.

This will appeal to anyone who is apprehensive about JavaScript being required to generate HTML, yet wants a modern framework to help with modern problems, like state management.

I wonder if this would be a good answer for things like WordPress or CraftCMS themes that are designed to be server side but, like any site, could benefit from client-side JavaScript enhancements. Stimulus isn't really built to handle SPAs, but instead pair with Turbolinks. That way, you're still changing out page content with JavaScript, but all the routing and HTML generation is server side. Kinda old school meets new school.

Direct Link to ArticlePermalink

Stimulus is a post from CSS-Tricks

Article Performance Leaderboard

Css Tricks - Sat, 02/10/2018 - 4:30am

A clever idea from Michael Donohoe: pit websites against each other in a performance battle! Donohoe is a long-time newsroom guy, so this is specifically about article pages for major publications.

Lets state the obvious, this is an imperfect and evolving measure and the goal is to foster discussion and rivalry in making our pages better, faster, and lighter. Bear in mind this was built as an internal tool at Hearst Newspapers to track changes as we rollout our new Article template on mobile for SFGate and eventually all sites (SF Chronicle, Houston Chronicle, Times Union, etc).

Developers, designers, and product need to talk more on how to achieve this. A 1,700 word article might weigh 10KB but by the time you load HTML, JS, CSS, images, 3rd-parties, and ads, it can range between 2MB to 8MB depending on the web site. Bear in mind, the first Harry Potter ebook is 1.1MB and that includes cover art.

Interested in how it works? Learn about how to use the WebPageTest API or even spin up a service of your own.

Direct Link to ArticlePermalink

Article Performance Leaderboard is a post from CSS-Tricks

PixelSnap

Css Tricks - Fri, 02/09/2018 - 5:06am

Forever I've used the macOS Command-Shift-4 screenshot utility to measure things. Pressing it gets you a little crosshairs cursor which you can click-and-drag to take a screenshot but, crucially, has little numbers that tell you the width/height of the selection in pixels. It's crude, but ever so useful.

See those teeny-tiny numbers in the bottom-right? So useful, even if they are tough to read.

PixelSnap is one of those apps that, once you see it, you're like OMG that's the best idea ever. It's the same kind of interaction (key command, then mouse around), but it's drawing lines between obvious measurement points in any window at all. Plus it has this drag around and area and snap to edges thing that's just as brilliant. Instant purchase for me.

The Product Hunt newsletter said:

Two teenage makers launched PixelSnap, a powerful design tool to measure every pixel on your screen. Hit #1 on Product Hunt, and over $5,000 in sales within 24 hours of their launch. &#x1f4dd;✨

Hey, even cooler!

A couple people pointed out xScope, which also has this feature. Fifty bucks, but also has a ton of other features. Tempting.

Direct Link to ArticlePermalink

PixelSnap is a post from CSS-Tricks

Direction Aware Hover Effects

Css Tricks - Fri, 02/09/2018 - 4:24am

This is a particular design trick that never fails to catch people's eye! I don't know the exact history of who-thought-of-what first and all that, but I know I have seen a number of implementations of it over the years. I figured I'd round a few of them up here.

Noel Delagado

See the Pen Direction-aware 3D hover effect (Concept) by Noel Delgado (@noeldelgado) on CodePen.

The detection here is done by tracking the mouse position on mouseover and mouseout and calculating which side was crossed. It's a small amount of clever JavaScript, the meat of which is figuring out that direction:

var getDirection = function (ev, obj) { var w = obj.offsetWidth, h = obj.offsetHeight, x = (ev.pageX - obj.offsetLeft - (w / 2) * (w > h ? (h / w) : 1)), y = (ev.pageY - obj.offsetTop - (h / 2) * (h > w ? (w / h) : 1)), d = Math.round( Math.atan2(y, x) / 1.57079633 + 5 ) % 4; return d; };

Then class names are applied depending on that direction to trigger the directional CSS animations.

Fabrice Weinberg

See the Pen Direction aware hover pure CSS by Fabrice Weinberg (@FWeinb) on CodePen.

Fabrice uses just pure CSS here. They don't detect the outgoing direction, but they do detect the incoming direction by way of four hidden hoverable boxes, each rotated to cover a triangle. Like this:

Codrops Demo

In an article by Mary Lou on Codrops from 2012, Direction-Aware Hover Effect with CSS3 and jQuery, the detection is also done in JavaScript. Here's that part of the plugin:

_getDir: function (coordinates) { // the width and height of the current div var w = this.$el.width(), h = this.$el.height(), // calculate the x and y to get an angle to the center of the div from that x and y. // gets the x value relative to the center of the DIV and "normalize" it x = (coordinates.x - this.$el.offset().left - (w / 2)) * (w > h ? (h / w) : 1), y = (coordinates.y - this.$el.offset().top - (h / 2)) * (h > w ? (w / h) : 1), // the angle and the direction from where the mouse came in/went out clockwise (TRBL=0123); // first calculate the angle of the point, // add 180 deg to get rid of the negative values // divide by 90 to get the quadrant // add 3 and do a modulo by 4 to shift the quadrants to a proper clockwise TRBL (top/right/bottom/left) **/ direction = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4; return direction; },

It's technically CSS doing the animation though, as inline styles are applied as needed to the elements.

John Stewart

See the Pen Direction Aware Hover Goodness by John Stewart (@johnstew) on CodePen.

John leaned on Greensock to do all the detection and animation work here. Like all the examples, it has its own homegrown geometric math to calculate the direction in which the elements were hovered.

// Detect Closest Edge function closestEdge(x,y,w,h) { var topEdgeDist = distMetric(x,y,w/2,0); var bottomEdgeDist = distMetric(x,y,w/2,h); var leftEdgeDist = distMetric(x,y,0,h/2); var rightEdgeDist = distMetric(x,y,w,h/2); var min = Math.min(topEdgeDist,bottomEdgeDist,leftEdgeDist,rightEdgeDist); switch (min) { case leftEdgeDist: return "left"; case rightEdgeDist: return "right"; case topEdgeDist: return "top"; case bottomEdgeDist: return "bottom"; } } // Distance Formula function distMetric(x,y,x2,y2) { var xDiff = x - x2; var yDiff = y - y2; return (xDiff * xDiff) + (yDiff * yDiff); } Gabrielle Wee

See the Pen CSS-Only Direction-Aware Cube Links by Gabrielle Wee ✨ (@gabriellewee) on CodePen.

Gabrielle gets it done entirely in CSS by positioning four hoverable child elements which trigger the animation on a sibling element (the cube) depending on which one was hovered. There is some tricky stuff here involving clip-path and transforms that I admit I don't fully understand. The hoverable areas don't appear to be triangular like you might expect, but rectangles covering half the area. It seems like they would overlap ineffectively, but they don't seem to. I think it might be that they hang off the edges slightly giving a hover area that allows each edge full edge coverage.

Elmer Balbin

See the Pen Direction Aware Tiles using clip-path Pure CSS by Elmer Balbin (@elmzarnsi) on CodePen.

Elmer is also using clip-path here, but the four hoverable elements are clipped into triangles. You can see how each of them has a point at 50% 50%, the center of the square, and has two other corner points.

clip-path: polygon(0 0, 100% 0, 50% 50%) clip-path: polygon(100% 0, 100% 100%, 50% 50%); clip-path: polygon(0 100%, 50% 50%, 100% 100%); clip-path: polygon(0 0, 50% 50%, 0 100%); Nigel O Toole Demo

Raw JavaScript powers Nigel's demo here, which is all modernized to work with npm and modules and all that. It's familiar calculations though:

const _getDirection = function (e, item) { // Width and height of current item let w = item.offsetWidth; let h = item.offsetHeight; let position = _getPosition(item); // Calculate the x/y value of the pointer entering/exiting, relative to the center of the item. let x = (e.pageX - position.x - (w / 2) * (w > h ? (h / w) : 1)); let y = (e.pageY - position.y - (h / 2) * (h > w ? (w / h) : 1)); // Calculate the angle the pointer entered/exited and convert to clockwise format (top/right/bottom/left = 0/1/2/3). See https://stackoverflow.com/a/3647634 for a full explanation. let d = Math.round(Math.atan2(y, x) / 1.57079633 + 5) % 4; // console.table([x, y, w, h, e.pageX, e.pageY, item.offsetLeft, item.offsetTop, position.x, position.y]); return d; };

The JavaScript ultimately applies classes, which are animated in CSS based on some fancy Sass-generated animations.

Giana

A CSS-only take that handles the outgoing direction nicely!

See the Pen CSS-only directionally aware hover by Giana (@giana) on CodePen.

Seen any others out there? Ever used this on something you've built?

Direction Aware Hover Effects is a post from CSS-Tricks

A Lifetime of Nerdery (Video)

Css Tricks - Fri, 02/09/2018 - 3:40am

I converted my slides into an article for this talk not too long ago. The video is up now, if that's more your speed:

A Lifetime of Nerdery (Video) is a post from CSS-Tricks

Offline *Only* Viewing

Css Tricks - Thu, 02/08/2018 - 9:42am

It made the rounds a while back that Chris Bolin built a page of his personal website that could only be viewed while you are offline.

This page itself is an experiment in that vein: What if certain content required us to disconnect? What if readers had access to that glorious focus that makes devouring a novel for hours at a time so satisfying? What if creators could pair that with the power of modern devices? Our phones and laptops are amazing platforms for inventive content—if only we could harness our own attention.

Now Bolin has a whole magazine around this same concept called The Disconnect!

The Disconnect is an offline-only, digital magazine of commentary, fiction, and poetry. Each issue forces you to disconnect from the internet, giving you a break from constant distractions and relentless advertisements.

I believe it's some Service Worker trickery to serve different files depending on the state of the network. Usually, Service Workers are meant to serve cached files when the network is off or slow such as to make the website continue to work. This flips that logic on its head, preventing files from being served until the network is off.

Offline *Only* Viewing is a post from CSS-Tricks

Wufoo Forms Integrate With Everything

Css Tricks - Thu, 02/08/2018 - 4:29am

(This is a sponsored post.)

Wufoo helps you build forms you can put on any website. There's a million reasons you might need to do that, from the humble contact form, to a sales lead generation form, to a sales or registration form.

That's powerful and useful all by itself. But Wufoo is even more powerful when you consider that it integrates with over 1,000 other web services.

Direct Link to ArticlePermalink

Wufoo Forms Integrate With Everything is a post from CSS-Tricks

Using Default Parameters in ES6

Css Tricks - Thu, 02/08/2018 - 4:13am

I’ve recently begun doing more research into what’s new in JavaScript, catching up on a lot of the new features and syntax improvements that have been included in ES6 (i.e. ES2015 and later).

You’ve likely heard about and started using the usual stuff: arrow functions, let and const, rest and spread operators, and so on. One feature, however, that caught my attention is the use of default parameters in functions, which is now an official ES6+ feature. This is the ability to have your functions initialize parameters with default values even if the function call doesn’t include them.

The feature itself is pretty straightforward in its simplest form, but there are quite a few subtleties and gotchas that you’ll want to note, which I’ll try to make clear in this post with some code examples and demos.

Default Parameters in ES5 and Earlier

A function that automatically provides default values for undeclared parameters can be a beneficial safeguard for your programs, and this is nothing new.

Prior to ES6, you may have seen or used a pattern like this one:

function getInfo (name, year, color) { year = (typeof year !== 'undefined') ? year : 2018; color = (typeof color !== 'undefined') ? color : 'Blue'; // remainder of the function... }

In this instance, the getInfo() function has only one mandatory parameter: name. The year and color parameters are optional, so if they’re not provided as arguments when getInfo() is called, they’ll be assigned default values:

getInfo('Chevy', 1957, 'Green'); getInfo('Benz', 1965); // default for color is "Blue" getInfo('Honda'); // defaults are 2018 and "Blue"

Try it on CodePen

Without this kind of check and safeguard in place, any uninitiated parameters would default to a value of undefined, which is usually not desired.

You could also use a truthy/falsy pattern to check for parameters that don’t have values:

function getInfo (name, year, color) { year = year || 2018; color = color || 'Blue'; // remainder of the function... }

But this may cause problems in some cases. In the above example, if you pass in a value of 0 for the year, the default 2018 will override it because 0 evaluates as falsy. In this specific example, it’s unlikely you’d be concerned about that, but there are many cases where your app might want to accept a value of 0 as a valid number rather than a falsy value.

Try it on CodePen

Of course, even with the typeof pattern, you may have to do further checks to have a truly bulletproof solution. For example, you might expect an optional callback function as a parameter. In that case, checking against undefined alone wouldn’t suffice. You’d also have to check if the passed-in value is a valid function.

So that’s a bit of a summary covering how we handled default parameters prior to ES6. Let’s look at a much better way.

Default Parameters in ES6

If your app requires that you use pre-ES6 features for legacy reasons or because of browser support, then you might have to do something similar to what I’ve described above. But ES6 has made this much easier. Here’s how to define default parameter values in ES6 and beyond:

function getInfo (name, year = 2018, color = 'blue') { // function body here... }

Try it on CodePen

It’s that simple.

If year and color values are passed into the function call, the values passed in as arguments will supersede the ones defined as parameters in the function definition. This works exactly the same way as with the ES5 patterns, but without all that extra code. Much easier to maintain, and much easier to read.

This feature can be used for any of the parameters in the function head, so you could set a default for the first parameter along with two other expected values that don’t have defaults:

function getInfo (name = 'Pat', year, color) { // function body here... } Dealing With Omitted Values

Note that—in a case like the one above—if you wanted to omit the optional name argument (thus using the default) while including a year and color, you’d have to pass in undefined as a placeholder for the first argument:

getInfo(undefined, 1995, 'Orange');

If you don’t do this, then logically the first value will always be assumed to be name.

The same would apply if you wanted to omit the year argument (the second one) while including the other two (assuming, of course, the second parameter is optional):

getInfo('Charlie', undefined, 'Pink');

I should also note that the following may produce unexpected results:

function getInfo (name, year = 1965, color = 'blue') { console.log(year); // null } getInfo('Frankie', null, 'Purple');

Try it on CodePen

In this case, I’ve passed in the second argument as null, which might lead some to believe the year value inside the function should be 1965, which is the default. But this doesn’t happen, because null is considered a valid value. And this makes sense because, according to the spec, null is viewed by the JavaScript engine as the intentional absence of an object’s value, whereas undefined is viewed as something that happens incidentally (e.g. when a function doesn’t have a return value it returns undefined).

So make sure to use undefined and not null when you want the default value to be used. Of course, there might be cases where you want to use null and then deal with the null value within the function body, but you should be familiar with this distinction.

Default Parameter Values and the arguments Object

Another point worth mentioning here is in relation to the arguments object. The arguments object is an array-like object, accessible inside a function’s body, that represents the arguments passed to a function.

In non-strict mode, the arguments object reflects any changes made to the argument values inside the function body. For example:

function getInfo (name, year, color) { console.log(arguments); /* [object Arguments] { 0: "Frankie", 1: 1987, 2: "Red" } */ name = 'Jimmie'; year = 1995; color = 'Orange'; console.log(arguments); /* [object Arguments] { 0: "Jimmie", 1: 1995, 2: "Orange" } */ } getInfo('Frankie', 1987, 'Red');

Try it on CodePen

Notice in the above example, if I change the values of the function’s parameters, those changes are reflected in the arguments object. This feature was viewed as more problematic than beneficial, so in strict mode the behavior is different:

function getInfo (name, year, color) { 'use strict'; name = 'Jimmie'; year = 1995; color = 'Orange'; console.log(arguments); /* [object Arguments] { 0: "Frankie", 1: 1987, 2: "Red" } */ } getInfo('Frankie', 1987, 'Red');

Try it on CodePen

As shown in the demo, in strict mode the arguments object retains its original values for the parameters.

That brings us to the use of default parameters. How does the arguments object behave when the default parameters feature is used? Take a look at the following code:

function getInfo (name, year = 1992, color = 'Blue') { console.log(arguments.length); // 1 console.log(year, color); // 1992 // "Blue" year = 1995; color = 'Orange'; console.log(arguments.length); // Still 1 console.log(arguments); /* [object Arguments] { 0: "Frankie" } */ console.log(year, color); // 1995 // "Orange" } getInfo('Frankie');

Try it on CodePen

There are a few things to note in this example.

First, the inclusion of default parameters doesn’t change the arguments object. So, as in this case, if I pass only one argument in the functional call, the arguments object will hold a single item—even with the default parameters present for the optional arguments.

Second, when default parameters are present, the arguments object will always behave the same way in strict mode and non-strict mode. The above example is in non-strict mode, which usually allows the arguments object to be modified. But this doesn’t happen. As you can see, the length of arguments remains the same after modifying the values. Also, when the object itself is logged, the name value is the only one present.

Expressions as Default Parameters

The default parameters feature is not limited to static values but can include an expression to be evaluated to determine the default value. Here’s an example to demonstrate a few things that are possible:

function getAmount() { return 100; } function getInfo (name, amount = getAmount(), color = name) { console.log(name, amount, color) } getInfo('Scarlet'); // "Scarlet" // 100 // "Scarlet" getInfo('Scarlet', 200); // "Scarlet" // 200 // "Scarlet" getInfo('Scarlet', 200, 'Pink'); // "Scarlet" // 200 // "Pink"

Try it on CodePen

There are a few things to take note of in the code above. First, I’m allowing the second parameter, when it’s not included in the function call, to be evaluated by means of the getAmount() function. This function will be called only if a second argument is not passed in. This is evident in the second getInfo() call and the subsequent log.

The next key point is that I can use a previous parameter as the default for another parameter. I’m not entirely sure how useful this would be, but it’s good to know it’s possible. As you can see in the above code, the getInfo() function sets the third parameter (color) to equal the first parameter’s value (name), if the third parameter is not included.

And of course, since it’s possible to use functions to determine default parameters, you can also pass an existing parameter into a function used as a later parameter, as in the following example:

function getFullPrice(price) { return (price * 1.13); } function getValue (price, pricePlusTax = getFullPrice(price)) { console.log(price.toFixed(2), pricePlusTax.toFixed(2)) } getValue(25); // "25.00" // "28.25" getValue(25, 30); // "25.00" // "30.00"

Try it on CodePen

In the above example, I’m doing a rudimentary tax calculation in the getFullPrice() function. When this function is called, it uses the existing price parameter as part of the pricePlusTax evaluation. As mentioned earlier, the getFullPrice() function is not called if a second argument is passed into getValue() (as demonstrated in the second getValue() call).

Two things to keep in mind with regards to the above. First, the function call in the default parameter expression needs to include the parentheses, otherwise you’ll receive a function reference rather than an evaluation of the function call.

Second, you can only reference previous parameters with default parameters. In other words, you can’t reference the second parameter as an argument in a function to determine the default of the first parameter:

// this won't work function getValue (pricePlusTax = getFullPrice(price), price) { console.log(price.toFixed(2), pricePlusTax.toFixed(2)) } getValue(25); // throws an error

Try it on CodePen

Similarly, as you would expect, you can’t access a variable defined inside the function body from a function parameter.

Conclusion

That should cover just about everything you’ll need to know to get the most out of using default parameters in your functions in ES6 and above. The feature itself is quite easy to use in its simplest form but, as I’ve discussed here, there are quite a few details worth understanding.

If you’d like to read more on this topic, here are some sources:

Using Default Parameters in ES6 is a post from CSS-Tricks

Brand And Experience

Usability Geek - Wed, 02/07/2018 - 1:17pm
Strong experience is an important, often key factor to the success of an endeavour like a start-up or launching a new service or brand. People walk away from an interaction with a company that offers...
Categories: Web Standards

Fallbacks for Videos-as-Images

Css Tricks - Wed, 02/07/2018 - 11:25am

Safari 11.1 shipped a strange-but-very-useful feature: the ability to use a video source in the <img> tag. The idea is it does the same job as a GIF (silent, autoplaying, repeating), but with big performance gains. How big? "20x faster and decode 7x faster than the GIF equivalent," says Colin Bendell.

Not all browsers support this so, to do a fallback, the <picture> element is ready. Bruce Lawson shows how easy it can be:

<picture> <source type="video/mp4" srcset="adorable-cat.mp4"> <!-- perhaps even an animated WebP fallback here as well --> <img src="adorable-cat.gif" alt="adorable cat tears throat out of owner and eats his eyeballs"> </picture>

Šime Vidas notes you get wider browser support by using the <video> tag:

<video src="https://media.giphy.com/media/klIaoXlnH9TMY/giphy.mp4" muted autoplay loop playsinline></video>

But as Bendell noted, the performance benefits aren't there with video, notably the fact that video isn't helped out by the preloader. Sadly, <video> it is for now, as:

there is this nasty WebKit bug in Safari that causes the preloader to download the first <source> regardless of the mimetype declaration. The main DOM loader realizes the error and selects the correct one. However, the damage will be done. The preloader squanders its opportunity to download the image early and on top of that, downloads the wrong version wasting bytes. The good news is that I’ve patched this bug and it should land in Safari TP 45.

In short, using the <picture> and <source type> for mime-type selection is not advisable until the next version of Safari reaches the 90%+ of the user base.

Still, eventually, it'll be quite useful.

Fallbacks for Videos-as-Images is a post from CSS-Tricks

A Short History of WaSP and Why Web Standards Matter

Css Tricks - Wed, 02/07/2018 - 4:10am

In August of 2013, Aaron Gustafson posted to the WaSP blog. He had a bittersweet message for a community that he had helped lead:

Thanks to the hard work of countless WaSP members and supporters (like you), Tim Berners-Lee’s vision of the web as an open, accessible, and universal community is largely the reality. While there is still work to be done, the sting of the WaSP is no longer necessary. And so it is time for us to close down The Web Standards Project.

If there’s just the slightest hint of wistful regret in Gustafson’s message, it’s because the Web Standards Project changed everything that had become the norm on the web during its 15+ years of service. Through dedication and developer advocacy, they hoisted the web up from a nest of browser incompatibility and meaningless markup to the standardized and feature-rich application platform most of us know today.

I previously covered what it took to bring CSS to the World Wide Web. This is the other side of that story. It was only through the efforts of many volunteers working tirelessly behind the scenes that CSS ever had a chance to become what it is today. They are the reason we have web standards at all.

Introducing Web Standards

Web standards weren't even a thing in 1998. There were HTML and CSS specifications and drafts of recommendations that were managed by the W3C, but they had spotty and uneven browser support which made them little more than words on a page. At the time, web designers stood at the precipice of what would soon be known as the Browser Wars, where Netscape and Microsoft raced to implement exclusive features and add-ons in an escalating fight for market share. Rather than stick to any official specification, these browsers forced designers to support either Netscape Navigator or Internet Explorer. And designers were definitely not happy about it.

Supporting both browsers and their competing feature implementations was possible, but it was also difficult and unreliable, like building a house on sand. To help each other along, many developers began joining mailing lists to swap tips and hacks for dealing with sites that needed to look good no matter where it was rendered.

From these mailing lists, a group began to form around an entirely new idea. The problem, this new group realized, wasn’t with the code, but with the browsers that refused to adhere to the codified, open specifications passed down by the W3C. Browsers touted new presentational HTML elements like the <blink> tag, but they were proprietary and provided no layout options. What the web needed was browsers that could follow the standards of the web.

The group decided they needed to step up and push browsers in the right direction. They called themselves the Web Standards Project. And, since the process would require a bit of a sting, they went by WaSP for short.

Launching the Web Standards Project

In August of 1998, WaSP announced their mission to the public on a brand new website: to "support these core standards and encourage browser makers to do the same, thereby ensuring simple, affordable access to Web technologies for all." Within a few hours, 450 people joined WaSP. In a few months, that number would jump to thousands.

WaSP took what was basically a two-pronged approach. The first was in public, tapping into the groundswell of developer support they had gathered to lobby for better standards support in browsers. Using grassroots tactics and targeted outreach, WaSP would often send its members on "missions" such as sending emails to browsers explaining in great detail their troubles working with a lack of consistent web standards support.

They also published scathing reports that put browsers on blast, highlighting all the ways that Netscape or Internet Explorer failed to add necessary support, even go so far to encourage users to use alternative browsers. It was these reports where the project truly lived up to its acronym. One needs to look no further then a quote from WaSP’s savage takedown of Internet Explorer as an example of its ability to sting:

Quit before the job's done, and the flamethrower's the only answer. Because that's our job. We speak for thousands of Web developers, and through them, millions of Web users.

The second prong of WaSP's approach included privately reaching out to passionate developers on browser teams. The problem, for big companies like Netscape and Microsoft, wasn’t that engineers were against web standards. Quite the contrary, actually. Many browser engineers believed deeply in WaSP’s mission but were resisted by perceived business interests and red-tape bureaucracy time and time again. As a result, WaSP would often work with browser developers to find the best path forward and advocate on their behalf to the higher-ups when necessary.

Holding it All Together

To help WaSP navigate its way through its missions, reports, and outreach, a Steering Committee was formed. This committee helped set the project's goals and reached out to the community to gather support. They were the heralds of a better day soon to come, and more than a few influential members would pass through their ranks before the project was over, including: Rachel Cox, Tim Bray, Steve Champeon, Glenn Davis, Glenda Sims, Todd Fahrner, Molly Holzschalg and Aaron Gustafson, among many, many others.

At the top of it all was a project lead who set the tone for the group and gave developers a unified voice. The position was initially held by George Olsen, one of the founders of the project, but was soon picked up by another founding member: Jeffrey Zeldman.

A network of loosely connected satellite groups orbiting around the Steering Committee helped developers and browsers alike understand the importance of web standards. There was, for instance, an Accessibility group that bridged the W3C with browser makers to ensure the web was open and accessible to everyone. Then there was the CSS Samurai, who published reports about CSS support (or, more commonly, lack thereof) in different browsers. They were the ones that devised the Box Acid test and offered guidance to browsers as they worked to expand CSS support. Todd Fahrner, who helped save CSS with doctype switching, counted himself among the CSS Samurai.

Making an Impact

WaSP was huge and growing all the time. Its members were passionate and, little by little, clusters of the community came together to enact change. And that is exactly what happened.

The changes felt kind of small at first but soon they bordered on massive. When Netscape was kicking around the idea of a new rendering engine named Gecko that would include much better standards support across the board, their initial timeline would have taken months to release. But the WaSP swarmed, emailing and reaching out to Netscape to put pressure on them to release Gecko sooner. It worked and, by the next release, Gecko (and better web standards) shipped.

Tantek Çelik was another member of WaSP. The community inspired him to take a stand on web standards at his day job as lead developer of Internet Explorer for Mac. It was through the encouragement and support of WaSP that he and his team released version 5 with full CSS Level 1 support.

Internet Explorer 5 for Mac was released with full CSS Level 1 support

In August of 2001, after years of public reports and private outreach and developer advocacy, the WaSP sting provoked seismic change in Internet Explorer as version 6 released with CSS Level 1 support and the latest HTML features. The upgrades were due in no small part to the work at the Web Standards Project and their work with dedicated members of the browser team. It appeared that standards were beginning to actually win out. The WaSP’s mission may have even been over.

But instead of calling it quits, they shifted tactics a bit.

Teaching Standards to a New Generation

In the early 2000’s, WaSP would radically change its approach to education and developer outreach.

They started with the launch of the Browser Upgrade Campaign which educated users who were coming online for the very first time and knew absolutely nothing about web standards and modern browsers. Site owners were encouraged to add some JavaScript and a banner to their sites to target these users. As a result, those surfing to a site on older versions of standards-compliant browsers, like Firefox or Opera, were greeted by a banner simply directing them to upgrade. Users visiting the site on a really old browser, like pre-IE5 or Netscape 5, would redirect visitors to an entirely new page explaining why upgrading to a modern browser with standards support was in their best interest.

A page from the Browser Upgrade Campaign

WaSP was going to bring the web up to speed, even if they had to do it one person at a time. Perhaps no one articulated this sentiment better than Molly Holzschalg when she wrote "Raise Your Standards" in February 2002. In the article, she broke down what web standards are and what they meant for developers and designers. She celebrated the work that had been done by browsers and the community working to make web standards a thing in the first place.

But, she argued, the web was far from done. It was now time for developers to step up to the plate and assume the responsibility for standards themselves by coding it into all of their sites. She wrote:

The Consortium is fraught with its own internal issues, and its actions—while almost always in the best interests of professional Web authors—are occasionally politicized.

Therefore, as Web authors, we're personally responsible for making implementation decisions within the framework of a site's markup needs. It's our job to administer recommendations to the best of our abilities.

This, however, would not be easy. It would once again require the combined efforts of WaSP members to pull together and teach the web a new way to code. Some began publishing tutorials to their personal blogs or on A List Apart. Others created a standards-based online curriculum for web developers who were new to the field. A few members even formed brand-new task forces to work with popular software tools, like Adobe Dreamweaver, and ensure that standards were supported there as well.

The redesigns of ESPN and Wired, which stood as a testament and example for standards-based designs for years to come, were undertaken in part because members of those teams were inspired by the work that WaSP was doing. They would not have been able to take those crucial first steps if not for the examples and tutorials made freely available to them by gracious WaSP members.

That is why web standards is basically second nature to many web developers today. It’s also why we have such a free spirit of creative exchange in our industry. It all started when WaSP decided to share the correct way of doing things right out in the open.

Looking Past Web Standards

It was this openness that carried WaSP into the late 2010’s. When Holzschlag took over as lead, she advocated for transparency and collaboration between browser makers and the web community. The WaSP, Holzschlag realized, was no longer necessary and could be done from within. For example, she made inroads at Microsoft to help make web standards a top priority on their browser team.

With each subsequent release, browsers began to catch up to the latest standards from the W3C. Browsers like Opera and Firefox actually competed on supporting the latest standards. Google Chrome used web standards as a selling point when it was initially released around the same time. The decade-and-a-half of work by WaSP was paying off. Browser makers were listening to the W3C and the web community, even going so far as to experiment with new standards before they were officially published for recommendation.

In 2013, WaSP posted its farewell announcement and closed up shop for good. It was a difficult decision for those who had fought long and hard for a better, more accessible and more open web, but it was necessary. There are still a number of battlegrounds for the open web but, thanks to the efforts of WaSP, the one for web standards has been won.

Enjoy learning about web history? Jay Hoffmann has a weekly newsletter called The History of the Web you can sign up for here.

A Short History of WaSP and Why Web Standards Matter is a post from CSS-Tricks

Syndicate content
©2003 - Present Akamai Design & Development.