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

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.

Desktop

Chrome Opera Firefox IE Edge Safari
19* 15 4* 10 12 6*

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
6.0-6.1* 46 No 67 69 62

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

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

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%;
}

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. 😉

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. 🇺🇸

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

What’s New In CSS?

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

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

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

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

(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

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.

Emphasizing Emphasis

I think Facundo Corradini is right here in calling out our tweet. If you’re italicizing text because it should be styled that way (e.g. using italics to display a person’s internal thought dialog, as illustrated in our example), then that’s an <i> and not an <em>, because <em> is for stress emphasis — as in, a word you would emphasize with your voice, if spoken, to affect meaning.

Plus, I’m always down for long-form articles about the nuances of a handful of HTML elements!

Direct Link to ArticlePermalink

The post Emphasizing Emphasis appeared first on CSS-Tricks.