About

Tuesday, June 30, 2020

Responsive Styling Using Attribute Selectors

One of the challenges we face when implementing class-based atomic styling is that it often depends on a specific breakpoint for context.

<div class="span-12"></div> <!-- we want this for small screens  -->
<div class="span-6"></div>  <!-- we want this for medium screens -->
<div class="span-4"></div>  <!-- we want this for large screens  -->

It’s common to use a prefix to target each breakpoint:

<div class="sm-span-12 md-span-6 lg-span-4"></div>

This works well until we start adding multiple classes. That’s when it becomes difficult to keep a track what relates to what and where to add, remove. or change stuff.

<div class="
  sm-span-12 
  md-span-6 
  lg-span-4 
  sm-font-size-xl 
  md-font-size-xl 
  lg-font-size-xl 
  md-font-weight-500 
  lg-font-weight-700">
</div>

We can try to make it more readable by re-grouping:

<div class="
  sm-span-12 
  sm-font-size-xl 


  md-span-6 
  md-font-size-xl 
  md-font-weight-500 


  lg-span-4 
  lg-font-size-xl 
  lg-font-weight-700">
</div>

We can add funky separators (invalid class names will be ignored):

<div class="
  [
   sm-span-12 
   sm-font-size-xl 
  ],[
   md-span-6 
   md-font-size-xl 
   md-font-weight-500 
  ],[
   lg-span-4 
   lg-font-size-xl 
   lg-font-weight-700
  ]">
</div>

But this still feels messy and hard to grasp, at least to me.

We can get a better overview and avoid implementation prefixes by grouping attribute selectors instead of actual classes:

<div 
  sm="span-12 font-size-lg"
  md="span-6 font-size-xl font-weight-500"
  lg="span-4 font-size-xl font-weight-700"
>
</div>

These aren’t lost of classes but a whitespace-separated list of attributes we can select using [attribute~="value"], where ~= requires the exact word to be found in the attribute value in order to match.

@media (min-width: 0) {
 [sm~="span-1"] { /*...*/ }              
 [sm~="span-2"] { /*...*/ }   
 /* etc. */ 
}
@media (min-width: 30rem) {
 [md~="span-1"] { /*...*/ }   
 [md~="span-2"] { /*...*/ }   
 /* etc. */   
}
@media (min-width: 60rem) {
 [lg~="span-1"] { /*...*/ }   
 [lg~="span-2"] { /*...*/ }   
 /* etc. */   
}

It may be a bit odd-looking but I think translating atomic classes to  attributes is fairly straightforward (e.g. .sm-span-1 becomes [sm~="span-1"]). Plus, attribute selectors have the same specificity as classes, so we lose nothing there. And, unlike classes, attributes can be written without escaping special characters, like /+.:?.

That’s all! Again, this is merely an idea that aims to make switching declarations in media queries easier to write, read and manage. It’s definitely not a proposal to do away with classes or anything like that.

The post Responsive Styling Using Attribute Selectors appeared first on CSS-Tricks.



source https://css-tricks.com/responsive-styling-using-attribute-selectors/

Five 5-minute Videos from Ethan on Design & Accessibility

Ethan:

I’ve been working with Aquent Gymnasium to produce a series of five short tutorial videos, which have been launching over the course of this past week. Since the last video just went live, I’m thrilled to share the whole list with you:

Introduction to using VoiceOver on macOS
Designing beautiful focus states
Flexible and accessible typesetting
Responsively designing with viewport units
Designing beautiful and accessible drop caps

Five minutes is a real sweet spot for a how-to video. Ain’t no time to screw around. I loved every minute of these.

Direct Link to ArticlePermalink

The post Five 5-minute Videos from Ethan on Design & Accessibility appeared first on CSS-Tricks.



source https://ethanmarcotte.com/wrote/takin-five/

When Sass and New CSS Features Collide

Recently, CSS has added a lot of new cool features such as custom properties and new functions. While these things can make our lives a lot easier, they can also end up interacting with preprocessors, like Sass, in funny ways.

So this is going to be a post about the issues I’ve encountered, how I go around them, and why I still find Sass necessary these days.

The errors

If you’ve played with the new min() and max() functions, you may have ran into an error message like this when working with different units: “Incompatible units: vh and em.”

Screenshot. Shows the `Incompatible units: 'em' and 'vh'` error when trying to set `width: min(20em, 50vh)`.
An error when working with different types of units in the min()/ max() function

This is because Sass has its ownmin() function, and ignores the CSS min() function. Plus, Sass cannot perform any sort of computation using two values with units that don’t have a fixed relation between them.

For example, cm and in units have a fixed relation between them, so Sass can figure out what’s the result of min(20in, 50cm) and doesn’t throw an error when we try to use it in our code.

The same things goes for other units. Angular units, for example, all have a fixed relation between them: 1turn, 1rad or 1grad always compute to the same deg values. Same goes for 1s which is always 1000ms, 1kHz which is always 1000Hz, 1dppx which is always 96dpi, and 1in which is always 96px. This is why Sass can convert between them and mix them in computations and inside functions such as its own min() function.

But things break when these units don’t have a fixed relation between them (like the earlier case with em and vh units).

And it’s not just different units. Trying to use calc() inside min() also results in an error. If I try something like calc(20em + 7px), the error I get is, “calc(20em + 7px) is not a number for min.”

Screenshot. Shows the `'calc(20em + 7px)' is not a number for 'min'` error when trying to set `width: min(calc(20em + 7px), 50vh)`.
An error when using different unit values with calc() nested in the min()function

Another problem arises when we want to use a CSS variable or the result of a mathematical CSS function (such as calc(), min() or max()) in a CSS filter like invert().

