Front End Web Development

CSS and Network Performance

Css Tricks - Tue, 11/13/2018 - 12:47pm

JavaScript and images tend to get the bulk of the blame for slow websites, but Harry explains very clearly why CSS is equally to blame and harder to deal with:

  1. A browser can’t render a page until it has built the Render Tree;
  2. the Render Tree is the combined result of the DOM and the CSSOM;
  3. the DOM is HTML plus any blocking JavaScript that needs to act upon it;
  4. the CSSOM is all CSS rules applied against the DOM;
  5. it’s easy to make JavaScript non-blocking with async and defer
    attributes;
  6. making CSS asynchronous is much more difficult;
  7. so a good rule of thumb to remember is that your page will only render as quickly as your slowest stylesheet.

There are lots of options to do better with this, including some interesting things that HTTP/2 unlocks.

Check out Šime Vidas's takeaways as well. It's all fascinating, but the progressive rendering stuff is particularly cool. I suspect many CSS-in-JS libraries could/should help with doing things this way.

Direct Link to ArticlePermalink

The post CSS and Network Performance appeared first on CSS-Tricks.

The “C” in CSS: The Cascade

Css Tricks - Tue, 11/13/2018 - 5:01am

Following up from Geoff’s intro article on The Second "S" in CSS, let’s now move the spotlight to the "C" in CSS — what we call the Cascade. It’s where things start to get messy, and even confusing at times.

Have you ever written a CSS property and the value doesn’t seem to work? Maybe you had to turn to using !important to get it going. Or perhaps you resorted to writing the CSS inline on the element in the HTML file.

<div style="background:orange; height:100px; width:100px;"> Ack, inline! </div>

Speaking of inline styles, have you wondered why SVG editors use them instead of a separate CSS file? That seems kinda weird, right?