In this case, we get told that “$color: 'var(--p, 0.85) is not a color for invert.”

Screenshot. Shows the `$color: 'var(--p, 0.85)' is not a color for 'invert'` error when trying to set `filter: invert(var(--p, .85))`.
var() in filter: invert() error

The same thing happens for grayscale(): “$color: ‘calc(.2 + var(--d, .3))‘ is not a color for grayscale.”

Screenshot. Shows the `$color: 'calc(.2 + var(--d, .3))' is not a color for 'grayscale'` error when trying to set `filter: grayscale(calc(.2 + var(--d, .3)))`.
calc() in filter: grayscale() error

opacity() causes the same issue: “$color: ‘var(--p, 0.8)‘ is not a color for opacity.”

Screenshot. Shows the `$color: 'var(--p, 0.8)' is not a color for 'opacity'` error when trying to set `filter: opacity(var(--p, 0.8))`.
var() in filter: opacity() error

However, other filter functions — including sepia(), blur(), drop-shadow(), brightness(), contrast() and hue-rotate()— all work just fine with CSS variables!

Turns out that what’s happening is similar to the min() and max() problem. Sass doesn’t have built-in sepia(), blur(), drop-shadow(), brightness(), contrast(), hue-rotate() functions, but it does have its own grayscale(), invert() and opacity() functions, and their first argument is a $color value. Since it doesn’t find that argument, it throws an error.

For the same reason, we also run into trouble when trying to use a CSS variable that lists at least two hsl()or hsla() values.

Screenshot. Shows the `wrong number of arguments (2 for 3) for 'hsl'` error when trying to set `color: hsl(9, var(--sl, 95%, 65%))`.
var() in color: hsl() error.

On the flip side, color: hsl(9, var(--sl, 95%, 65%)) is perfectly valid CSS and works just fine without Sass.

The exact same thing happens with the rgb()and rgba() functions.

Screenshot. Shows the `$color: 'var(--rgb, 128, 64, 64)' is not a color for 'rgba'` error when trying to set `color: rgba(var(--rgb, 128, 64, 64), .7)`.
var() in color: rgba() error.

Furthermore, if we import Compass and try to use a CSS variable inside a linear-gradient() or inside a radial-gradient(), we get another error, even though using variables inside conic-gradient() works just fine (that is, if the browser supports it).

Screenshot. Shows the At least two color stops are required for a linear-gradient error when trying to set background: linear-gradient(var(--c, pink), gold).
var() in background: linear-gradient() error.

This is because Compass comes with linear-gradient() and radial-gradient() functions, but has never added a conic-gradient() one.

The problems in all of these cases arise from Sass or Compass having identically-named functions and assuming those are what we intended to use in our code.

Drat!

The solution

The trick here is to remember that Sass is case-sensitive, but CSS isn’t.

That means we can write Min(20em, 50vh)and Sass won’t recognize it as its own min() function. No errors will be thrown and it’s still valid CSS that works as intended. Similarly, writing HSL()/ HSLA()/ RGB()/ RGBA() or Invert() allows us to avoid issues we looked at earlier.

As for gradients, I usually prefer linear-Gradient() and radial-Gradient() just because it’s closer to the SVG version, but using at least one capital letter in there works just fine.

But why?

Almost every time I tweet anything Sass-related, I get lectured on how it shouldn’t be used now that we have CSS variables. I thought I’d address that and explain why I disagree.

First, while I find CSS variables immensely useful and have used them for almost everything for the past three years, it’s good to keep in mind that they come with a performance cost and that tracing where something went wrong in a maze of calc() computations can be a pain with our current DevTools. I try not to overuse them to avoid getting into a territory where the downsides of using them outweigh the benefits.

Screenshot. Shows how `calc()` expressions are presented in DevTools.
Not exactly easy to figure out what’s the result of those calc() expressions.

In general, if it acts like a constant, doesn’t change element-to-element or state-to-state (in which case custom properties are definitely the way to go) or reduce the amount of compiled CSS (solving the repetition problem created by prefixes), then I’m going to use a Sass variable.

Secondly, variables have always been a pretty small portion of why I use Sass. When I started using Sass in late 2012, it was primarily for looping, a feature we still don’t have in CSS. While I’ve moved some of that looping to an HTML preprocessor (because it reduces the generated code and avoids having to modify both the HTML and the CSS later), I still use Sass loops in plenty of cases, like generating lists of values, stop lists inside gradient functions, lists of points inside a polygon function, lists of transforms, and so on.

Here’s an example. I used to generate n HTML items with a preprocessor. The choice of preprocessor matters less, but I’ll be using Pug here.

- let n = 12;

while n--
  .item

Then I would set the $n variable into the Sass (and it would have to be equal to that in the HTML) and loop up to it to generate the transforms that would position each item:

$n: 12;
$ba: 360deg/$n;
$d: 2em;

.item {
  position: absolute;
  top: 50%; left: 50%;
  margin: -.5*$d;
  width: $d; height: $d;
  /* prettifying styles */

  @for $i from 0 to $n {
    &:nth-child(#{$i + 1}) {
      transform: rotate($i*$ba) translate(2*$d) rotate(-$i*$ba);
                        
      &::before { content: '#{$i}' }
    }
  }
}

However, this meant that I would have to change both the Pug and the Sass when changing the number of items, making the generated code very repetitive.

Screenshot. Shows the generated CSS, really verbose, almost completely identical transform declaration repeated for each item.
CSS generated by the above code

I have since moved to making Pug generate the indices as custom properties and then use those in the transform declaration.

- let n = 12;

body(style=`--n: ${n}`)
  - for(let i = 0; i < n; i++)
    .item(style=`--i: ${i}`)
$d: 2em;

.item {
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -.5*$d;
  width: $d;
  height: $d;
  /* prettifying styles */
  --az: calc(var(--i)*1turn/var(--n));
  transform: rotate(var(--az)) translate(2*$d) rotate(calc(-1*var(--az)));
  counter-reset: i var(--i);
        
  &::before { content: counter(i) }
}

This significantly reduces the generated code.

Screenshot. Shows the generated CSS, much more compact, no having almost the exact same declaration set on every element separately.
CSS generated by the above code

However, looping in Sass is still necessary if I want to generate something like a rainbow.

@function get-rainbow($n: 12, $sat: 90%, $lum: 65%) {
  $unit: 360/$n;
  $s-list: ();
        
  @for $i from 0 through $n {
    $s-list: $s-list, hsl($i*$unit, $sat, $lum)
  }
        
  @return $s-list
}

html { background: linear-gradient(90deg, get-rainbow()) }

Sure, I could generate it as a list variable from Pug, but doing so doesn’t take advantage of the dynamic nature of CSS variables and it doesn’t reduce the amount of code that gets served to the browser, so there’s no benefit coming out of it.

Another big part of my Sass (and Compass) use is tied to built-in mathematical functions (such as trigonometric functions), which are part of the CSS spec now, but not yet implemented in any browser. Sass doesn’t come with these functions either, but Compass does and this is why I often need to use Compass.

And, sure, I could write my own such functions in Sass. I did resort to this in the beginning, before Compass supported inverse trigonometric functions. I really needed them, so I wrote my own based on the Taylor series. But Compass provides these sorts of functions nowadays and they are better and more performant than mine.

Mathematical functions are extremely important for me as I’m a technician, not an artist. The values in my CSS usually result from mathematical computations. They’re not magic numbers or something used purely for aesthetics. A example is generating lists of clip paths points that create regular or quasi-regular polygons. Think about the case where we want to create things like non-rectangular avatars or stickers.

Let’s consider a regular polygon with vertices on a circle with a radius 50% of the square element we start from. Dragging the slider in the following demo allows us to see where the points are placed for different numbers of vertices:

Putting it into Sass code, we have:

@mixin reg-poly($n: 3) {
  $ba: 360deg/$n; // base angle
  $p: (); // point coords list, initially empty
        
  @for $i from 0 to $n {
    $ca: $i*$ba; // current angle
    $x: 50%*(1 + cos($ca)); // x coord of current point
    $y: 50%*(1 + sin($ca)); // y coord of current point
    $p: $p, $x $y // add current point coords to point coords list
  }
        
  clip-path: polygon($p) // set clip-path to list of points
}

Note that here we’re also making use of looping and of things such as conditionals and modulo that are a real pain when using CSS without Sass.

A slightly more evolved version of this might involve rotating the polygon by adding the same offset angle ($oa) to the angle of each vertex. This can be seen in the following demo. This example tosses in a star mixin that works in a similar manner, except we always have an even number of vertices and every odd-indexed vertex is situated on a circle of a smaller radius ($f*50%, where $f is sub-unitary):

We can also have chubby stars like this:

Or stickers with interesting border patterns. In this particular demo, each sticker is created with a single HTML element and the border pattern is created with clip-path, looping and mathematics in Sass. Quite a bit of it, in fact.

Another example are these card backgrounds where looping, the modulo operation and exponential functions work together to generate the dithering pixel background layers:

This demo just happens to rely heavily on CSS variables as well.

Then there’s using mixins to avoid writing the exact same declarations over and over when styling things like range inputs. Different browsers use different pseudo-elements to style the components of such a control, so for every component, we have to set the styles that control its look on multiple pseudos.

Sadly, as tempting as it may be to put this in our CSS:

input::-webkit-slider-runnable-track, 
input::-moz-range-track, 
input::-ms-track { /* common styles */ }

…we cannot do it because it doesn’t work! The entire rule set is dropped if even one of the selectors isn’t recognized. And since no browser recognises all three of the above, the styles don’t get applied in any browser.

We need to have something like this if we want our styles to be applied:

input::-webkit-slider-runnable-track { /* common styles */ }
input::-moz-range-track { /* common styles */ }
input::-ms-track { /* common styles */ }

But that can mean a lot of identical styles repeated three times. And if we want to change, say, the background of the track, we need to change it in the ::-webkit-slider-runnable-track styles, in the ::-moz-range-track styles and in the ::-ms-track styles.

The only sane solution we have is to use a mixin. The styles get repeated in the compiled code because they have to be repeated there, but we don’t have to write the same thing three times anymore.

@mixin track() { /* common styles */ }

input {
  &::-webkit-slider-runnable-track { @include track }
  &::-moz-range-track { @include track }
  &::-ms-track { @include track }
}

The bottom line is: yes, Sass is still very much necessary in 2020.

The post When Sass and New CSS Features Collide appeared first on CSS-Tricks.



source https://css-tricks.com/when-sass-and-new-css-features-collide/

Styling Layout Wrappers In CSS

Two things that strike me often about the web are how many ways there are to go about the same thing and how many considerations go into even the most seemingly simple things.

Working with wrapper elements is definitely on both those lists. Wrappers (or containers or whatever) are so common — especially when establishing grid layouts and boundaries for the elements inside them — that it’s easy to take them for granted and reach for them without stepping back to consider how they work, why we use them, and how to use them effectively.

Ahmed Shadeed wrote up the most exhaustive article on wrappers I’ve ever read. He provides a brief overview of them before diving into a bunch of considerations and techniques for working with them, including:

  • When to use them
  • How to size them
  • Positioning them
  • Adding margin and padding
  • Working with CSS grid and other display values
  • Breaking out of the wrapper
  • Using CSS custom properties