<svg id="icon-logo-star" viewBox="0 0 362.62 388.52" width="100%" height="100%"> <style> .logo { fill: #ff9800; } </style> <title>CSS Tricks Logo</title> <path class="logo" d="M156.58 239l-88.3 64.75c-10.59 7.06-18.84 11.77-29.43 11.77-21.19 0-38.85-18.84-38.85-40 0-17.69 14.13-30.64 27.08-36.52l103.6-44.74-103.6-45.92C13 142.46 0 129.51 0 111.85 0 90.66 18.84 73 40 73c10.6 0 17.66 3.53 28.25 11.77l88.3 64.75-11.74-104.78C141.28 20 157.76 0 181.31 0s40 18.84 36.5 43.56L206 149.52l88.3-64.75C304.93 76.53 313.17 73 323.77 73a39.2 39.2 0 0 1 38.85 38.85c0 18.84-12.95 30.61-27.08 36.5l-103.61 45.91L335.54 239c14.13 5.88 27.08 18.83 27.08 37.67 0 21.19-18.84 38.85-40 38.85-9.42 0-17.66-4.71-28.26-11.77L206 239l11.77 104.78c3.53 24.72-12.95 44.74-36.5 44.74s-40-18.84-36.5-43.56z"></path> </svg>

Well, the cascade has a lot to do with this. Read on to find out how styling methods affect what's being applied to your elements and how to use the cascade to your advantage because, believe me, it’s a wonderful thing when you get the hang of it.

TL;DR: Jump right to the CSS order diagram for a visual of how everything works.

The cascade cares about how and where styles are written

There are a myriad of ways you can apply CSS rules to an element. Below is an example of how stroke: red; can be applied to the same element. The examples are ordered in ascending priority, where the highest priority is at the bottom:

<!-- Inheritance --> <g style="stroke: red"> <rect x="1" y="1" width="10" height="10" /> <!-- inherits stroke: red --> </g> <!-- Inline attributes --> <rect x="1" y="1" width="10" height="10" stroke="red" /> <!-- External style sheet --> <link rel="stylesheet" href="/path/to/stylesheet.css"> <!-- Embedded styles --> <style> rect { stroke: red; } </style> <!-- Different specificity or selectors --> rect { stroke: red; } .myClass { stroke: red; } #myID { stroke: red; } <!-- Inline style --> <g style="stroke: red"></g> <!-- Important keyword --> <g style="stroke: red !important"></g>

Inheritance? Embedded? External? Inline? Specificity? Important? Yeah, lots of terms being thrown around. Let’s break those down a bit because each one determines what the browser ends up using when a web page loads.

Elements can inherit styles from other elements

Both HTML and SVG elements can inherit CSS rules that are applied to other elements. We call this a parent-child relationship, where the element the CSS is applied to is the parent and the element contained inside the parent is the child.

<div class="parent"> <div class="child">I'm the child because the parent is wrapped around me.</div> </div>

If we set the text color of the parent and do not declare a text color on the child, then the child will look up to the parent to know what color its text should be. We call that inheritance and it’s a prime example of how a style cascades down to an element it matches... or "bubbles up" the chain to the next matched style.

However, inheritance has the lowest priority among styling methods. In other words, if a child has a rule that is specific to it, then the inherited value will be ignored, even though the inherited value may have an important keyword. The following is an example:

<div class="parent" style="color: red !important;"> <div class="child">I'm the child because the parent is wrapped around me.</div> </div>

See the Pen Child ignores inline inheritance with !important by Geoff Graham (@geoffgraham) on CodePen.

SVG inline attributes

For SVG elements, we can also apply styles using inline attributes, where those have the second lowest priority in the cascade. This means the CSS rules in a stylesheet will be able to override them.

<rect x="1" y="1" width="10" height="10" stroke="red" /> rect { stroke: blue; }

See the Pen Stylesheet overrides SVG inline attributes by Geoff Graham (@geoffgraham) on CodePen.

Most SVG editors use inline attributes for portability; that is, the ability to copy some elements and paste them elsewhere without losing the attributes. Users can then use the resultant SVG and style its elements using an external stylesheet.

Stylesheets

Stylesheets are divided into two flavors: external and embedded:

<!-- External style sheet --> <link rel="stylesheet" href="/path/to/stylesheet.css"> <!-- Embedded styles --> <style> div { border: 1px solid red } </style>

Embedded styles have the same priority as external stylesheets. Therefore, if you have the same CSS rules, ordering rules applies.

See the Pen Embedded styles override stylesheet rules by Geoff Graham (@geoffgraham) on CodePen.

All stylesheets follow ordering rules, where files that are defined later, will have higher priority than those defined earlier. In this example, stylesheet-2.css will take precedence over the stylesheet-1.css file because it is defined last.

<link rel="stylesheet" href="/path/to/stylesheet-1.css"> <link rel="stylesheet" href="/path/to/stylesheet-2.css"> Specificity or selectors

How you select your elements will also determine which rules are applied, whereby tags (e.g. <p>, <div>), classes (e.g. .my-class) and IDs (e.g. #myI-id) have ascending priorities.

See the Pen Specificity by selectors by Geoff Graham (@geoffgraham) on CodePen.

In the example above, if you have a div element with both .my-class and #my-id, the border will be red because IDs have higher priority than classes and tags.

*Specificity has higher priority than ordering rules, therefore, irrespective if your rule is at the top or bottom. Specificity still has higher priority and will be applied.

Ordering

CSS rules always prioritize from left-to-right, then from top-to-bottom.

<!-- Blue will be applied because it is on the right --> <div style="border: 1px solid red; border: 1px solid blue;"></div> <style> div { border: 1px solid red; border: 1px solid blue; /* This will be applied because it is at the bottom */ } </style> Inline styles

Inline styles have the second highest priority, just below the !important keyword. This means that inline styles are only overridden by the important keyword and nothing else. Within inline styles, normal ordering rules applies, from left-to-right and top-to-bottom.

<div style="1px solid red;"></div> The important keyword

Speaking of the !important keyword, it is used to override ordering, specificity and inline rules. In other words, it wields incredible powers.

Overriding inline rules <style> div { /* This beats inline styling */ border: 1px solid orange !important; /* These do not */ height: 200px; width: 200px; } </style> <div style="border: 1px solid red; height: 100px; width: 100px;"></div>

In the example above, without the important keyword, the div would have a red border because inline styling has higher priority than embedded styles. But, with the important keyword, the div border becomes orange, because the important keyword has higher priority than inline styling.

Using !important can be super useful, but should be used with caution. Chris has some thoughts on situations where it makes sense to use it.

Overriding specificity rules

Without the important keyword, this div border will be blue, because classes have higher priority than tags in specificity.

<style> /* Classes have higher priority than tags */ .my-class { border: 1px solid blue; height: 100px; width: 100px; } div { border: 1px solid red; height: 200px; width: 200px; } </style> <div class="my-class"></div>

See the Pen Classes beat tags by Geoff Graham (@geoffgraham) on CodePen.

But! Adding the important keyword to the tag rules tells the element to ignore the cascade and take precedence over the class rules.

<style> .my-class { border: 1px solid red; } /* The important keyword overrides specificity priority */ .my-class { border: 1px solid blue !important; } </style> <div class="my-class"></div>

See the Pen !important ignores the cascade by Geoff Graham (@geoffgraham) on CodePen.

Overriding ordering rules

OK, so we’ve already talked about how the order of rules affects specificity: bottom beats top and right beats left. The surefire way to override that is to put !important into use once again.

In this example, the div will take the red border, even though the blue border is the bottom rule. You can thank !important for that handiwork.

<style> div { border: 1px solid red !important; } /* This wins, despite the ordering */ div { border: 1px solid blue; } </style> <div></div>

See the Pen Important wins over ordering by Geoff Graham (@geoffgraham) on CodePen.

Visualizing the cascade

Who knew there was so much meaning in the "C" of CSS? We covered a ton of ground here and hopefully it helps clarify the way styles are affected and applied by how we write them. The cascade is a powerful feature. There are opinions galore about how to use it properly, but you can see the various ways properties are passed and inherited by elements.

More of a visual learner? Here’s a chart that pulls it all together.

Download chart

The post The “C” in CSS: The Cascade appeared first on CSS-Tricks.

A Bunch of Options for Looping Over querySelectorAll NodeLists

Css Tricks - Mon, 11/12/2018 - 4:54am

A common need when writing vanilla JavaScript is to find a selection of elements in the DOM and loop over them. For example, finding instances of a button and attaching a click handler to them.

const buttons = document.querySelectorAll(".js-do-thing"); // There could be any number of these! // I need to loop over them and attach a click handler.

There are SO MANY ways to go about it. Let's go through them.

forEach

forEach is normally for arrays, and interestingly, what comes back from querySelectorAll is not an array but a NodeList. Fortunately, most modern browsers support using forEach on NodeLists anyway.

buttons.forEach((button) => { button.addEventListener('click', () => { console.log("forEach worked"); }); });

If you're worried that forEach might not work on your NodeList, you could spread it into an array first:

[...buttons].forEach((button) => { button.addEventListener('click', () => { console.log("spread forEach worked"); }); });

But I'm not actually sure if that helps anything since it seems a bit unlikely there are browsers that support spreads but not forEach on NodeLists. Maybe it gets weird when transpiling gets involved, though I dunno. Either way, spreading is nice in case you want to use anything else array-specific, like .map(), .filter(), or .reduce().

A slightly older method is to jack into the array's natural forEach with this little hack:

[].forEach.call(buttons, (button) => { button.addEventListener('click', () => { console.log("array forEach worked"); }); });

Todd Motto once called out this method pretty hard though, so be advised. He recommended building your own method (updated for ES6):

const forEach = (array, callback, scope) => { for (var i = 0; i < array.length; i++) { callback.call(scope, i, array[i]); } };

...which we would use like this:

forEach(buttons, (index, button) => { console.log("our own function worked"); }); for .. of

Browser support for for .. of loops looks pretty good and this seems like a super clean syntax to me:

for (const button of buttons) { button.addEventListener('click', () => { console.log("for .. of worked"); }); } Make an array right away const buttons = Array.prototype.slice.apply( document.querySelectorAll(".js-do-thing") );

Now you can use all the normal array functions.

buttons.forEach((button) => { console.log("apply worked"); }); Old for loop

If you need maximum possible browser support, there is no shame in an ancient classic for loop:

for (let i = 0; i < buttons.length; ++i) { buttons[i].addEventListener('click', () => { console.log("for loop worked"); }); } Libraries

If you're using jQuery, you don't even have to bother....

$(".buttons").on("click", () => { console.log("jQuery works"); });

If you're using a React/JSX setup, you don't need think about this kind of binding at all.

Lodash has a _.forEach as well, which presumably helps with older browsers.

_.forEach(buttons, (button, key) => { console.log("lodash worked"); }); Poll

Twitter peeps:

const els = document.querySelectorAll(".foo");

// which loop do you use? one of these? other?

— Chris Coyier (@chriscoyier) November 7, 2018

Also here's a Pen with all these options in it.

The post A Bunch of Options for Looping Over querySelectorAll NodeLists appeared first on CSS-Tricks.

Why Browsers Download Stylesheets with Non-Matching Media Queries

Css Tricks - Mon, 11/12/2018 - 4:53am

Say you have a stylesheet linked up like this:

<link href="mobile.css" rel="stylesheet" media="screen and (max-width: 600px)">

But as the page loads, you're on a desktop browser where the screen is 1753px wide. The browser should just skip loading that stylesheet entirely, right? It doesn't. Thomas Steiner explains:

it turns out that the CSS spec writers and browser implementors are actually pretty darn smart about this:

The thing is, the user could always decide to resize their window (impacting width, height, aspect ratio), to print the document, etc., and even things that at first sight seem static (like the resolution) can change when a user with a multi-screen setup moves a window from say a Retina laptop screen to a bigger desktop monitor, or the user can unplug their mouse, and so on.

What browsers do do (heh, &#x1f4a9;) is apply a Lowest download priority.

Direct Link to ArticlePermalink

The post Why Browsers Download Stylesheets with Non-Matching Media Queries appeared first on CSS-Tricks.

The ironic inaccessibility of a11y

Css Tricks - Sun, 11/11/2018 - 6:54pm

This resonated with me:

It’s ironic to me that the numeronym “a11y” lacks accessibility: it’s not immediately decipherable by humans who aren’t “in the club”; and, in some fonts, it’s visually indistinguishable from the word “ally” (with lowercase L’s), which can foil searches for clarity.

— Eric Meyer (@meyerweb) November 5, 2018

Because I bet it took me a year after seeing that acronym ("numeronym", I guess) for the first time to know that was just a stand-in for the word "accessibility". I'm only now just understanding that "i18n" means "Internationalization" and "l10n" means "Localization". I wonder how many conversations or articles I've missed because I just assumed the weird moniker was referring to something that had nothing to do with me. On the flip side, I wonder what good has come from having these cool words form a banner to rally under.

Lots of good conversation in that thread. I don't know enough to have an opinion about whether anyone else should or shouldn't use it, but remembering my own confusion, I think I'll avoid it around here.

The post The ironic inaccessibility of a11y appeared first on CSS-Tricks.

When’s the last time you SFTP’d (or the like) into a server and changed a file directly?

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

In the grand tradition of every single poll question I've ever posted, the poll below has a has a fundamental flaw. In this case, there is no option between "In the last month" and "Never" but, alas, the results are interesting:

When's the last time you SFTP'd (or the equiv) into a server and changed a file directly?

— Chris Coyier (@chriscoyier) October 9, 2018

What I was trying to get at with this poll is how many people do and don't do any sort of editing of production files directly and instead work locally. I don't think I need to launch a major investigation to know that it's most people and more than in the past.

Most workflows these days have us working locally and pushing new and updated files through a version control system, and even through systems beyond that, perhaps continuous integration processes, testing processes, actions, deployment — it's big world of DevOps out there! Rarely do we skip the line and dip our fingers into production servers and make live manipulations. Cowboy coding, they sometimes call it.

But just because you don't generally code that way doesn't mean you never do it, which is another flaw of this poll. I know DevOps nerds who are constantly SSH-ing into servers to manipulate configuration files. I personally still hop into Coda and will directly SFTP into servers sometimes to edit .htaccess files, which are sometimes on my production sites and dev sites and that I generally .gitignore.

Anyways, I think this is a fun thing to talk about, so feel free to have at it in the comments. I'd love to hear to what degree you cowboy code. Still do it all the time and love it? Do you do it because you haven't learned another way or that's how your workplace demands? Do you have a personal philosophy about it? Let the rodeo begin. &#x1f920;

The post When’s the last time you SFTP’d (or the like) into a server and changed a file directly? appeared first on CSS-Tricks.

Get References from HTML Built with Template Literals

Css Tricks - Thu, 11/08/2018 - 1:44pm

One thing JavaScript template literals are great at is little blocks of HTML. Like:

// Probably from some API or whatever const data = { title: "Title", content: "Content" }; const some_html = ` <div class="module"> <h2>${data.title}</h2> <p>${data.content}</p> </div> `;

But that's still just a string. It's not ready to append to the DOM just yet. And what if we need references to those elements inside somehow?

We've written about a couple of libraries that are in this vein: lit-html and hyperHTML. Those are pretty small libs, but are also sorta more about re-rendering of templates in an efficient way (like super mini React).

What if you just need the nodes? That's almost a one-liner:

const getNodes = str => { return new DOMParser().parseFromString(str, 'text/html').body.childNodes; }

Now we could drop that template literal of HTML right into the DOM:

document.body.appendChild(getNodes(some_html)[0]);

Here's that:

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

But how do we get our hands on individual bits of that HTML? We don't exactly have references to anything, even the whole chunk we put in.

I just saw this little lib called Facon that looks to do just this. It makes use of tagged template literals, which is super cool:

import f from 'facon'; const data = { title: "Title", content: "Content" }; let html = f` <div class="module"> <h2>${data.title}</h2> <p>${data.content}</p> </div> `; document.body.appendChild(html);

This skips the need for our little getNodes function, but more importantly, we can yank out those references!

let html = f` <div class="module"> <h2 ref="title">${data.title}</h2> <p ref="content">${data.content}</p> </div> `; let { title, content } = html.collect(); title.innerText = "Title Changed!";

Here's that:

See the Pen Facon Template by Chris Coyier (@chriscoyier) on CodePen.

The post Get References from HTML Built with Template Literals appeared first on CSS-Tricks.

CSS-Tricks Uses Jetpack

Css Tricks - Thu, 11/08/2018 - 1:12pm

(This is a sponsored post.)

Hey! I made a little page to explain all the ways in which this very site uses the Jetpack WordPress plugin.

Here's the gist of it:

  • Our Jetpack subscription gives us VaultPress, which backs up literally everything on this site in real time. That helps me sleep.
  • Jetpack improves our site search and allows it to be tweaked and the design customized.
  • Jetpack connects to Twitter and Facebook, so as we publish posts it can kick out tweets and updates.
  • Jetpack allows us to author content in Markdown (and you to comment in Markdown).
  • Jetpack adds social login buttons to the comment form, so you don't have to be troubled to type out your name and email.
  • We display related posts on articles, and Jetpack does a crack job of it without stressing out our server.

But Jetpack has way more features than that. That's just what we use, what you might find useful for your site could be totally different.

Direct Link to ArticlePermalink

The post CSS-Tricks Uses Jetpack appeared first on CSS-Tricks.

A Guide to Custom Elements for React Developers

Css Tricks - Thu, 11/08/2018 - 4:59am

I had to build a UI recently and (for the first time in a long while) I didn't have the option of using React.js, which is my preferred solution for UI these days. So, I looked at what the built-in browser APIs had to offer and saw that using custom elements (aka Web Components) may just be the remedy that this React developer needed.

Custom elements can offer the same general benefits of React components without being tied to a specific framework implementation. A custom element gives us a new HTML tag that we can programmatically control through a native browser API.

Let's talk about the benefits of component-based UI:

  • Encapsulation - concerns scoped to that component remain in that component's implementation
  • Reusability - when the UI is separated into more generic pieces, they're easier to break into patterns that you're more likely to repeat
  • Isolation - because components are designed to be encapsulated and with that, you get the added benefit of isolation, which allows you scope bugs and changes to a particular part of your application easier
Use cases

You might be wondering who is using custom elements in production. Notably:

  • GitHub is using custom elements for their modal dialogs, autocomplete and display time.
  • YouTube's new web app is built with Polymer and web components.
Similarities to the Component API

When trying to compare React Components versus custom elements, I found the APIs really similar:

  • They're both classes that aren't "new" and are able that extend a base class
  • They both inherit a mounting or rendering lifecycle
  • They both take static or dynamic input via props or attributes
Demo

So, let's build a tiny application that lists details about a GitHub repository.

If I were going to approach this with React, I would define a simple component like this:

<Repository name="charliewilco/obsidian" />

This component takes a single prop — the name of the repository — and we implement it like this:

class Repository extends React.Component { state = { repo: null }; async getDetails(name) { return await fetch(`https://api.github.com/repos/${name}`, { mode: 'cors' }).then(res => res.json()); } async componentDidMount() { const { name } = this.props; const repo = await this.getDetails(name); this.setState({ repo }); } render() { const { repo } = this.state; if (!repo) { return <h1>Loading</h1>; } if (repo.message) { return <div className="Card Card--error">Error: {repo.message}</div>; } return ( <div class="Card"> <aside> <img width="48" height="48" class="Avatar" src={repo.owner.avatar_url} alt="Profile picture for ${repo.owner.login}" /> </aside> <header> <h2 class="Card__title">{repo.full_name}</h2> <span class="Card__meta">{repo.description}</span> </header> </div> ); } }

See the Pen React Demo - GitHub by Charles (@charliewilco) on CodePen.

To break this down further, we have a component that has its own state, which is the repo details. Initially, we set it to be null because we don't have any of that data yet, so we'll have a loading indicator while the data is fetched.

During the React lifecycle, we'll use fetch to go get the data from GitHub, set up the card, and trigger a re-render with setState() after we get the data back. All of these different states the UI takes are represented in the render() method.

Defining / Using a Custom Element

Doing this with custom elements is a little different. Like the React component, our custom element will take a single attribute — again, the name of the repository — and manage its own state.

Our element will look like this:

<github-repo name="charliewilco/obsidian"></github-repo> <github-repo name="charliewilco/level.css"></github-repo> <github-repo name="charliewilco/react-branches"></github-repo> <github-repo name="charliewilco/react-gluejar"></github-repo> <github-repo name="charliewilco/dotfiles"></github-repo>

See the Pen Custom Elements Demo - GitHub by Charles (@charliewilco) on CodePen.

To start, all we need to do to define and register a custom element is create a class that extends the HTMLElement class and then register the name of the element with customElements.define().

class OurCustomElement extends HTMLElement {} window.customElements.define('our-element', OurCustomElement);

And we can call it:

<our-element></our-element>

This new element isn't very useful, but with custom elements, we get three methods to expand the functionality of this element. These are almost analogous to React’s lifecycle methods for their Component API. The two lifecycle-like methods most relevant to us are the disconnectedCallBack and the connectedCallback and since this is a class, it comes with a constructor.

Name Called when constructor An instance of the element is created or upgraded. Useful for initializing state, settings up event listeners, or creating Shadow DOM. See the spec for restrictions on what you can do in the constructor. connectedCallback The element is inserted into the DOM. Useful for running setup code, such as fetching resources or rendering UI. Generally, you should try to delay work until this time disconnectedCallback When the element is removed from the DOM. Useful for running clean-up code.

To implement our custom element, we'll create the class and set up some attributes related to that UI:

class Repository extends HTMLElement { constructor() { super(); this.repoDetails = null; this.name = this.getAttribute("name"); this.endpoint = `https://api.github.com/repos/${this.name}` this.innerHTML = `<h1>Loading</h1>` } }

By calling super() in our constructor, the context of this is the element itself and all the DOM manipulation APIs can be used. So far, we've set the default repository details to null, gotten the repo name from element's attribute, created an endpoint to call so we don't have to define it later and, most importantly, set the initial HTML to be a loading indicator.

In order to get the details about that element’s repository, we’re going to need to make a request to GitHub’s API. We’ll use fetch and, since that's Promise-based, we'll use async and await to make our code more readable. You can learn more about the async/await keywords here and more about the browser's fetch API here. You can also tweet at me to find out whether I prefer it to the Axios library. (Hint, it depends if I had tea or coffee with my breakfast.)

Now, let's add a method to this class to ask GitHub for details about the repository.

class Repository extends HTMLElement { constructor() { // ... } async getDetails() { return await fetch(this.endpoint, { mode: "cors" }).then(res => res.json()); } }

Next, let's use the connectedCallback method and the Shadow DOM to use the return value from this method. Using this method will do something similar as when we called Repository.componentDidMount() in the React example. Instead, we'll override the null value we initially gave this.repoDetails — we'll use this later when we start to call the template to create the HTML.

class Repository extends HTMLElement { constructor() { // ... } async getDetails() { // ... } async connectedCallback() { let repo = await this.getDetails(); this.repoDetails = repo; this.initShadowDOM(); } initShadowDOM() { let shadowRoot = this.attachShadow({ mode: "open" }); shadowRoot.innerHTML = this.template; } }

You'll notice that we're calling methods related to the Shadow DOM. Besides being a rejected title for a Marvel movie, the Shadow DOM has its own rich API worth looking into. For our purposes, though, it's going to abstract the implementation of adding innerHTML to the element.

Now we're assigning the innerHTML to be equal to the value of this.template. Let's define that now:

class Repository extends HTMLElement { get template() { const repo = this.repoDetails; // if we get an error message let's show that back to the user if (repo.message) { return `<div class="Card Card--error">Error: ${repo.message}</div>` } else { return ` <div class="Card"> <aside> <img width="48" height="48" class="Avatar" src="${repo.owner.avatar_url}" alt="Profile picture for ${repo.owner.login}" /> </aside> <header> <h2 class="Card__title">${repo.full_name}</h2> <span class="Card__meta">${repo.description}</span> </header> </div> ` } } }

That's pretty much it. We've defined a custom element that manages its own state, fetches its own data, and reflects that state back to the user while giving us an HTML element to use in our application.

After going through this exercise, I found that the only required dependency for custom elements is the browser's native APIs rather than a framework to additionally parse and execute. This makes for a more portable and reusable solution with similar APIs to the frameworks you already love and use to make your living.

There are drawbacks of using this approach, of course. We're talking about various browser support issues and some lack of consistency. Plus, working with DOM manipulation APIs can be very confusing. Sometimes they are assignments. Sometimes they are functions. Sometimes those functions take a callback and sometimes they don't. If you don't believe me, take a look at adding a class to an HTML element created via document.createElement(), which is one of the top five reasons to use React. The basic implementation isn’t that complicated but it is inconsistent with other similar document methods.

The real question is: does it even out in the wash? Maybe. React is still pretty good at the things it's designed to be very very good at: the virtual DOM, managing application state, encapsulation, and passing data down the tree. There's next to no incentive to use custom elements inside that framework. Custom elements, on the other hand, are simply available by virtue of building an application for the browser.

Learn more

The post A Guide to Custom Elements for React Developers appeared first on CSS-Tricks.

Simplify Styling with Functional CSS

Css Tricks - Wed, 11/07/2018 - 8:35am

There is no doubt that "functional CSS" resonates strongly with some people. If that term is new to you, I belive it's come to mean the same thing as "Atomic CSS" as defined by John Polacek here. Harry Nicholls likens it to a function that can only produce one result (although I'd call that a pure function or pure component), but instead of a return value being entirely predictable based on inputs, it is an application of style that only does one thing.

I'm of two minds here. People say how fast they can work this way. Great! They like how predictable the applied styles are. Great! I can understand how a tiny stylesheet that doesn't grow over time is appealing as well.

At the same time, I haven't seen writing about other styling concerns. What happens with big redesigns? Is it about the same, time- and difficulty-wise, or do you spend more time tearing down all those classes? What happens when you need a style that isn't available? Write your own? Or does that ruin the spirit of all this and put you in dangerous territory? How intense can all the class names get? I can think of areas I've styled that have three or more media queries that dramatically re-style an element. Putting all that information in HTML seems like it could get awfully messy. Is consistency harder or easier? I get that "p5" might be a useful way to apply an abstract amount of padding, but you still need to sprinkle it all over your codebase and know when to use it, right?

The closest I've been to being convinced about it was hearing from Adam just how configurable Tailwind is. In any case, I find this all endless fascinating and, if you love it, more power to ya.

Direct Link to ArticlePermalink

The post Simplify Styling with Functional CSS appeared first on CSS-Tricks.

Building a Donut Chart with Vue and SVG

Css Tricks - Wed, 11/07/2018 - 4:49am

Mmm... forbidden donut."

- Homer Simpson

I recently needed to make a donut chart for a reporting dashboard at work. The mock-up that I got looked something like this:

My chart had a few basic requirements. It needed to:

  • Dynamically calculate its segments based on an arbitrary set of values
  • Have labels
  • Scale well across all screen sizes and devices
  • Be cross-browser compatible back to Internet Explorer 11
  • Be accessible
  • Be reusable across my work’s Vue.js front end

I also wanted something that I could animate later if I needed to. All of this sounded like a job for SVG.

SVGs are accessible out-of-the-box (the W3C has a whole section on this) and can be made more accessible through additional input. And, because they’re powered by data, they’re a perfect candidate for dynamic visualization.

There are plenty of articles on the topic, including two by Chris (here and here) and a super recent one by Burke Holland. I didn’t use D3 for this project because the application didn’t need the overhead of that library.

I created the chart as a Vue component for my project, but you could just as easily do this with vanilla JavaScript, HTML, and CSS.

Here’s the finished product:

See the Pen Vue Donut Chart - Final Version by Salomone Baquis (@soluhmin) on CodePen.

Reinventing the wheel circle

Like any self-respecting developer, the first thing I did was Google to see if someone else had already made this. Then, like same said developer, I scrapped the pre-built solution in favor of my own.

The top hit for "SVG donut chart" is this article, which describes how to use stroke-dasharray and stroke-dashoffset to draw multiple overlaid circles and create the illusion of a single segmented circle (more on this shortly).

I really like the overlay concept, but found recalculating both stroke-dasharray and stroke-dashoffset values confusing. Why not set one fixed stroke-dasharrary value and then rotate each circle with a transform? I also needed to add labels to each segment, which wasn’t covered in the tutorial.

Drawing a line

Before we can create a dynamic donut chart, we first need to understand how SVG line drawing works. If you haven’t read Jake Archibald’s excellent Animated Line Drawing in SVG. Chris also has a good overview.

Those articles provide most of the context you’ll need, but briefly, SVG has two presentation attributes: stroke-dasharray and stroke-dashoffset.

stroke-dasharray defines an array of dashes and gaps used to paint the outline of a shape. It can take zero, one, or two values. The first value defines the dash length; the second defines the gap length.

stroke-dashoffset, on the other hand, defines where the set of dashes and gaps begins. If the stroke-dasharray and the stroke-dashoffset values are the length of the line and equal, the entire line is visible because we’re telling the offset (where the dash-array starts) to begin at the end of the line. If the stroke-dasharray is the length of the line, but the stroke-dashoffset is 0, then the line is invisible because we’re offsetting the rendered part of the dash by its entire length.

Chris’ example demonstrates this nicely:

See the Pen Basic Example of SVG Line Drawing, Backward and Forward by Chris Coyier (@chriscoyier) on CodePen.

How we’ll build the chart

To create the donut chart’s segments, we’ll make a separate circle for each one, overlay the circles on top of one another, then use stroke, stroke-dasharray, and stroke-dashoffset to show only part of the stroke of each circle. We’ll then rotate each visible part into the correct position, creating the illusion of a single shape. As we do this, we’ll also calculate the coordinates for the text labels.

Here’s an example demonstrating these rotations and overlays:

See the Pen Circle Overlays by Salomone Baquis (@soluhmin) on CodePen.

Basic setup

Let’s start by setting up our structure. I’m using x-template for demo purposes, but I’d recommend creating a single file component for production.

<div id="app"> <donut-chart></donut-chart> </div> <script type="text/x-template" id="donutTemplate"> <svg height="160" width="160" viewBox="0 0 160 160"> <g v-for="(value, index) in initialValues"> <circle :cx="cx" :cy="cy" :r="radius" fill="transparent" :stroke="colors[index]" :stroke-width="strokeWidth" ></circle> <text></text> </g> </svg> </script> Vue.component('donutChart', { template: '#donutTemplate', props: ["initialValues"], data() { return { chartData: [], colors: ["#6495ED", "goldenrod", "#cd5c5c", "thistle", "lightgray"], cx: 80, cy: 80, radius: 60, sortedValues: [], strokeWidth: 30, } } }) new Vue({ el: "#app", data() { return { values: [230, 308, 520, 130, 200] } }, });

With this, we:

  • Create our Vue instance and our donut chart component, then tell our donut component to expect some values (our dataset) as props
  • Establish our basic SVG shapes: <circle> for the segments and <text> for the labels, with the basic dimensions, stroke width, and colors defined
  • Wrap these shapes in a <g> element, which groups them together
  • Add a v-for loop to the g> element, which we’ll use to iterate through each value that the component receives
  • Create an empty sortedValues array, which we’ll use to hold a sorted version of our data
  • Create an empty chartData array, which will contain our main positioning data
Circle length

Our stroke-dasharray should be the length of the entire circle, giving us an easy baseline number which we can use to calculate each stroke-dashoffset value. Recall that the length of a circle is its circumference and the formula for circumference is 2?r (you remember this, right?).

We can make this a computed property in our component.

computed: { circumference() { return 2 * Math.PI * this.radius } }

...and bind the value to our template markup.

<svg height="160" width="160" viewBox="0 0 160 160"> <g v-for="(value, index) in initialValues"> <circle :cx="cx" :cy="cy" :r="radius" fill="transparent" :stroke="colors[index]" :stroke-width="strokeWidth" :stroke-dasharray="circumference" ></circle> <text></text> </g> </svg>

In the initial mockup, we saw that the segments went from largest to smallest. We can make another computed property to sort these. We’ll store the sorted version inside the sortedValues array.

sortInitialValues() { return this.sortedValues = this.initialValues.sort((a,b) => b-a) }

Finally, in order for these sorted values to be available to Vue before the chart gets rendered, we’ll want to reference this computed property from the mounted() lifecycle hook.

mounted() { this.sortInitialValues }

Right now, our chart look like this:

See the Pen Donut Chart - No Segments by Salomone Baquis (@soluhmin) on CodePen.

No segments. Just a solid-colored donut. Like HTML, SVG elements are rendered in the order that they appear in the markup. The color that appears is the stroke color of the last circle in the SVG. Because we haven’t added any stroke-dashoffset values yet, each circle’s stroke goes all the way around. Let’s fix this by creating segments.

Creating segments

To get each of the circle segments, we’ll need to:

  1. Calculate the percentage of each data value from the total data values that we pass in
  2. Multiply this percentage by the circumference to get the length of the visible stroke
  3. Subtract this length from the circumference to get the stroke-offset

It sounds more complicated than it is. Let’s start with some helper functions. We first need to total up our data values. We can use a computed property to do this.

dataTotal() { return this.sortedValues.reduce((acc, val) => acc + val) },

To calculate the percentage of each data value, we’ll need to pass in values from the v-for loop that we created earlier, which means that we’ll need to add a method.

methods: { dataPercentage(dataVal) { return dataVal / this.dataTotal } },

We now have enough information to calculate our stroke-offset values, which will establish our circle segments.

Again, we want to: (a) multiply our data percentage by the circle circumference to get the length of the visible stroke, and (b) subtract this length from the circumference to get the stroke-offset.

Here’s the method to get our stroke-offsets:

calculateStrokeDashOffset(dataVal, circumference) { const strokeDiff = this.dataPercentage(dataVal) * circumference return circumference - strokeDiff },

...which we bind to our circle in the HTML with:

:stroke-dashoffset="calculateStrokeDashOffset(value, circumference)"

And voilà! We should have something like this:

See the Pen Donut Chart - No Rotations by Salomone Baquis (@soluhmin) on CodePen.

Rotating segments

Now the fun part. All of segments begin at 3 o’clock, which is the default starting point for SVG circles. To get them in the right place, we need to rotate each segment to its correct position.

We can do this by finding each segment’s ratio out of 360 degrees and then offset that amount by the total degrees that came before it.

First, let’s add a data property to keep track of the offset:

angleOffset: -90,

Then our calculation (this is a computed property):

calculateChartData() { this.sortedValues.forEach((dataVal, index) => { const data = { degrees: this.angleOffset, } this.chartData.push(data) this.angleOffset = this.dataPercentage(dataVal) * 360 + this.angleOffset }) },

Each loop creates a new object with a "degrees" property, pushes that into our chartValues array that we created earlier, and then updates the angleOffset for the next loop.

But wait, what’s up with the -90 value?

Well, looking back at our original mockup, the first segment is shown at the 12 o’clock position, or -90 degrees from the starting point. By setting our angleOffset at -90, we ensure that our largest donut segment starts from the top.

To rotate these segments in the HTML, we’ll use the transform presentation attribute with the rotate function. Let’s create another computed property so that we can return a nice, formatted string.

returnCircleTransformValue(index) { return rotate(${this.chartData[index].degrees}, ${this.cx}, ${this.cy})` },

The rotate function takes three arguments: an angle of rotation and x and y coordinates around which the angle rotates. If we don’t supply cx and cy coordinates, then our segments will rotate around the entire SVG coordinate system.

Next, we bind this to our circle markup.

:transform="returnCircleTransformValue(index)"

And, since we need to do all of these calculations before the chart is rendered, we’ll add our calculateChartData computed property in the mounted hook:

mounted() { this.sortInitialValues this.calculateChartData }

Finally, if we want that sweet, sweet gap between each segment, we can subtract two from the circumference and use this as our new stroke-dasharray.

adjustedCircumference() { return this.circumference - 2 }, :stroke-dasharray="adjustedCircumference"

Segments, baby!

See the Pen Donut Chart - Segments Only by Salomone Baquis (@soluhmin) on CodePen.

Labels

We have our segments, but now we need to create labels. This means that we need to place our <text> elements with x and y coordinates at different points along the circle. You might suspect that this requires math. Sadly, you are correct.

Fortunately, this isn’t the kind of math where we need to apply Real Concepts; this is more the kind where we Google formulas and don’t ask too many questions.

According to the Internet, the formulas to calculate x and y points along a circle are:

x = r cos(t) + a y = r sin(t) + b

...where r is the radius, t is the angle, and a and b are the x and y center point offsets.

We already have most of this: we know our radius, we know how to calculate our segment angles, and we know our center offset values (cx and cy).

There’s one catch, though: in those formulas, t is in *radians*. We’re working in degrees, which means that we need to do some conversions. Again, a quick search turns up a formula:

radians = degrees * (? / 180)

...which we can represent in a method:

degreesToRadians(angle) { return angle * (Math.PI / 180) },

We now have enough information to calculate our x and y text coordinates:

calculateTextCoords(dataVal, angleOffset) { const angle = (this.dataPercentage(dataVal) * 360) / 2 + angleOffset const radians = this.degreesToRadians(angle) const textCoords = { x: (this.radius * Math.cos(radians) + this.cx), y: (this.radius * Math.sin(radians) + this.cy) } return textCoords },

First, we calculate the angle of our segment by multiplying the ratio of our data value by 360; however, we actually want half of this because our text labels are in the middle of the segment rather than the end. We need to add the angle offset like we did when we created the segments.

Our calculateTextCoords method can now be used in the calculateChartData computed property:

calculateChartData() { this.sortedValues.forEach((dataVal, index) => { const { x, y } = this.calculateTextCoords(dataVal, this.angleOffset) const data = { degrees: this.angleOffset, textX: x, textY: y } this.chartData.push(data) this.angleOffset = this.dataPercentage(dataVal) * 360 + this.angleOffset }) },

Let’s also add a method to return the label string:

percentageLabel(dataVal) { return `${Math.round(this.dataPercentage(dataVal) * 100)}%` },

And, in the markup:

<text :x="chartData[index].textX" :y="chartData[index].textY">{{ percentageLabel(value) }}</text>

Now we’ve got labels:

See the Pen Donut Chart - Unformatted Labels by Salomone Baquis (@soluhmin) on CodePen.

Blech, so off-center. We can fix this with the text-anchor presentation attribute. Depending on your font and font-size, you may want to adjust the positioning as well. Check out dx and dy for this.

Revamped text element:

<text text-anchor="middle" dy="3px" :x="chartData[index].textX" :y="chartData[index].textY">{{ percentageLabel(value) }}</text>

Hmm, it seems that if we have small percentages, the labels go outside of the segments. Let’s add a method to check for this.

segmentBigEnough(dataVal) { return Math.round(this.dataPercentage(dataVal) * 100) > 5 } <text v-if="segmentBigEnough(value)" text-anchor="middle" dy="3px" :x="chartData[index].textX" :y="chartData[index].textY">{{ percentageLabel(value) }}</text>

Now, we’ll only add labels to segments larger than 5%.

And we’re done! We now have a reusable donut chart component that can accept any set of values and create segments. Super cool!

The finished product:

See the Pen Vue Donut Chart - Final Version by Salomone Baquis (@soluhmin) on CodePen.

Next steps

There are lots of ways that we can modify or improve this now that it’s built. For example:

  • Adding elements to enhance accessibility, such as <title> and <desc> tags, aria-labels, and aria role attributes.
  • Creating animations with CSS or libraries like Greensock to create eye-catching effects when the chart comes into view.
  • Playing with color schemes.

I’d love to hear what you think about this implementation and other experiences you’ve had with SVG charts. Share in the comments!

The post Building a Donut Chart with Vue and SVG appeared first on CSS-Tricks.

Fun Tip: Use calc() to Change the Height of a Hero Component

Css Tricks - Tue, 11/06/2018 - 4:51am

The concept of Fluid Typography was tossed around a couple of years ago. The main idea is that if you know what size your font is at two different viewport sizes, then you can have the font scaling smoothly between the two sizes. We had a jQuery solution for this in FitText (meant of headings, of course) until the calc() function was shipped giving us a pure CSS solution.

p { font-size: calc(16px + (24 - 16)*(100vw - 400px)/(800 - 400)); }

See the Pen Fluid Typography by Martino Stenta (@martinostenta) on CodePen.

The important numbers here are 24px (the larger font up to 800px viewports) and 16px (the smaller font size down to 400px viewports). I wouldn’t use the terms "minimum" or "maximum" to describe font sizes and viewports in this context because it is a little misleading. In fact, you still need to provide a default font size for viewports smaller than 400px and bigger than 800px — otherwise, the font will keep getting smaller (or bigger) with the same scale of the equation. Or, if you are fancy, you could define another scale for bigger screen sizes.

See the Pen Fluid Typography with reset size by Martino Stenta (@martinostenta) on CodePen.

It works really well and you should definitely check the math behind this.

Padding and line height?

I liked the concept of Fluid Typography so much that I asked myself if it could work with other properties. And it does! You can’t use a percentage, but as long as you stick with px, em or rem units, then it’s OK. I’m a pixel guy, so all my experiments have used those, but there is this neat generatorthat helps you with conversions if you need it.

So, back to padding and line-height. Using the same calc() logic, we can achieve a fully fluid *layout* with fixed values for defined screen sizes.

See the Pen Pure CSS Variable Padding, Font Size and Line Height by Martino Stenta (@martinostenta) on CodePen.

I implemented this idea on this website, but kept it to font-size and line-height. And, yes, it gets easier to look past all that math and put to use the more you work with it.

See the Pen Working Example of calc() on font-size and line-hieght by Martino Stenta (@martinostenta) on CodePen.

A digression about "Hero" components

If you’re like me, then you might take issue with what we all have come to know as the hero component. It’s ubiquitous to the extent that it’s become a staple in design systems (like Bootstrap) and you may have even seen it satirized on sites like this.

My main gripe concerns the best way to make them responsive. If it’s not a *full screen* hero (i.e. takes over the entire viewport at any size), then I usually ask the designer how the page should behave. There’s often a proportion of the hero page that works fine, so that allows me to use padding-bottom in % with absolute positioning of the inner content. That tactic works most of the time,

This is fun and it works fine especially on the desktop version of a website. You end up with a neat hero section, the proportion is good and the content is centered.

See the Pen Standard hero section with 'padding-bottom' by Martino Stenta (@martinostenta) on CodePen.

But what happens when you start shrinking the viewport? The hero remains readable up to a point, you really need to change the proportion.

Assuming we are working with a desktop-first responsive approach, we could start with a horizontal rectangle that scales down to the point where we’re left with a vertical rectangle on small screens.

Hero component with different proportions based on device

This is a PITA because you could end up with many lines of CSS to have a nice and readable hero section at various breakpoints.

There has to be a better way, right? What if the hero could increase its height while the page width gets narrower?

Back to fluidity!

So, I turned back to the calc() function that worked in those other situations, like making the browser handle the math and scale things accordingly as the viewport changes.

Here’s the CSS from the Fluid Typography example we started with:

p { width: 100%; max-width: 1200px; margin: 0 auto; font-family: 'Open Sans', sans-serif; font-size: calc(24px + (18 - 24)*(100vw - 400px)/(1200 - 400)); line-height: 1.5; padding: 10px; }

Here’s what we want: a hero component that gets bigger while you shrink the page. I used pixel units for the fluid part and percentages everywhere else.

Here’s a screencast of how the solution I landed on:

Live Demo

This is pretty useful when you want to give more vertical space to the text. Shrinking the viewport width from large to small will end up having more lines for the same text, since the font size can’t be too small.

See the Pen Hero section with calc() by Martino Stenta (@martinostenta) on CodePen.

Pretty nice, right? Yet another way calc() proved it could solve a scenario for me.

Yes, there are some caveats

Browser support is very good, tallying almost 93% of the users (at the time of writing), with the main exception being Opera mini.

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

DesktopChromeOperaFirefoxIEEdgeSafari19*154*10126*Mobile / TabletiOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox6.0-6.1*46No676962

Also, remember that this calc() technique supports only px, em, and rem units. But the examples we covered here are pretty easy to convert units for things like padding-bottom percentages to pixels since the hero is typically 100% in width.

Oh! And remember to reset your values before and after the breakpoints in the calc() function. Otherwise you’ll end up with either very big or very small values for the target properties.

What say you?

This is probably just one way we can handle the situation and it was primarily driven by my interest in the calc() function. So, that begs the question: how have you handled scaling hero component height? Have you put calc() to use for it? Do you prefer wrangling breakpoints at various widths? Is there something else you use? Light up the comments!

The post Fun Tip: Use calc() to Change the Height of a Hero Component appeared first on CSS-Tricks.

How we made Carousell’s mobile web experience 3x faster

Css Tricks - Tue, 11/06/2018 - 4:50am

Both a sobering and interesting read from Stacey Tay on how the team at Carousell gathered the metrics to define a performance budget and, in turn, developed a better experience for their customers:

Our new PWA listing page loads 3x faster than our old listing page. After releasing this new page, we’ve had a 63% increase in organic traffic from Indonesia, compared to our our all time-high week. Over a 3 week period, we also saw a 3x increase in ads click-through-rates and a 46% increase in anonymous users who initiated a chat on the listing page.

The team inlined critical CSS, reduced the number of resources the app was loading, and implemented a lazy loading strategy, among many other things. I think it’s interesting to note that they also changed the design of the app in certain ways to make things more performant, too. I reckon it’s easy to fall into the trap of thinking that performance is solely a task for developers and posts like this prove that it's more collaborative than that.

Direct Link to ArticlePermalink

The post How we made Carousell’s mobile web experience 3x faster appeared first on CSS-Tricks.

Rocking California’s “I Voted” Sticker in CSS for Election Day 2018

Css Tricks - Mon, 11/05/2018 - 4:54am

Oh hey, so tomorrow (tomorrow!) is Election Day here in the United States. We're not in the business of making political endorsements or anything like that at CSS-Tricks, though we do endorse that everyone exercise their right to vote.

I did exactly that two years ago and posted a CSS rendition of the "I Voted" sticker that came with my California mail-in ballot.

See the Pen I Voted Sticker by Geoff Graham (@geoffgraham) on CodePen.

Fast forward to today, and I received a new sticker in the ballot sporting a fresh design:

Credit: Los Angeles Magazine (source)

I have a little time, so I'm going to try to re-create this sticker in CSS and walk through my thought process as I do it. Feel free to follow along if you'd like!

Breaking down the elements

Anytime I'm given a design of any kind, I like to pretend that my eyes have the superpower of X-ray vision and can see through the design as if it were a skeleton. This helps me start to think through how many elements I might use in the HTML.

OK, I think I'm going to start with something like this:

<!-- Main Circle --> <div class="sticker"> <div class="sticker__top"> <!-- Will use ::before and ::after to create halves --> <h1>I Voted</h1> </div> <div class="sticker__bottom"> <!-- The list of languages --> <ul> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> </ul> </div> </div>

I'm also going to throw in some base styles on the <body> so I can jump right into the rest of the sticker.

See the Pen "I Voted" Sticker HTML by Geoff Graham (@geoffgraham) on CodePen.

OK, nothing fancy so far. Really just looks like an unordered list with a heading with some terrible contrast between the content and background.

Working on the main sticker container

I think I'll set up the container, which is the main circle. I'm going to use a fixed width and height, then use border-radius to round it out and into the shape of a circle.

Oh, and I ought to take care of that dark text and also add a border while I'm at it, so I can see what I'm doing.

.sticker { border: 20px solid #fff; border-radius: 100%; color: #fff; height: 400px; width: 400px; }

See the Pen "I Voted" Sticker HTML 2 by Geoff Graham (@geoffgraham) on CodePen.

The alignment is all off. Seems like a good spot to drop in some flexbox. This will allow me to center our elements horizontally. I think going with a single-column layout will take care of the vertical alignment.

.sticker { display: flex; flex-flow: column; align-items: center; border: 20px solid #fff; border-radius: 100%; color: #fff; height: 400px; width: 400px; }

Yep, that helps.

See the Pen "I Voted" Sticker HTML 3 by Geoff Graham (@geoffgraham) on CodePen.

The last thing I want to do with the sticker for now is split it up into two halves — a top and a bottom. OK, so yeah, I have explicit elements for those in the HTML (.sticker__top and .sticker__bottom). I could use background-color on each element to make the top half blue and bottom half red, but I actually like the idea of using a linear gradient instead with a hard stop at the halfway mark.

.sticker { background-image: linear-gradient( to bottom, #080968, #080968 50%, #080968 50%, #F81616 50% ); border: 20px solid #fff; border-radius: 100%; color: #fff; display: flex; flex-flow: column; align-items: center; height: 400px; width: 400px; }

Hey now, looking much sharper already!

See the Pen "I Voted" Sticker HTML 4 by Geoff Graham (@geoffgraham) on CodePen.

Time to deal with the top half

The top and bottom halves both occupy 50% of the sticker's height, so the selectors can be combined to hit them both at once. Plus, I'm using flexbox, so I can simply flex those items.

.sticker__top, .sticker-bottom { flex: 0 50%; }

The top half is super weird. The way I see it, there's two rows: one that contains the stars and stripes and the other that contains the heading. I'm going to turn to flexbox again to draw that layout.

.sticker__top { display: flex; flex-flow: row wrap; position: relative; }

That's not really going to change much at the moment because, well, I haven't done anything to define elements for the stars and stripes in the HTML. I'm thinking of using the ::before and ::after pseudo elements on .sticker__top to make those. Again, they can be combined since they share some common properties and values.

.sticker__top::before, .sticker__top::after { content: ""; height: 45%; /* Had to play with this a bit */ margin-top: 2em; /* Move away from the top edge of the sticker */ }

I'm going to cheat and use SVG for the stars. I mean, I guess that's not cheating but it sorta feels like a deviation from a "pure" CSS way of doing things. Oh well.

That said, the stripes can definitely be made in CSS, again, with the same linear gradient background technique that's used to split the sticker up into blue and red halves.

.sticker__top::before { background-image: url("/path/to/star/image.svg"); background-size: 35px; /* Magic number, depends on the image used. */ } .sticker__top::after { background-image: linear-gradient( to bottom, #F81616, #F81616 14%, transparent 14%, transparent 28%, #F81616 28%, #F81616 42%, transparent 42%, transparent 56%, #F81616 56%, #F81616 70%, transparent 70%, transparent 84%, #F81616 84%, #F81616 98%, transparent 100% ); }

That's cool but, crap, things are out of order.

See the Pen "I Voted" Sticker HTML 5 by Geoff Graham (@geoffgraham) on CodePen.

I'm so thankful flexbox has an order property. I'm going to order the stars, stripes and heading at 1, 2 and 3, respectively,

.sticker__top::before { /* Same as before... */ order: 1; } .sticker__top::after { /* Same as before... */ order: 2; } .sticker__top h1 { order: 3; }

If I stop here, the shape of the stars and stripes would be all off and the heading font would be sloppy.

border-radius is still a good way to get the stars and stripes to follow the same circular path as the sticker. The rub is that the bottoms of them have to maintain a flat edge. Since border-radius is a shorthand property, I'm going to drop border-top-left-radius on the stars and border-top-right-radius on the stripes.

It's also worth noting that the stripes are a little wider than the stars. Maybe a 55-45 split? I don't know. I'll go with that and also use relative positioning on the stripes so I can push them to the right a bit to add separation between them and the stars.

.sticker__top::before { /* Same as before... */ flex: 45%; } .sticker__top::after { /* Same as before... */ flex: 55%; position: relative; left: 10px; }

The stars and stripes should flex with the size and width of the heading. I had to play with the font family, font size, letter spacing, and text transform to get something that looks pretty nice. In case you're wondering, I wound up using Raleway for the font. It's not precise, but close enough... at least to my untrained typographical eye.

.sticker__top h1 { font-family: 'Raleway', sans-serif; font-size: 4em; letter-spacing: 3px; line-height: 0; text-transform: uppercase; order: 3; }

See the Pen "I Voted" Sticker HTML 6 by Geoff Graham (@geoffgraham) on CodePen.

Alright, so now the bottom half is making my skin crawl. Gotta tackle that.

Style up the bottom half

So much has already been done. The element for bottom half is already there in the HTML and is sized and positioned the way it should be. I think stripping out the bullet points of the list items and removing the left padding from the unordered list will clean things up a lot.

.sticker__bottom ul { list-style: none; padding: 0; width: 100%; /* Gotta take up the all of the bottom half */ }

But, that's not going to cut it completely. I want that list to run horizontally, wrap lines, and to allow the list items to occupy open space. Yep, that sounds like flexbox again.

.sticker__bottom ul { display: flex; flex-flow: row wrap; align-items: flex-start; justify-content: flex-start; /* same as before... */ } .sticker__bottom li { flex: auto; /* Flex as much as you need, guys */ margin: .75em; /* A liiiiitle breathing room between items */ }

See the Pen "I Voted" Sticker HTML 7 by Geoff Graham (@geoffgraham) on CodePen.

Now I have to make a few tweaks to .sticker__bottom. Specifically, I'm going to make it a little narrower (80% of the full sticker width) to get it off the edge of the sticker and then round its edges... though it might not actually need rounded corners since content is not going to overflow.

.sticker__bottom { border-bottom-right-radius: 100%; border-bottom-left-radius: 100%; width: 80%; }

And, now center the text. I guess that can go on the parent .sticker element since nothing on the sticker is technically left-justified.

.sticker { /* same as before... */ text-align: center; }

Finally, I'm going to do my best to replace the dummy content with the "I Voted" translations. Let me go look those up.

(Heads over to Google Translate.)

Meh, I couldn't find everything I needed. I'm sure it's my lack of patience, but I wound up using some alternatives:

<ul> <li>Yo voté</li> <li>???</li> <li>?? ????</li> <li>Bumoto ako</li> <li>? ????????????</li> <li>???? ????? ????</li> <li>??? ????</li> <li>Ik stemde</li> <li>Szavaztam</li> <li>???????????</li> <li>Anigu waxaan codsaday</li> <li>Tôi ?ã b?u ch?n</li> </ul>

I'm going to have to play around with the font size and to get the same sort of alignment as the IRL sticker, which has rows of: 4 items, 3 items, 3 items, 1 item, 1 item.

Here's where I landed:

.sticker__bottom ul { display: flex; flex-flow: row wrap; font-size: .75em; align-items: flex-start; justify-content: flex-start; list-style: none; padding: 0; width: 100%; }

To get the last two items off the same line, I'm going to single out the second-to-last one using :last-child() so that both of them always flex 100%:

.sticker__bottom li:nth-child(11) { flex: 100%; }

And, lastly, I'm going to change the white border around the sticker from white to blue. Gives it that faux padding we're looking for.

See the Pen "I Voted" Sticker HTML 8 by Geoff Graham (@geoffgraham) on CodePen.

Ding, ready!

I'm going to call this one baked. I know, I know. I should cross-browser test. It would also be wise to find graceful fallbacks for older browsers that do not support flexbox. And, some responsiveness would be nice to have. Maybe someone would like to take those up and share. &#x1f609;

Is this the best way to make the sticker? Probably not. For example, I bet there are some interesting things that can be done with clip-path instead of the way I fumbled through background gradients. And, if I had to do it again, I might even consider going with a CSS Grid layout on the parent because there are clearly opportunities to work in two directions instead of one.

But that's the beauty of CSS. There's more than one way to accomplish something.

Happy Election Day, friends. &#x1f1fa;&#x1f1f8;

The post Rocking California’s “I Voted” Sticker in CSS for Election Day 2018 appeared first on CSS-Tricks.

What’s New In CSS?

Css Tricks - Fri, 11/02/2018 - 12:44pm

Rachel hooks us up with what the CSS Working Group is talking about:

  • Styling scrollbars. This would come with properties like scrollbar-width and scrollbar-color. The best we have right now is proprietary WebKit stuff.
  • Aspect ratios. I imagine the CSS portion of this journey will be best handled if it plays nicely with the HTML intrinsicsize stuff.
  • Matching without specificity. :where() is :matches() with no specificity, and :matches() may become :is().
  • Logical Properties shorthand. The team is discussing a shorthand syntax for Logical Properties and the possibility logical would be default over the current physical with a defined "mode" in the stylesheet.

Direct Link to ArticlePermalink

The post What’s New In CSS? appeared first on CSS-Tricks.

Simple Named Grid Areas

Css Tricks - Fri, 11/02/2018 - 4:02am

I think of named grid areas in CSS Grids as bring-your-own syntactic sugar. You don't absolutely need them (you could express grid placement in other ways), but it can make that placement more intuitive. And, hey, if I'm wrong about that, correct me in the comments.

Say you set up a 3-column grid:

.grid { display: grid; grid-gap: 1rem; grid-template-columns: 200px 1fr 1fr; }

No rows defined there; those are implicit and will appear as needed. We could define them, we just aren't, because like most situations in web design, we don't care how tall the items are — the height will grow as needed to accomodate the content.

Now, how do we place something in that very top-left position in the grid? We could tell the grid to place it there like this:

.item { grid-column: 1 / 2; /* start at the first grid column line and end at the second */ }

That works, although that .item better be the first child of .grid. Otherwise, something else may implicitly be placed there and .item will kick down to the next open row. If we wanted to be super sure to place it in the top-left, we could do the row as well:

.item { grid-column: 1 / 2; grid-row: 1 / 2; }

Now it will be in the top-left for sure, even if other items are explicitly placed there (they'll just overlap). We can even shorten things up with the grid-area property:

.item { grid-area: 1 / 1 / 2 / 2; }

All those 1's and 2's might be intuitive enough for now, but the numbers become a bit much in more complex grids involving both column and row placement.

Check this. While we are defining the columns, we can name them with a separate property:

.grid { display: grid; grid-gap: 1rem; grid-template-columns: 200px 1fr 1fr; grid-template-areas: "pro a b" "pro c d"; }

Every quoted group in grid-template-areas is a row. Inside are names I just made up. Could be just about anything, as long as it makes sense to you. See how the word "pro" is repeated twice there on two rows? That's important, as it's saying that we could place a grid item where that value "pro" is and it will be in the first of three columns and span two rows. Pretty intuitive, yeah?

We place it like this:

.pro-features { /* rather than */ grid-area: 1 / 1 / 2 / 3; /* we can now do */ grid-area: pro; }

Here's that simple example:

See the Pen Simple Named Grid Areas by Chris Coyier (@chriscoyier) on CodePen.

Want to get even more descriptive with a grid? Try drawing it in your CSS comments.

The post Simple Named Grid Areas appeared first on CSS-Tricks.

Understanding React Render Props and HOC

Css Tricks - Thu, 11/01/2018 - 9:25am

Here’s a great post by Aditya Agarwal on the difference between render props and higher-order components in React. I particularly like the demo he chose to explain the two. But, to summarize:

Higher-order components (HOCs) take a component and return a component. So let’s say you have a component called Username that just returns a string of a user’s name and you want to capitalize that somewhere – this is the perfect opportunity to use a HOC that wraps that Username component and changes each character. Just like the excellent tutorial Kingsley Silas wrote up here on CSS-Tricks.

HOCs are particularly useful for when you want to modify a component and then use it in a bunch of places, or to make tiny batches of code to prevent overwhelming a component with too many options and props.

A render prop on the other hand is “a function prop that a component uses to know what to render.” At least, that’s what the React docs say, but it took me a while to figure it out. As far as I understand, it lets you provide a way for a React component (typically one that just has a bunch of data you want to reuse) and give it to another (so a component that then renders that data).

here’s a great example of this in the React docs:

class MouseTracker extends React.Component { render() { return ( <div> <h1>Move the mouse around!</h1> <Mouse render={mouse => ( <Cat mouse={mouse} /> )}/> </div> ); } }

What’s happening here is that someone defined a Mouse component in the codebase that provides x + y coordinates based on the position of the user’s mouse. This Mouse component then returns a bunch of data that we store as mouse and then pass it down into the Cat component which is what renders something with that data.

This is great when you want to reuse the data from Mouse but also when you want to pass lots of different types of data into the Cat component. Say you want Cat to render something else based on the type of data you feed into it.

So, to summarize: HOCs and render props are two ways to do similar work. Namely, they can break our code into lots of reusable bits and encourage us to make components that are more flexible in the long run.

Direct Link to ArticlePermalink

The post Understanding React Render Props and HOC appeared first on CSS-Tricks.

Symbolic Links for Easier Multi-Folder Local Development

Css Tricks - Thu, 11/01/2018 - 4:22am

You know how you open a "project" in a local code editor? I guess different editors have different terminology for it, but essentially what you are doing is opening a folder/directory and it shows you a sidebar full of files and folders you can navigate through and such.

Typically there is one parent folder, and everything else is within that folder. Right? Well, it doesn't have to be! That's where symbolic links come in.

Otherwise known as symlinks, they are like pointers to another place. While you don't have to actually move the folder you are referencing, you can create a pointer to it that behaves as if you did.

You can create them right from the command line:

ln -s /path/to/original/ /path/to/link

You'll get a link that looks like an "alias" on macOS. Ya know, the things you can make by right-clicking an item or going File > Make Alias. But they are different. In my experience, aliases tend not to work in code editors, but symlinks do.

Looks like an alias, but it's really a symlink.

I was actually lazy (hey, I prefer GUIs for just about everything) and used Nick Zitzmann's symboliclinker context menu plugin to help make the link I wanted (and allow me to make other ones super easy).

Why bother? I've had a handful of occasions over the years, but here's one that just came up for me. I'm working on a WordPress theme, and there is a WordPress Functionality Plugin that goes with it. Ideally, I'd have just my theme folder open in my code editor (no need to have the entire WordPress root there, that would just slow my editor and make searching a mess). But I'd also like to have that plugin open at the same time, so in case I'm calling functions and such that the plugin controls, I can see both. But these folders are in totally different places...

No matter, I can put a symlink to the plugin in the theme. (You may want to .gitignore it, depending on your deployment setup and such.) Now I can search and find things in both places like I want:

I know that some editors have their own concept of this, like VS Code's Multi-root Workspaces and how you can Project > Add Folder to Project in Sublime. But symlinks are a way to do the same thing but in a cross-editor and cross-system way that everyone can use!

The post Symbolic Links for Easier Multi-Folder Local Development appeared first on CSS-Tricks.

monday.com, a new way to manage your work! Meet the new visual project management tool

Css Tricks - Thu, 11/01/2018 - 4:13am

(This is a sponsored post.)

monday.com is a centralized platform for teams to manage every detail of their work, from high-level roadmap planning to the specifics of day-to-day tasks, while building a culture of transparency. It is a tool for an any-sized team, which can start with two freelancers working together to thousands collaborating across the globe. The tool is really popular amongst non-tech teams, often replacing burdensome excel files, whiteboards, and excessively long meetings.

The main thing is that it’s not limited to tech companies, it is used by churches, construction companies, schools and universities, startups, fortune 500 companies including WeWork, Samsung, Discovery Channel, Wix, NBC, General Assembly, McDonalds, Uber, Wix, AOL, and Adidas. Currently, it has over 22,000 paying teams.

monday.com is a tool to help people work better together. monday.com is not a project management tool because it isn’t projects that need managing, it’s people. People are any company’s most valuable resource and as people, we all face the same workplace challenges; communicating with others, not feeling appreciated or motivated to do our jobs, a lack of understanding of how our work fits into the bigger picture, among so many others. Those are the essential problems Monday is trying to solve.

What can this app do?
  • Creating and managing project’s milestones
  • Creating and assigning task
  • Attaching files to any project’s tabhe projects on the go.
  • Using mobile applications to manage projects
  • Communicating with your team members
  • Updating team using the news feed
  • Possible to keep clients in the loop
  • Organizing the organization into teams
  • Creating detailed project’s charts and reports
  • Tracking the time your team members spend on tasks
  • Managing projects’ financials
  • Website as well as a desktop app for mac and windows

monday.com aims to make every user feel empowered and part of something bigger than their own individual tasks, and as a result, to boost collective productivity and transparency.

Direct Link to ArticlePermalink

The post monday.com, a new way to manage your work! Meet the new visual project management tool appeared first on CSS-Tricks.

Subset Numerals so They’re as Awesome as the Rest of Your Content

Css Tricks - Wed, 10/31/2018 - 3:34am

You’re putting the finishing touches on your new million-dollar-idea — your copy is perfect, your color scheme is dazzling, and you’ve found a glorious font pairing (who knew Baskerville and Raleway looked so great together? You did.) but there’s one problem: Raleway’s pesky lowercase numbers make your shopping cart look confusing and overwhelm the user.

This is a fairly mundane problem, but an issue that can make beautiful typefaces unusable if numbers are an important part of your site; a store or an analytics dashboard for example. And this isn’t just an issue with lowercase numerals. Non-monospaced numerals can be equally distracting when glancing at a list of numbers.

We’re going to look at a few techniques to combat this problem, but first we need to find a font whose numerals we can use instead of our main body font. There’s no cut-and-dry way of finding your font twin. The most important characteristics to search for are the weight and width so that you can match it to that of your original font. If you intend to use numerals at multiple weights, try looking at fonts that have a wide range of weights to up your chances at matching your original. You may end up needing a different numeral font for each weight or mismatching the weights of the font pairs, but that’s fine because there are in fact no font police.

Here are a few Google Font pairings that match well enough to not be noticeable at small sizes:

Method 0: Wrap ‘em in spans @import url('https://fonts.googleapis.com/css?family=Raleway:400|Nunito:300'); body { font-family: 'Raleway', sans-serif; } .numeral { font-family: 'Nunito', 'Raleway', sans-serif; } Your total comes to $<span class="numeral">15</span>.<span class="numeral">99</span>

This is not a good solution. Having to add to the markup is bad, and loading both fonts in their entirety is not great, but if you don’t have a lot of content and want a simple solution, then there’s no shame in it.

What we’d prefer to find is a CSS-only solution that isolates the numerals of the number font and loads them instead of (or before the main font) without having to change the HTML. Read on.

How font-family works

The following methods rely on creating a @font-face declaration which only refers to our preferred subset of numerals, and references them in the font stack as normal:

body { font-family: 'Custom Numeral Font', 'Main Font', sans-serif; }

By ordering the subsetted font first in your font-family declaration, the browser will default to it and will fallback to the subsequent fonts for glyphs that are not available in the first. This is a really important distinction — the browser is not only checking that the declared font is available (locally or imported via @font-face), but it is also checking that its character map contains the requested character and will pass onto the next font if it doesn’t, on a character-by-character basis. By the way, the spec for the font-matching algorithm is a surprisingly interesting read.

It’s important to note that the browser will prioritize the font family over the font weight and style, so if you subset the numerals for only a normal weight and then have a number inside a bold-style element, the browser will choose to show the normal-weight character from the numeral font rather than the bold-weight character of the main font. Basically, if you’re doing this, make sure you do it for all the font weights you’ll show numbers in.

Method 1: Font Squirrel custom subsetting

If you self-host your font files instead of serving them from a hosted service like Adobe Fonts or Google Fonts, then you can use the expert configuration of Font Squirrel’s Webfont Generator to create files that only contain the numeral subset. Read the font’s license agreement to make sure this type of manipulation is okay before proceeding.

Setting the Character Type for the replacement font to Numbers in the Font Squirrel interface.

Once you have the subsetted font files, you can use them as you normally would. Check out this article for more information about @font-face and file type browser support.

@font-face { font-family: 'Nunito'; src: url('nunito-light-webfont.woff2') format('woff2'), url('nunito-light-webfont.woff') format('woff'); font-weight: normal; font-style: normal; } body { font-family: 'Nunito', 'Raleway', sans-serif; }

If you’re being performance-conscious, you can also subset your main font to remove its numeral glyphs and shave off a few extra bytes.

Method 2: @font-face unicode-range subsetting

The unicode-range property of @font-face is mostly used to declare the character set the font files contain in order to help the browser decide whether or not to download the files; a big potential performance boost for multi-language sites that use non-Latin alphabets. The flip-side is that unicode-range also restricts the @font-face declaration to the specified range, meaning that we can only use it to make certain portions of the font files available for use in the browser.

@font-face { font-family: 'Nunito'; src: url('nunito-light-webfont.woff2') format('woff2'), url('nunito-light-webfont.woff') format('woff'); font-weight: normal; font-style: normal; unicode-range: U+30-39; /* 0-9 / } body { font-family: 'Nunito', 'Raleway', sans-serif; }

This is worse for performance than the previous method as the browser still has to download the whole font file to use the numerals, but preferable if the license agreement disallows manipulation of the files.

Sadly, we can’t use this method to subset fonts already loaded by an external service, but it can be used on local fonts:

@font-face { font-family: 'Times Numeral Roman'; src: local('Times New Roman'); unicode-range: U+30-39; /* 0-9 */ }

This is a neat way of tweaking particular characters of your main font, perhaps subsetting for just an ampersand or preferred curly quotes (in which case you’d have to give up the “Times Numeral Roman” pun), with no performance loss as the local font will just be ignored if it doesn’t exist. You can check common system font availability here. And you can become Queen of the Type Nerds by making a site that can only be appreciated properly if you have all its subsetted fonts downloaded locally, premium esoteric.

Support for unicode-range is pretty good, but note that the subset font will be used for all text if it’s not supported, so maybe don’t make it Papyrus. Or if you really want to use Papyrus, you can be sneaky and add another web-safe font first so that unsupported browsers will default to it instead of Papyrus:

@font-face { font-family: 'Backup Font'; src: local('Arial'); unicode-range: U+60; /* backtick because I can't think of a more innocuous character */ } @font-face { font-family: 'Papyrus Ampersand'; src: local('Papyrus'); unicode-range: U+26; /* & */ } body { font-family: 'Backup Font', 'Papyrus Ampersand', 'Main Font', sans-serif; } Method 3: Google Fonts text subsetting

The Google Fonts API comes with a few handy extra options to aid optimization by specifying only particular font weights, styles and alphabets (the subset parameter takes a list of alphabets like greek,cyrillic and not a unicode range, sadly), but there’s also a little-known “beta” parameter called text which is ostensibly for use in titles and logos but works equally well for our purpose:

@import url('https://fonts.googleapis.com/css?family=Raleway:400'); @import url('https://fonts.googleapis.com/css?family=Nunito:300&text=0123456789'); body { font-family: 'Nunito', 'Raleway', sans-serif; }

So simple! So elegant!

The text parameter can take any UTF-8 characters, but make sure to URL encode them if they’re not alphanumeric. The only possible issue with this method is that we’re not creating a custom name with @font-face, so if the user already has the subset font on their system, it will use that font in its entirety.

I haven’t been able to find any other hosted font services that offer this level of granularity for subsetting but do comment below if you come across one.

A few use cases Live Demo Live Demo Live Demo Live Demo

The post Subset Numerals so They’re as Awesome as the Rest of Your Content appeared first on CSS-Tricks.

Syndicate content
©2003 - Present Akamai Design & Development.