If you take the images from the article, it tells a pretty cool story.

Direct Link to ArticlePermalink

The post Styling Layout Wrappers In CSS appeared first on CSS-Tricks.



source https://ishadeed.com/article/styling-wrappers-css

Monday, June 29, 2020

Book: The Greatest CSS Tricks Vol. I

Ya know, for a site called “CSS-Tricks” that I’ve run for well over a decade, it’s a little funny we’ve never done a book under that name. I’ve written a book about WordPress and SVG, but never CSS!

Well, allow me to change that. I’ve been working on a “book” called The Greatest CSS Tricks Vol. I, as my attempt to stay true to this site’s name! The big idea to make it like a coffee-table book for CSS, where each chapter is totally independent and talks about one literal CSS trick that I’ve found to be exceptionally clever and useful. A book about quite literally the best CSS tricks I’ve come across over the years.

I quoted the word “book” above because this is the loosest possible definition of a book. I have not yet made it into an eBook format. I have not even considered printing it yet (although there is a “full book” URL available with the whole book together for printing and print-to-PDFing). This book exists as URLs which are essentially fancy blog posts grouped together. I’m also calling it Volume I as there are already ideas for another one!

Some chapters are fairly broadly known concepts that I’m writing up to put a point on. But many of the chapters are based on ideas that can be traced back to individual people and I always try to credit them directly.

Here’s the chapter list so far:

  1. Pin Scrolling to Bottom
  2. Scroll Animation
  3. Yellow Flash
  4. Shape Morphing
  5. Flexible Grids
  6. Border Triangles
  7. Scroll Indicator
  8. Boxy Buttons
  9. Self-Drawing Shapes
  10. Perfect Font Fallbacks
  11. Scroll Shadows
  12. Editable Style Blocks
  13. Draggable Elements
  14. Hard Stop Gradients
  15. Squigglevision

I say so far because I might add a few and rearrange them and such, not to mention it could still use a healthy bit of editing. But I think the bulk of the value of the book is already there.

Value? I think so. While it’s fun to learn some CSS trickery, I think there is value beyond the tricks themselves. Tricks help you see how CSS works at a deeper level. When you understand the trick, you’re seeing how that part of CSS works through a new lens and it helps you be more in tune with the nature of that CSS. It will help you reach for those CSS properties more intuitively when you know what they are capable of.

In another sense, it’s like taking a walk with weights in your backpack. You do it on purpose so that when you walk normally, it feels easier. The tricks are like mental weights. They make writing non-tricky CSS feel easier.

So about buying the book. You don’t buy the book directly. What you buy is an MVP Supporter membership to this site. When you’re an MVP Supporter, you have access to the book, and more. This is the whole package:

  • No Ads. You see no ads on this site, except for sponsored posts which are just blog posts and I try to make useful anyway.
  • Extra Content. You can read the digital books I’m making (you can already read some chapters, but they are under progress.)
  • Easier Commenting. You’ll be logged in, so leaving comments is easier and won’t require the delay for approval.
  • Good feels. An extreme sense of satisfaction of supporting this site and our commitment to bringing you useful tech knowledge.

It’s just just $20/year.

Have I, or this site, helped you out over the years? This is the best way to say thanks.

Also, if you would really like to have access to read the book, and can’t afford it right now, I totally get it. Email me at chriscoyier@gmail.com and we can work that out.

The post Book: The Greatest CSS Tricks Vol. I appeared first on CSS-Tricks.



source https://css-tricks.com/book-the-greatest-css-tricks-vol-i/

Saturday, June 27, 2020

Quick Tips for High Contrast Mode

Sarah Higley has some CSS tricks up her sleeve for dealing with High Contrast Mode on Windows, which I learned is referred to as WHCM.

Here’s the first trick:

[…] if the default CSS outline property doesn’t give you the visual effect you want [in WHCM] for focus states, there’s a very simple fix. Instead of overriding default browser focus styles with outline: none, make it transparent instead: outline 3px solid transparent.

That will essentially do nothing outside of WHCM, but in WHCM, it will be a thick white border, which is a strong, good visual focus style.

Direct Link to ArticlePermalink

The post Quick Tips for High Contrast Mode appeared first on CSS-Tricks.



source https://sarahmhigley.com/writing/whcm-quick-tips/

The Return of the 90s Web

One of my forever-lessons here on CSS-Tricks is that having your own website and blogging on it is a good idea. It’s probably one of the best decisions I’ve ever made, as it’s been a direct source of fun, career development and, eventually, income.

I always chuckle at little blogging is cool again declarations from the community. It’s always cool, my friends. But it is always nice to see more people pick it back up.

I enjoyed this post from Max Böck that gets into how what is old is new again. Server side rendering! Personal websites! Blogging! Heck yes.

Direct Link to ArticlePermalink

The post The Return of the 90s Web appeared first on CSS-Tricks.



source https://mxb.dev/blog/the-return-of-the-90s-web/

In Defense of a Fussy Website

The other day, I was doom-scrolling Twitter and saw a delightful article titled “The Case for Fussy Breakfasts.” I love food — especially breakfast — and since the pandemic hit I’ve been using my breaks in between meetings (or, shh, sometimes in meetings) to make a full bacon, poached egg, vegetable plate. Suffice to say, I really got into the article. This small joy of creating a bit of space for myself for the most important meal of the day has been meaningful to me — while everything else feels out of control, indulging in some ceremony has done a tiny part to offset the intensity of our collective situation.

It caused me to think of this “fussiness” as applied to other inconsequential joys. A walk. A bath. What about programming?

While we’re all laser-focused on shipping the newest feature with the hottest software and the best Lighthouse scores, I’ve been missing some joy on the web. For example, I’ve come across apps that seem to convey little care for UX, guidance, richness, and… well, let’s just say that for humans trying to communicate through a computer, we’re certainly bending a lot to… the computer.

Which is a good reminder for us all: the web is more than a mere document reader. While I do love me a healthy Lighthouse score, some of these point matrixes seem to be driven more by our own developer ego in some form of gamification race to the creative bottom rather than a challenge or opportunity. It’s like a hyper-focused attention to shedding bytes and server requests is coming at the expense of creative ways to accomplish delightful experiences. It’s still possible to dazzle users with a solid combination of content, color, and layout if we’re willing to be a bit adventurous — with little to no additional weight at all!

A few of my favorite personal developer sites these days are from Josh Comeau, Johnson Ogwuru and Cassie Evans. The small touches and careful attention to detail lead to these little a-ha! moments that make me want to stick around for a while. I wander around the site, exploring, learning, and feeling more connected to each of these talented devs as people. And notice how they pull it off without laggy performance. They flex their creative and technical muscles and put pure pride into their work and it intrigues me!

Just Corneau uses clever illustration and layout combinations that make his site fun to look at — not to mention great content we can all learn from.

It’s easy to get stuck in absolutes and one absolute to watch out for is the belief that anything fun or featuring a flair of style mean it’s “not useful.” I’d argue that the opposite is true. Emotions attach to the limbic system, making memories easier to recall. If your site is a flat bit of text, how will anyone remember it?

Don’t you want to build the site that teams in companies the world over remember and cite as an inspiration? I’ve been at four different companies where people have held up Stripe’s site as an aspirational example. Stripe took chances. Stripe told stories. Stripe engaged the imagination of developer and spoke directly to us.

It honestly makes me a little sad to acknowledge the irony of using a site as an example of what to do then tossing out the things that make it great for other priorities. Any creativity, risk, and intention that goes into great experiences like this gets slowly, piece by piece, chipped away by the drumbeat of “usefulness.” It’s like missing the forest for the trees.

It’s clearly apparent when a site is done with care and excitement. You feel it as you visit, that hum of intention. These are the sites with low bounce rates and the best engagement metrics. They’re the ones that elicit questions like “How can I contribute?” No gimmicks necessary.

Sure, there are lots of factors at play. I get it. Every person or company has constraints and competing priorities. Of course, we all have to get things over the line.

Perhaps a challenge: What small thing can you incorporate into a project that adds a dash of delight to the user experience? Can you start with a something like a hover effect on a link or button? Hey, I didn’t start my new breakfast regimen with a perfectly poached egg; I started by making a goofy scrambled one and I improved on it from there. We can all do the same when it comes to finding opportunities to create engaging websites. Can you outsource one graphic? Can you introduce a tiny easter egg? Perhaps you can write something with a little more personality than the typical corporate lingo.

If something is meaningful to you, the audience you gather will likely be the folks that find it meaningful too.

The post In Defense of a Fussy Website appeared first on CSS-Tricks.



source https://css-tricks.com/in-defense-of-a-fussy-website/

Line-Animated Hamburger Menu

This kind of SVG + CSS animation trickery is catnip to me. Mikael Ainalem shares how to draw a hamburger icon (the “three lines” thing you’re well familiar with), but then animate it in a way that is surprising and fun by controlling the SVG properties in CSS.

The trick is that the top and bottom lines aren’t just a straight <line /> but a <path /> that curves up, down, and around forming the cross. You can only see part of the line (making it appear straight at first) because the stroke-dasharray only reveals part of the line. Then, by animating both the stroke-dasharray and stroke-dashoffset, the ✕ is formed.

Direct Link to ArticlePermalink

The post Line-Animated Hamburger Menu appeared first on CSS-Tricks.



source https://uxdesign.cc/the-menu-210bec7ad80c

Friday, June 26, 2020

Grid for layout, flexbox for components

When should we reach for CSS grid and when should we use flexbox? Rachel Andrew wrote about this very conundrum way back in 2016:

Flexbox is essentially for laying out items in a single dimension – in a row OR a column. Grid is for layout of items in two dimensions – rows AND columns.

Ahmad Shadeed wrote a post where he gives the same advice, but from a different angle. He argues we should use grid for layout and flexbox for components:

Remember that old layout method might be perfect for the job. Overusing flexbox or grid can increase the complexity of your CSS by time. I don’t mean they are complex, but using them correctly and in the right context as explained from the examples in this article is much better.

Speaking of which, there’s so many great layout examples in this post, too.

Direct Link to ArticlePermalink

The post Grid for layout, flexbox for components appeared first on CSS-Tricks.



source https://ishadeed.com/article/grid-layout-flexbox-components/

The Mad Magazine Fold-In Effect in CSS

This was always my favorite thing in Mad magazine. One page (the inside of the back cover, I think) was covered in a zany illustration. You folded that page in thirds, covering up the middle-third of that image, and a new image would form because the illustration was designed to perfectly line up with those folds. The new image (and text!) was part of the joke.

Every one was a clever trick, so of course, I’m delighted to see that trick make it’s way to CSS, courtesy of Thomas Park.

I’m pretty surprised Thomas was able to do it with a single state (:hover / :active) . I would have bet a nickel that it would have needed @keyframes to adjust the 3D transforms into different positions during the animation, but it looks like multiple transitions happening (both parent and child) handle that.


If you’re in the mood for other cool CSS paper effects…

Here’s a new one from Lynn Fischer:

A classic from Mandy Michael:

And more folding from Mattia Astorino:

Direct Link to ArticlePermalink

The post The Mad Magazine Fold-In Effect in CSS appeared first on CSS-Tricks.



source https://thomaspark.co/2020/06/the-mad-magazine-fold-in-effect-in-css/

Some Typography Links

I just can’t stop opening excellent typography-related articles, which means I need to subject you to blog posts that round them up so I can clean up my open tabs.

Vistaserve is “a grass-roots web hosting initiative hailing from Thornbury, Australia. Inspired by the quirky web of the 90s, we allow users to create home pages, your own little sandbox on the World Wide Web, as it were.” Caitlin & Paul (I think the no-last-name thing is part of the aesthetic) wanted to get the fonts right, which meant removing anti-aliasing (the thing that makes fonts look good on screens!). CSS was no help. Turned out to be quite a journey involving literally rebuilding the fonts.


Thomas Bohm makes the point that the kerning around punctation may require special attention. For example, a question mark needing a little extra space or moving a superscript number away from butting against a letter.

You could do it manually with stuff like &thinsp; or &hairsp in between characters. But I’m far too lazy for that unless I’m working on a very special piece. Personally, I just cross my fingers that the font I’m using is high quality enough to have thought of and implemented this sort of attention to detail.


I’m sure we’ve all seen, “The quick brown fox jumps over the lazy dog” as a tester string for type, because it uses all the characters in the alphabet. Jonathan Hoefler created some new proofing text that is much more helpful for typographers like him.

That’s deep in the type nerd weeds there. More useful perhaps is another recent post from Jonathan on pairings. I’ve probably read dozens of posts on font pairings in my life, but this one resonates the most.

Some of the most dazzling typographic pairings — and certainly my favorites — are those that use unexpected fonts together. At left, the grey flannel suit that is Tungsten Compressed is paired with crimson silk doublet of the St. Augustin Civilité, a fiery sixteenth century typeface that demands a good foil.


If you’ve got macOS Catalina, you’ve got access to some really nice fonts you might not know about that need to be manually downloaded. Ralf Herrmann has the story on what you get:

You can download the fonts right from Font Book

I get Erik Kennedy’s Learn UI Design newsletter, and he mentions using Calena in it…

Overall, Canela walks this balance between the warmth of human handwriting and stately details. It makes me think of something literary, which is why I used it for project in one of the new video lessons in Learn UI Design.


Mark Boulton has a cool new site: TypeSpecimens.

Type specimens are curious objects. They aim to inspire designers. They are tools with which to make design decisions. They are also marketing material for foundries. This project will dig into specimens from these three perspectives: as artefacts made by and for font designers to evolve type culture; as tools for font users to make decisions about choosing and using type; and as effective marketing tools.

The post Some Typography Links appeared first on CSS-Tricks.



source https://css-tricks.com/some-typography-links-2/

Thursday, June 25, 2020

The Analytics That Matter

I’ve long been skeptical of quoting global browser usage percentages to justify their usage of browser features. It doesn’t matter what global usage of a browser is, other than nerdy cocktail party fodder. The usage that matters is what users on your site are using, and that can be wildly different from site to site.

That idea of tracking real usage of your actual site concept has bounced around my head the last few days. And it’s not just “I can’t use CSS grid because IE 11 has 1.42% of global usage still” stuff, it’s about measuring metrics that matter to your site, no matter what they are.

Performance metrics are a big one. When you’re doing performance testing, much of it is what you would call synthetic testing. An automated browser loads your site and tracks what it finds as it loads, like the timing of a thing, the size of assets, the number of assets, etc. Synthetic information like this enters my mind when spending tons of time on performance. “I bet I can get rid of this one extra request,” I think. “I bet I can optimize this asset a little further.” And the performance tools we use report this kind of data to us readily. How big is our JavaScript bundle? What is our “Largest Contentful Paint”? What is our Lighthouse performance score? All things that are related to performance, but aren’t measuring actual user’s experience.

Let that sit for a second.

There are other analytics we can gather on a site, like usage analytics. For example, we might slap Google Analytics on a site, doing nothing but installing the generic snippet. This is going to tell us stuff like what pages are the most popular, how long people spend on the site, and what countries deliver the most traffic. Those are real user analytics, but it’s very generic analytic information.

If you’re hoping for more useful analytics data on your site, you have to think about it a little harder up front. What do you want to know? Maybe you want to know how often people use Feature X. Or you want to know how many files they have uploaded this week. Or how many messages they have sent. Or how many times they have clicked the star button. This is stuff that tells you how your site is doing. Generic analytics tracking won’t do that; you’ll have to write a little JavaScript to capture and report on those things. It takes a little effort to get the analytics you really care about.

Now apply that to performance tooling.

Rather than generic synthetic tests, why not measure things that are actually important to your specific site? One aspect to this is RUM, that is, “Real User Monitoring.” So rather than a single synthetic test being the source of all performance testing on your site, you’re tracking real users actually using the site on their actual devices. That makes a lot of sense to me, but aside from the logic of it, it unlocks some important data.

For example, one of Google’s Web Core Vitals, which are soon to affect the SEO of our pages, include a metric called First Input Delay (FID) and you have to collect data via JavaScript¹ on your page to use it.

Another Web Core Vital is “Largest Contentful Paint” which is a fascinating attempt at a more meaningful performance metric. Imagine a metric like “start render” or the first page paint. Is that interesting? Sorta. At least it is signaling to the user that something is happening (probably). Yet that first render might not be actually useful content, like the headline and body copy of a news article. So this metric makes a guess at what that useful content probably is and measures that. Very clever.

But, why guess? I get why Google has to guess. They have to measure LCP on a bazillion sites and provide generically useful measurements. But on your own site (again, where the focused analytics actually matter) we can tell performance tools which elements matter us and record when they render. Personally, I’d care about when the article itself renders on this site. With SpeedCurve’s hero rendering time, I could do something like:

<main elementtiming="article"></main>

<!-- or focus on the top of the page, like the "hero" timing suggests -->
<header elementtiming="hero"></header>

Now I’m measuring what matters to my site and not just generic numbers.

Similarly, FID is cool and all, but why not fire off a JavaScript event telling performance tooling when things happen that are important to your site. For example, on CodePen, we’d do that when the editor is ready to use. That’s called User Timing and it’s a dang W3C spec!

Editors.init();
performance.mark("Editors are initialized.");

These kind some-effort-required analytics are definitely better than the standard fare. Sure, a performance budget that warns you when you go over 200KB of JavaScript is great, but a performance budget that warns you when a core feature of your app isn’t ready until 1.4 seconds when your budget is 1.1 seconds is way more important.

  1. I say this because I was trying to make a chart on the SpeedCurve of the three Web Core Vitals, and you can’t add FID unless you have LUX running, which is their RUM thing. Phew that was a lot of acronyms, sorry.

The post The Analytics That Matter appeared first on CSS-Tricks.



source https://css-tricks.com/the-analytics-that-matter/

How to Disable Code: The Developer’s Production Kill Switch

The following is a guest post written by Carlos Schults.

Being able to disable code in production is a power that many developers aren’t aware of. And that’s a shame. The ability to switch off some portions—or even complete features—of the codebase can dramatically improve the software development process by allowing best practices that can shorten feedback cycles and increase the overall quality.

So, that’s what this post will cover: the mechanisms you can use to perform this switching off, why they’re useful and how to get started. Let’s dig in.

Why Would You Want to Disable Code?

Before we take a deep dive into feature flags, explaining what they are and how they’re implemented, you might be asking: Why would people want to switch off some parts of their codebase? What’s the benefit of doing that?

To answer these questions, we need to go back in time to take a look at how software was developed a couple of decades ago. Time for a history lesson!

The Dark Ages: Integration Hell

Historically, integration has been one of the toughest challenges for teams trying to develop software together. 

Picture several teams inside an organization, working separately for several months, each one developing its own feature. While the teams were working in complete isolation, their versions of the application were evolving in different directions. Now they need to converge again into a single, non conflicting version. This is a Herculean task. 

That’s what “integration hell” means: the struggle to merge versions of the same application that have been allowed to diverge for too long. 

Enter the Solution: Continuous Integration

“If it hurts, do it more often.” What this saying means is that there are problems we postpone solving because doing so is hard. What you often find with these kinds of problems is that solving them more frequently, before they accumulate, is way less painful—or even trivial.

So, how can you make integrations less painful? Integrate more often.

That’s continuous integration (CI) in a nutshell: Have your developers integrate their work with a public shared repository, at the very least once a day. Have a server trigger a build and run the automated test suite every time someone integrates their work. That way, if there are problems, they’re exposed sooner rather than later.

How to Handle Partially Completed Features

One challenge that many teams struggle with in CI is how to deal with features that aren’t complete. If developers are merging their code to the mainline, that means that any developments that take more than one day to complete will have to be split into several parts. 

How can you avoid the customer accessing unfinished functionality? There are some trivial scenarios with similarly trivial solutions, but harder scenarios call for a different approach: the ability to switch off a part of the code completely.

Feature Flags to the Rescue

Defining Feature Flags

There are many names for the mechanisms that allow developers to switch a portion of their code off and on. Some call them “feature toggles” or “kill switches.” But “feature flags” is the most popular name, so that’s what we’ll use for the remainder of this post. So, what are feature flags?

Put simply, feature flags are techniques that allow teams to change the behavior of an application without modifying the code. In general, flags are used to prevent users from accessing and using the changes introduced by some piece of code, because they’re not adequate for production yet for a number of reasons.

Disable Code: What Are the Use Cases?

We’ll now cover some of the most common use cases for disabling code in production.

Switching Off Unfinished Features

As you’ve seen, one of the main use cases for feature flags is preventing users from accessing features that aren’t ready for use yet.

That way, programmers developing features that are more complex and take a longer time to complete aren’t prevented from integrating their work often and benefiting from it.

Enabling A/B Testing

The adoption of feature flags enables the use of several valuable practices in the software development process, one of which is A/B testing

A/B testing is a user experience research technique that consists of comparing two versions of a website or application to decide which one to keep. It entails randomly splitting users into two groups, A and B, and then delivering a different version of the application to each group. One group might receive the current production version, which we call the “control,” whereas the second group would receive the candidate for the new version, called the “treatment.” 

The testers then monitor the behavior of both groups and determine which of the versions achieved better results. 

Feature flags are a practical way to enable A/B testing because they allow you to quickly and conveniently change between the control and treatment versions of your application.

Enabling Canary Releases

If you deliver the new version of your app to your entire userbase at once, 100 percent of your users will be impacted if the release is bad in some way. What if you could gradually roll out the new version instead? You’d first deploy to a small subset of users, monitoring that group to detect issues. If something went wrong, you could roll it back. If everything looked fine, you could then gradually release the version for larger groups. That’s a canary release in a nutshell. It’s another powerful technique that feature flags might help with.

Customizing Features According to Users’ Preferences

It’s not uncommon to have to customize your application according to the needs of specific users, and there are several ways in which software teams can accomplish that—some more efficient, and others less so (companies that create separate branches or entire repositories for each client come to mind).

This is another area where feature flags could help, allowing teams to dynamically switch between different versions of the same functionality.

Disable Code in Production 101

How do you go about disabling code? That’s what we’re going to see now, in three increasingly sophisticated phases.

First Stage: The Most Basic Approach

We start with an approach that’s so primitive, it maybe shouldn’t be considered a feature flag at all. Consider the pseudocode below:

calculateAdditionalWorkHours(Employee employee, Date start, Date end) {
  // return calculateAdditionalWorkHoursSameOldWay(employee, start, end);
  return calculateAdditionalWorkHoursImproved(employee, start, end);
}

In the code above, we’re just commenting out the old version of some method and replacing it with a new version. When we want the older version to be used, we just do the opposite. (Well, I said it was primitive.) This approach lacks one of the most fundamental properties of a feature flag—the ability to change how the application behaves without changing its code.

However, it plants the seed for more sophisticated approaches.

Second Stage: Taking the Decision Out of the Code

The previous approach didn’t allow developers to select the desired version of the feature without changing the code. Fortunately, that’s not so hard to do. First, we introduce a logical variable to determine which version we’re going to use:

calculateAdditionalWorkHours(Employee employee, Date start, Date end) {

  var result = useNewCalculation
    ? calculateAdditionalWorkHoursImproved(employee, start, end)
    : calculateAdditionalWorkHoursSameOldWay(employee, start, end);

  return result;
}

Then, we use some mechanism to be able to assign the value to the variable from an external source. We could use a configuration file:

var useNewCalculation = config[newCalculation];

Passing arguments to the application might be another option. What matters is that we now have the ability to modify how the app behaves from the outside, which is a great step toward “true” feature flagging.

Keep in mind that the code examples you see are all pseudocode. Using your favorite programming language, there’s nothing stopping you from starting with this approach and taking it up a notch. You could, for instance, use classes to represent the features and design patterns (e.g., factories) to avoid if statements.

Stage 3: Full-Fledged Feature Flag Management

The previous approach might be enough when your application has only a small number of flags. But as that number grows, things start to become messy.

First, you have the issue of technical debt. Manually implemented feature flags can create terribly confusing conditional flows in your codebase. That only grows worse with new flags being introduced each day. Additionally, they might make the code harder to understand and navigate, especially for more junior developers, which is an invitation for bugs.

Another problem is that as the number of flags grows, it becomes more and more common to forget to delete old, obsolete ones.

The main problem of a homegrown approach is that it doesn’t give you an easy way to see and manage all of your flags at once. That’s why our third and final stage is a single piece of advice: Instead of rolling out your own feature flags approach, adopt a third-party feature flag management system.

Feature Flags Are a CI/CD Enabler

We’ve covered the mechanisms developers can use to disable portions of their codebase in production without having to touch the code. This capability is powerful and enables techniques such as A/B testing and canary releases, which are all hallmarks of a modern, agile-based software development process.

The names for the techniques might vary—feature flags, feature toggles, feature flipper, and so on. The way in which the techniques are implemented can also vary—from a humble if statement to sophisticated cloud-based solutions.

But no matter what you call them, you can’t overstate the benefit these mechanisms offer. They’re an enabler of Continuous Integration, which is essential for any modern software organization that wants to stay afloat.

The post How to Disable Code: The Developer’s Production Kill Switch appeared first on CSS-Tricks.



source https://css-tricks.com/how-to-disable-code-the-developers-production-kill-switch/

Hide Scrollbars During an Animation

CSS still can’t animate to auto dimensions.

.dropdown {
  transition: 0.2s;
  height: 0;
}
.dropdown.open {
  /* the height will change, but it won't animate. */
  height: auto;
}

There is JavaScript trickery you can try. Brandon Smith outlined several techniques here a little while back. My mind always goes to this solution just because it’s so simple:

.dropdown {
  transition: 0.2s;
  max-height: 0;
}
.dropdown.open {
  /* 🎉 */
  max-height: 400px;
}

Now we have this 400px magic number which is really not ideal. But the fact that this works and is so simple makes it extremely appealing that I use it production all the time.

But the magic number isn’t the only problem. Another problem is scrollbars.

When we set max-height: 0;, we also need overflow: hidden; to make sure the dropdown is actually hidden when it is closed. When the dropdown is open, we should probably be using overflow: auto; so that we don’t accidentally cut off content in case the natural height of the dropdown is taller than the max-height after it expands. The use of overflow: auto; solves that problem while introducing another: during the expansion, our dropdown will always have scrollbars for at least part of the expansion, even if the final expansion height doesn’t need them. That’s awkward!

CSS trickery to the rescue.

We can still use overflow: auto; on the expanded state — we’ll just override it during the animation. As we learned in the great CSS specificity battle, @keyframes have an amazing ability to override anything while they are active. Let’s use them not to animate the opening, but just for this scrollbar-hiding functionality:

.dropdown {
  max-height: 0;
  overflow: hidden;
  transition: max-height 1.2s ease-in-out;
}
.dropdown.open {
  overflow: auto;
  max-height: 400px;
  animation: hide-scroll 1.2s backwards;
  @keyframes hide-scroll {
    from, to { overflow: hidden; } 
  }
}

That does the trick!

Try adjusting the height to something less to see how you don’t see scrollbars during the animation but only at the end when they are needed. That causes a little bit of jerkiness when the scrollbar pops in, but that was acceptable in my case as it’s rare that it happens at all. If you absolutely wanted to stop the jerkiness, you’d probably apply a (custom) scrollbar at all times to the dropdown and perhaps adjust the styling of the scrollbar during the animation, if needed.


Credit here to Mr. Stephen Shaw of the fancy @keyframers for this trick. I yanked him in to help me figure it out while I was working on it for something on CodePen. We decided to turn the trick into a video for the CodePen channel showcasing Collab Mode, which we used to figure out the problem/solution:

The post Hide Scrollbars During an Animation appeared first on CSS-Tricks.



source https://css-tricks.com/hide-scrollbars-during-an-animation/