Archiwum kategorii: CSS

Going Offline

Post pobrano z: Going Offline

Jeremy Keith has written a new book all about service workers and offline functionality that releases at the end of the month. The first chapter is posted on A List Apart. Now that the latest versions of iOS and macOS Safari support service workers, I can’t think of a better time to learn about how progressive web apps work under the hood. In fact, here’s an example of a simple offline site and a short series on making web apps work offline.

News of Jeremy’s book had me going back through his previous book, Resilient Web Design, where I half-remembered this super interesting quote from Chapter 4:

If you build something using web technologies, and someone visits with a web browser, you can’t be sure how many of the web technologies will be supported. It probably won’t be 100%. But it’s also unlikely to be 0%. Some people will visit with iOS devices. Others will visit with Android devices. Some people will get 80% or 90% of what you’ve designed. Others will get just 20%, 30%, or 50%. The web isn’t a platform. It’s a continuum.

I love this idea of the web as a continuum that’s constantly improving and growing over time and so I’m sure Jeremy’s latest book will be just as fun and interesting.

Direct Link to ArticlePermalink

The post Going Offline appeared first on CSS-Tricks.

Displaying the Weather With Serverless and Colors

Post pobrano z: Displaying the Weather With Serverless and Colors

I like to jog. Sometimes it’s cold out. Sometimes it’s cold out, but it looks like it isn’t. The sun is shining, the birds are chirping. Then you step outside in shorts and a t-shirt and realize you have roughly 2 minutes before exposure sets in.

I decided to solve this first world problem using a lightbulb to display a certain color based on what the temperature outside is. It works better than I expected, and that’s saying something because usually nothing works out like I want it to.

This was a fun project to build, and since it is essentially a hosted service running on a timer, it’s a perfect use case for Serverless.

Now you might be thinking, “um, wouldn’t it be easier to just check the weather?” Well, it would, but then I wouldn’t have an excuse to buy an expensive lightbulb or write an article with the word “Serverless.”

So let’s look at how you can build your own Weather Bulb. The final code is not complicated, but it does have some interesting pieces that are worth noting. By the way, did I mention that it’s Serverless?

Building the Weather Bulb

The first thing you are going to need is the bulb. You can’t have a Weather Bulb sans bulb. Say the word “bulb” out loud about 10 times and you’ll notice what a bizarre word it is. Bulb, bulb, bulb, bulb — see? Weird.

I am using the LIFX Mini Color. It’s not *too* expensive, but more importantly, it’s got an API that is wide open.

The API has two methods of authentication. The first contains the word “OAuth” and I’m already sorry that you had to read that. Don’t worry, there is an easier way that doesn’t involve OAu…. that which won’t be named.

The second way is to register an application with LIFX. You get back a key and all you have to do is pass that key with any HTTP request. That’s what I’m using for this demo.

For instance, if we wanted to change the bulb color to blue, we can just pass color: blue to the /state endpoint.

The API supports a few different color formats, including named colors (like red, blue), hex values, RBG, Kevlin, hue brightness and saturation. This is important because it factors into what proved to be the hardest part of this project: turning temperature into color.

Representing Temperature With Color

If you’ve ever watched a weather report, you’ll be familiar with the way that meteorology represents weather conditions with color on a map.

Usually, this is done to visualize precipitation. You have probably seen that ominous green strip of storms bearing down on you on a weather map while you try to figure out if you should get in the bathtub because you’re in the path of a tornado. Or maybe that’s just all of us unlucky souls here in America’s Tornado Alley.

Color is also used to represent temperature. This is precisely what I wanted to do with the bulb. The tough thing is that there doesn’t seem to be a standardized way to do this. Some maps show it as solid colors in bands. In this case, blue might represent the band from 0℉ – 32℉.

Others have it as a gradient scale which is more precise. This is what I was after for the Weather Bulb.

My first stab at solving this was just to Google “temperature color scale” and other various iterations of that search term. I got back a lot of information about Kelvin.

Kelvin is a representation of the temperature of a color. Literally. For any light source (light bulb, the sun, ect) the actual temperature of that source will affect the color of the light it emits. A fire burns a yellowish red color. The hotter that fire gets, the more it moves towards white. Hence the saying, “white hot”. So if someone ever says “red hot,” you can correct them in front of everyone because who doesn’t love a pedantic jerk?

The LIFX bulb supports Kelvin, so you might think that this would work. After all, this is the Kelvin scale….

The problem is that there is simply not enough color variation because these are not actual colors, but rather the tinge of color that a light is emitting based on it’s “temperature.” Here is the Kelvin color wheel that comes with the LIFX app.

These colors are barely distinguishable from one another on the bulb. Not exactly what I was after.

That leaves me with trying to convert the color to either Hex, RGB or some other format. This is tough because where do you begin? I spent an embarrassing amount of time adjust RGB scale values between blue for cold (0, 0, 255) and red for hot (255, 0, 0). It was about this time that it dawned on me that maybe HSL would be a better way to go here. Why? Because hue is a whole lot easier to understand.

Hue

Hue is a representation of color on a scale between 0 and 360. This is why we often see color represented on a wheel (360°). That’s a vast oversimplification, but unless you want me to start talking about wavelengths, let’s go with that definition.

The hue color wheel looks like this….

If we flatten it out, it’s easier to reason about.

We’re ready to convert temperature to color. The first thing we need to do is figure out a set temperature range. I went with 0℉ to 100℉. We can’t work with infinite temperature color combinations. Numbers go on forever, colors do not. It can only get so hot before our bulb is just bright red all the time, and that’s 100℉. The same is true for cold.

If light blue represents 0℉, I can start at about the 200 mark on the hue scale. Red will represent 100℉. You can see that red is at both extremes, so I can move either left OR right, depending on what colors I want to use to represent the temperature. It’s not the same as the colors they use in actual weather programs, but who cares? Obviously not me.

I chose to go right because there is no pink on the left and pink is my favorite color. I also felt like pink represents warm a bit better than green. Green is rain and tornadoes.

Now we can back into a hue based on temperature. Ready? Here we go.

Let’s pretend it’s a brisk 50℉ outside.

If 100℉ is the hottest we go (360) and 0℉ is the coldest (200), then we have a color scale of 160 points. To figure out where in that 160 point range we need to be, we can divide the current temperature by the upper bound of 100℉ which will give us the exact percentage we need to move in our range, or 50%. If we move 50% of the way into a 160 point range, that leaves us at 80. Since we are starting at 200, that gives us a hue of 280.

That sounds complicated, but only because word problems in math SUCK. Here’s how the code looks when it’s all said and done…

let hue = 200 + (160 * ( temperature / 100 ));

OK! We’ve got a dynamic color scale based on hue, and wouldn’t you know it, we can just pass the hue to LIFX as simply as we pass a named color.

Now we just need to find out what the current temperature is, back into a hue and do that every few minutes. Serverless, here we come!

Serverless Timer Functions

Serverless is all the rage. It’s like HTML5 used to be: it doesn’t matter what it is, it only matters that you know the word and are not afraid to use it in a blog post.

For this example, we’ll use Azure Functions because there is support for timer triggers, and we can test those timer triggers locally before we deploy using VS Code. One of the things about Serverless that irritates me to no end is when I can’t debug it locally.

Using the Azure Functions Core Tools and the Azure Functions Extension for VS Code, I can create a new Serverless project and select a Timer Trigger.

Timer Triggers in Azure Functions are specified as Cron Expressions. Don’t worry, I didn’t know what that was either.

Cron Expressions allow you to get very specific with interval definition. Cron breaks things down into second, minute, hour, day, month, year. So if you wanted to run something every second of every minute of every hour of every day of every year, your expression would look like this…

* * * * * *

If you wanted to run it every day at 10:15, it would look like this…

* 15 10 * * *

If you wanted to run it every 5 minutes (which is what Azure defaults to), you specify that by saying “when minutes is divisible by 5.”

0 */5 * * * *

For the purposes of this function, we set it to 2 minutes.

I am using a 2 minute interval because that’s how often we can call the weather API for free 💰.

Getting the Forecast From DarkSky

DarkSky has a wonderful weather API that you can call up to 1,000 times per day for free. If there are 1,440 minutes in a day (and there are), that means we can call DarkSky every 1.44 minutes per day and stay in the free zone. I just rounded up to 2 minutes because temperature doesn’t change that fast.

This is what our function looks like when we call the DarkSky API. All of my tokens, keys, latitude and longitude settings are in environment variables so they aren’t hardcoded. Those are set in the local.settings.json file. I used axios for my HTTP requests because it is a magical, magical package.

const axios = require('axios');

module.exports = function (context, myTimer) {
  // build up the DarkSky endpoint
  let endpoint = `${process.env.DS_API}/${process.env.DS_SECRET}/${process.env.LAT}, 
                  ${process.env.LNG}`;
  
  // use axios to call DarkSky for weather
  axios
    .get(endpoint)
    .then(response => {
      let temp = Math.round(response.data.currently.temperature);
    
      // TODO: Set the color of the LIFX bulb
    })
    .catch(err => {
      context.log(err.message);
    });
};

Now that I have the temperature, I need to call the LIFX API. And wouldn’t you know it, someone has already created an npm package to do this called lifx-http-api. This is why you love JavaScript.

Setting the Bulb Hue

After the weather result comes back, I need to use the LIFX API instance and call the setState method. This method returns a promise which means that we need to nest promises. Nesting promises can get out of hand and could land us right back in callback hell, which is what we’re trying to avoid with promises in the first place.

Instead, we’ll handle the first promise and then return Promise.all which we can handle at another top-level then. This just prevents us from nesting then statements.

Remember kids, promises are just socially acceptable callbacks.

const axios = require('axios');
const LIFX = require('lifx-http-api');

let client = new LIFX({
  bearerToken: process.env.LIFX_TOKEN
});

module.exports = function (context, myTimer) {
  // build up the DarkSky endpoint
  let endpoint = <code>${process.env.DS_API}/${process.env.DS_SECRET}/${
    process.env.LAT
    },${process.env.LNG}<code>;
    
  // use axios to call DarkSky for weather
  axios
    .get(endpoint)
    .then(response => {
      let temp = Math.round(response.data.currently.temperature);
      
      // make sure the temp isn't above 100 because that's as high as we can go
      temp = temp < 100 ? temp : 100;
      
      // determine the hue
      let hue = 200 + (160 * (temp / 100));

      // return Promise.all so we can resolve at the top level
      return Promise.all([
        data,
        client.setState('all', { color: <code>hue:${hue}<code> })
      ]);
    })
    .then(result => {
      // result[0] contains the darksky result
      // result[1] contains the LIFX result
      context.log(result[1]);
    })
    .catch(err => {
      context.log(err.message);
    });
};

Now we can run this thing locally and watch our timer do it’s thang.

That’s it! Let’s deploy it.

Deploying Weather Bulb

I can create a new Functions project from the VS Code extension.

I can right-click that to “Open in portal” where I can define a deployment source so it sucks my code in from Github and deploys it. This is ideal because now whenever I push a change to Github, my application automatically gets redeployed.

All Hail the Weather Bulb

Now just sit back and behold the soft glow of the Weather Bulb! Why look at the actual temperature when you can look at this beautiful shade of hot pink instead?

Can you guess what the temperature is based on what you know from this article? The person who leaves a comment and gets the closest will get a free LIFX lightbulb from me (because I ❤️ all of you), or the cost of the bulb if you are outside the U.S. (~$40).

You can grab all of the code for this project from Github.

The post Displaying the Weather With Serverless and Colors appeared first on CSS-Tricks.

Why would you do that in CSS?

Post pobrano z: Why would you do that in CSS?

And by that, it’s usually some kind of CSS experiment, often an elaborate drawing or interaction.

For example, have you seen Lynn Fisher’s extraordinary A Single Div project? Not only are all these graphics drawn in just HTML and CSS, they are all created with (you guessed it) a single <div></div>.

Why would she do that? Here’s one pertinent possibility: it’s none of our business. We’re free to wonder, or even ask if it’s done respectfully enough. But does it really matter? Let’s stop short of assuming she doesn’t know what’s she’s doing, assuming it’s a twisted form of pain, or that she’s unaware of other technologies. Check out the example where she drew the official SVG logo with CSS and a single div. Woke.

A screenshot of the official SVG logo recreated using a single element in CSS on a yellow background.

I even kinda get it. I wrote a whole book about SVG because I think it’s underused. Are there „CSS drawings” that I think would be better as SVG for a production site meant to last? Sure.

How about this one?

See the Pen Pure CSS Biker by Julia Muzafarova (@miocene) on CodePen.

Jeepers creepers that’s something else. I would have guessed GreenSock was behind this at a quick glance. Speaking of, GreenSock has advocated right here on CSS-Tricks some techniques for smart animations. Part of that is breaking animations into parts and stitching them together into larger timelines for maintenance ease and „without getting bogged down by the process.”

So, did Julia Muzafarova do it wrong? Of course not. If there is a wrong way to animate a cartoon hipster on a bike in this world, I don’t wanna live here anymore. It’s 2,100 lines of meticulous positioning, coloring, and animating. Heck, it’ll work in some email clients if you really need to latch onto something „practical.”

Sasha Tran, a UI developer at Apple, shared her story of creating drawings in CSS last year. She drew something new everyday for 20 days during Codevember.

Even if I am not talented in hand illustrations, there is a way to express myself through other mediums. I found that medium to be in HTML and CSS. To level up and get to a point where I could create cute artwork, I focused on two things: the basics, and consistency. Working with basic CSS shapes like rectangles and basic properties like border-radius overtime gave me the muscle memory to progress into more intricate illustrations.

Significantly leveled up in a month and developed better CSS muscle memory. Huh. Speaking of shapes, there are plenty of ways to get tricky with those in CSS!

You could argue that pushing boundaries toward the impractical is what hones our skills for all that other work we have to do.

See the Pen CSS3 Thermostat by Daniel Stancu (@birkof) on CodePen.

You could argue that forcing yourself into restrictions is fuel for creativity.

See the Pen Pixel Hellboy by Servin (@servinnissen) on CodePen.

You could argue that stretching your brain creatively in these forced conditions helps build your confidence and widens your toolbox.

See the Pen Simple CSS Anchor by Joni Trythall (@jonitrythall) on CodePen.

You could argue that it’s just kinda fun.

See the Pen CSS Cheese (or sponge) by Hugo Giraudel (@HugoGiraudel) on CodePen.

The post Why would you do that in CSS? appeared first on CSS-Tricks.

Animated SVG Radial Progress Bars

Post pobrano z: Animated SVG Radial Progress Bars

Dave Rupert shows us all how to animate radial progress bars in SVG with a tiny script alongside the stroke-dasharray and stroke-dashoffset properties:

For a client project we tasked ourselves with building out one of those cool radial progress bars. In the past, we’ve used entire Canvas-based charting libraries (156k/44k gzip), but that seemed like overkill. I looked at Airbnb’s Lottie project where you export After Effects animations as JSON. This is cool for complex animations, but the dependencies seemed heavy (248k/56k gzip) for one micro-animation.

Per the usual, I tried my hand at a minimal custom SVG with CSS animation and a small bit of JavaScript (~223b gzip). I’m pleased with the results.

Here’s another example Jeremias Menichelli posted here on CSS-Tricks with the added twist of making them components in React and Vue.

Direct Link to ArticlePermalink

The post Animated SVG Radial Progress Bars appeared first on CSS-Tricks.

Scooped Corners in 2018

Post pobrano z: Scooped Corners in 2018

When I saw Chris’ article on notched boxes, I remembered that I got a challenge a while ago to CSS a design like the one below in a cross-browser manner:

The design shows a header box and a 2x2 grid of boxes below, all middle aligned horizontally. There's a line extending from the bottom middle of the header, going in between the two boxes on the row right underneath the header and then growing into a circle whose central point is at equal distance from all four boxes on the 2x2 grid. To accommodate for this pretty big circle, all these boxes have a scooped corner (that's the bottom right corner for the top left box, the bottom left corner for the top right box, the top right corner for the bottom left box and the top left corner for the bottom right box).
What the challenge looked like.

It looks pretty similar to the concept of notched boxes, except the corners are now scooped and we only have to worry about one corner per box. So let’s see how we can do it, how we can expand the technique to multiple corners, what issues we run into and how we can get around them with or without making browser support compromises.

The initial idea: box-shadow!

We start with a box element:

<div class='box'></div>

We can give this some dimensions or let its dimensions be decided by the content—it doesn’t really matter. For simplicity, we’re just setting a max-width and a min-height on it. We’re also giving it an outline so we can see its boundaries.

.box {
  outline: solid 2px;
  max-width: 15em;
  min-height: 10em;
}

Next, we absolutely position a square ::before pseudo-element whose edge length is equal to the diameter (or twice the radius $r) of the scoop in the corner. We also give this pseudo-element a reddish box-shadow and a dummy background (that we’ll remove later) just so that we can see it better:

$r: 2em;

.box {
  position: relative;
  /* same styles as before */
  
  &:before {
    position: absolute;
    padding: $r;
    box-shadow: 0 0 7px #b53;
    background: #95a;
    content: ''
  }
}

And this is what we have so far:

See the Pen by thebabydino (@thebabydino) on CodePen.

Well, it doesn’t look too exciting… yet! So let’s move on and make this square a disc by setting border-radius: 50% on it and give it a negative margin equal to its radius $r, so that its central point coincides with the (0,0) point (top left corner) of its parent box. We also set overflow: hidden on the parent box, so that whatever of this pseudo-element is outside the .box gets cut out.

$r: 2em;

.box {
  overflow: hidden;
  /* same styles as before */
  
  &:before {
    /* same styles as before */
    margin: -$r;
    border-radius: 50%
  }
}

Now we’re starting to see the shape we’ve been aiming for:

See the Pen by thebabydino (@thebabydino) on CodePen.

But it’s still not quite what we want. In order to get there, we use the fourth length value for the box-shadow property: the spread radius. If you need a refresher on how box-shadow works with these four values, you can check out the interactive demo below:

See the Pen by thebabydino (@thebabydino) on CodePen.

You may have already guessed what we do next. We remove the dummy background, we zero the first three box-shadow values (the x and y offsets and the blur radius) and use a pretty big number for the last one (the spread radius):

box-shadow: 0 0 0 300px;

The interactive demo below shows how increasing the spread radius makes it cover up more and more of its parent .box:

See the Pen by thebabydino (@thebabydino) on CodePen.

So, the trick here is having a spread radius sufficiently large so that it covers the rest of the parent element. The cool thing about this is that we can make the box-shadow semi-transparent or have rounded corners on the parent .box:

.box {
  /* same styles as before */
  border-radius: 1em;
  
  &:before {
    /* same styles as before */
    box-shadow: 0 0 0 300px rgba(#95a, .75);
  }
}

See the Pen by thebabydino (@thebabydino) on CodePen.

Of course, just like Chris pointed out in the article on notched boxes, we can make the scoop radius a CSS variable and then easily modify that from the JavaScript. Then everything updates nicely, even with text content in our box:

:root { --r: 50px } 

.box {
  /* same styles as before */
  padding: var(--r);

  &:before {
    /* same styles as before */
    margin: calc(-1*var(--r));
    padding: inherit;
}

Note that when we also have text content, we need to set a negative z-index on the ::before pseudo-element and explicitly position it in the corner as we now also have a padding on the .box to compensate for the scoop.

.box {
  /* same styles as before */

  &:before {
    /* same styles as before */
    z-index: -1;
    top: 0;
    left: 0
}

See the Pen by thebabydino (@thebabydino) on CodePen.

Applying this technique

Now, let’s move further and see how we can apply this concept in order to reproduce the design I showed at the beginning. In this particular case, the central points of the pseudo-element discs don’t coincide with box corners, but are outside, in the middle of the space in between boxes.

The structure used is pretty straightforward, just a <header> element followed by four <article> elements I’ve generated in a Pug loop:

while n--
  article
    h3 #{data[n].name}
    section
      p #{data[n].quote}
      a(href='#') go

We use a wrapping flexbox layout on the <body> with the <header> really wide and with one or two <article> elements on each row, depending on how wide the viewport is.

Landscape (left) vs. portrait (right) mode.

If we have a single <article> on each row, we don’t have scooped corners, so their radius is 0px. Otherwise, we give this radius --r a non-zero value.

$min-w: 15rem; /* min width of an article element */
$m: 1rem; /* margin of such an element */

html { --r: 0px; }

article {
  margin: $m;
  min-width: $min-w;
  width: 21em;
}

@media (min-width: 2*($min-w + 2*$m) /* enough for 2 per row */) {
  html { --r: 4rem; }
  
  article { width: 40%; }
}

Let’s now consider just the situation when we have two <article> elements per row (and of course a scooped corner for each because that’s what’s of interest to us).

In the case of the first one, we start with the leftmost limit of the disc along the right edge of its parent. That’s left: 100% so far. To move the x coordinate of the disc’s central point on the right edge of its parent, we subtract the disc’s radius, which brings us to left: calc(100% - var(--r)). But we don’t want it on the right edge, we want it offset to the right by the <article> margin $m, which brings us to the final value:

left: calc(100% - var(--r) + #{$m});

See the Pen by thebabydino (@thebabydino) on CodePen.

Along the y axis, we start with the topmost limit of the disc along the bottom edge of its parent—that’s top: 100%. To put the disc’s central point on the bottom edge of the parent box, we move it up by one radius, which gives us top: calc(100% - var(--r)). Finally, we want this central point to be $m below the parent’s bottom edge, which gives us the final vertical offset of:

top: calc(100% - var(--r) + #{$m});

See the Pen by thebabydino (@thebabydino) on CodePen.

For the second <article> (second on the same row), we have the same value in the case of the vertical offset.

See the Pen by thebabydino (@thebabydino) on CodePen.

Horizontally however, we start with the disc’s left limit being along its parent’s left edge—that’s left: 0%. To put the disc’s central point on its parent’s left edge, we move it left by a radius --r, thus getting left: calc(0% - var(--r)). However, the final position is $m to the left of the parent’s left edge:

left: calc(0% - var(--r) - #{$m});

See the Pen by thebabydino (@thebabydino) on CodePen.

For the third <article> (first on the last row), we have the same value for the offset along the x axis as in the case of the first one.

See the Pen by thebabydino (@thebabydino) on CodePen.

Vertically, we start with the disc’s top limit along the top edge of its parent—that’s top: 0%. To put the disc’s central point on the parent’s top edge, we move it up by a radius --r, thus getting top: calc(0% - var(--r)). But we want to have it $m above the parent’s top edge, so the final top offset is:

top: calc(0% - var(--r) - #{$m});

See the Pen by thebabydino (@thebabydino) on CodePen.

For the final one (second on the last row), we have the same horizontal offset as in the case of the one above it and the same vertical offset as for the one to its left on the same row.

See the Pen by thebabydino (@thebabydino) on CodePen.

So, our offsets can be written:

article:nth-of-type(1) { /* 1st */
 left: calc(100%/* 2*50% = (1 + 1)*50% = (1 + i)*50% */ - var(--r) + /* i=+1 */#{$m});
 top:  calc(100%/* 2*50% = (1 + 1)*50% = (1 + j)*50% */ - var(--r) + /* j=+1 */#{$m});
}

article:nth-of-type(2) { /* 2nd */
 left: calc(  0%/* 0*50% = (1 - 1)*50% = (1 + i)*50% */ - var(--r) - /* i=-1 */#{$m});
 top:  calc(100%/* 2*50% = (1 + 1)*50% = (1 + j)*50% */ - var(--r) + /* j=+1 */#{$m});
}

article:nth-of-type(3) { /* 3rd */
 left: calc(100%/* 2*50% = (1 + 1)*50% = (1 + i)*50% */ - var(--r) + /* i=+1 */#{$m});
 top:  calc(  0%/* 0*50% = (1 - 1)*50% = (1 + j)*50% */ - var(--r) - /* j=-1 */#{$m});
}

article:nth-of-type(4) { /* 4th */
 left: calc(  0%/* 0*50% = (1 - 1)*50% = (1 + i)*50% */ - var(--r) - /* i=-1 */#{$m});
 top:  calc(  0%/* 0*50% = (1 - 1)*50% = (1 + j)*50% */ - var(--r) - /* j=-1 */#{$m});
}

This means the positions of the central points of the discs depend on the gap in between our <article> elements (this gap is twice the margin: $m we set on them), on the disc radius r and on a couple of horizontal and vertical multipliers (--i and --j respectively). Both these multipliers are initially -1.

For the first two <article> elements (on the first row of the 2x2 grid), we change the vertical multiplier --j to 1 because we want the y coordinate of the discs’ central points to be below the bottom edge, while for the odd ones (on the first column), we change the horizontal multiplier --i to 1 because we want the x coordinate to be to the right of the right edge.

html { --i: -1; --j: -1 } /* multipliers initially set to -1 */

h3, section {
  &:before {
    /* set generic offsets */
    top:  calc((1 + var(--j))*50% - var(--r) + var(--j)*#{$m});
    left: calc((1 + var(--i))*50% - var(--r) + var(--i)*#{$m});
  }
}

@media (min-width: 2*($min-w + 2*$m)) {
  article {
    /* change vertical multiplier for first two (on 1st row of 2x2 grid) */
    &:nth-of-type(-n + 2) { --j: 1 }

    /* change horizontal multiplier for odd ones (on 1st column) */
    &:nth-of-type(odd) { --i: 1 }
}

Note that we only have visible disc cutouts on the <section> element for the first two <article> elements and only on the <h3> for the last two. So for the first two <article> elements, the radius --r on the heading’s ::before pseudo-element is 0, while for the last two, this radius is 0 for the section’s ::before pseudo:

@media (min-width: 2*($min-w + 2*$m)) {
  article {
    &:nth-of-type(-n + 2) h3, 
    &:nth-of-type(n + 3) section { &:before { --r: 0 ; } }
  }
}

In a similar manner, we add differentiated paddings to the children of the <article> elements:

$p: .5rem;

h3, section { padding: $p; }

@media (min-width: 2*($min-w + 2*$m)) {
  article {
    &:nth-of-type(-n + 2) section, 
    &:nth-of-type(n + 3) h3 {
      padding-right: calc(.5*(1 + var(--i))*(var(--r) - #{$m}) + #{$p});
      padding-left: calc(.5*(1 - var(--i))*(var(--r) - #{$m}) + #{$p});
    }
  }
}

This helps us get the result we’re looking for:

See the Pen by thebabydino (@thebabydino) on CodePen.

The above demo works in current versions of all major browsers and, if we can do with some repetition instead of using CSS variables, we can extend support all the way back to IE9.

Potential issues with the above method

While this was a quick and easy cross-browser way to get the desired result in this particular case, we may not always be so lucky with this approach.

First off, we need a pseudo-element for each scooped corner, so if we want this effect for all corners, we need to bring in an extra element. Sad panda.

Secondly, we may not always want a solid background. We may want a semi-transparent one (which becomes a pain to get if we want to have more than one scooped corner), a gradient one (while we can emulate some radial gradients with box-shadow, it’s a less than ideal solution) or even an image background (hardly doable with the only solution being to use mix-blend-mode which cuts out Edge support without an elegant fallback).

And how about really large boxes for which the spread we’ve set is not enough? Ugh.

So, let’s explore other, more reliable approaches with various degrees of browser support.

Flexibility and good browser support? SVG it!

This is probably no surprise, but the full SVG solution fares best if we want something flexible and reliably cross-browser today. It’s a solution that involves using an SVG element before the content of our box. This SVG contains a <circle> on which we’ve set a radius r attribute.

<div class='box'>
  <svg>
    <circle r='50'/>
  </svg>
  TEXT CONTENT OF BOX GOES HERE
</div>

We absolutely position this SVG within the box and size it such that it fully covers its parent:

.box { position: relative; }

svg {
  position: absolute;
  width: 100%;
  height: 100%;
}

Nothing too interesting so far, so let’s give the <circle> an id and clone it in the other corners:

<circle id='c' r='50'/> 
<use xlink:href='#c' x='100%'/> 
<use xlink:href='#c' y='100%'/> 
<use xlink:href='#c' x='100%' y='100%'/> 

Note that if we want to exclude one corner or more, we just don’t clone it there.

See the Pen by thebabydino (@thebabydino) on CodePen.

Alright, but what we’ve done here is create circles in the corners and what we actually want is… the exact opposite! What we do next is put these circles within a <mask>, on top of a white, full-size (covering the whole SVG) rectangle and then we use this mask on another full size rectangle:

<mask id='m' fill='#fff'>
  <rect id='r' width='100%' height='100%'/>
  <circle id='c' r='50' fill='#000'/>
  <use xlink:href='#c' x='100%'/>
  <use xlink:href='#c' y='100%'/>
  <use xlink:href='#c' x='100%' y='100%'/>
</mask>
<use xlink:href='#r' fill='#f90' mask='url(#m)'/>

The result can be seen below:

See the Pen by thebabydino (@thebabydino) on CodePen.

If we have text, we need to adapt the box padding to our corner radius, setting the it to the same value as we’ve set the radius of the SVG circle, using JavaScript to keep them in sync:

See the Pen by thebabydino (@thebabydino) on CodePen.

Of course, the fill of our background rectangle doesn’t need to be a solid one. It may well be semi-transparent (as it is in the demo above), or we can use an SVG gradient or pattern for it. The latter would also allow us to use one or more background images.

See the Pen by thebabydino (@thebabydino) on CodePen.

But I came here for CSS candy!

Well, glad you asked! There are a number of things we can do here to shift the weight of the masking method from SVG to CSS.

Sadly, none of these is cross-browser, but they simplify things and they’re definitely something to keep a watch for in the near or more distant future.

Use CSS masking on HTML elements instead

What we do here is remove everything outside the mask from the SVG. Then, from the CSS, we set a background (which can be semi-transparent, a CSS gradient, an image, a combination of multiple backgrounds… anything that CSS has to offer) and the mask property on the .box element:

.box {
  /* any kind of background we wish */
  mask: url(#m);
}

Note that setting an inline SVG mask on an HTML element only works in Firefox for now!

Animated gif. Dragging a slider changes both the r attribute of the circle inside the SVG mask and the padding around the text content inside the box.
Version using CSS masking directly on our .box (live demo, Firefox only).

Set the circle radius from the CSS

This means removing the r attribute from our <circle> and setting it in the CSS to the same variable as the box padding:

.box { padding: var(--r); }

[id='c'] { r: var(--r); }

This way, when we change the value of --r, both the scoop radius and the padding around the .box content get updated!

Note that setting geometry properties for SVG elements from the CSS only works in Blink browsers for now!

Screenshot. Shows the corners being scooped out in the version setting the radius of the scoop circle as a CSS variable from the CSS.
Version using a CSS variable for the <circle> radius (live demo, Blink only).

Combine the previous two methods

While this would be cool, it’s sadly not possible in practice in any browser at the moment. But the good news is we can do even better than that!

Use CSS gradients for masking

Note that CSS masking on HTML elements doesn’t work at all in Edge at this point, though it’s listed as „In Development” and a flag for it (that doesn’t do anything for now) has already shown up in about:flags.

We ditch the SVG part completely and start building our CSS gradient mask. We create the circles at the corners using radial gradients. The following CSS creates a circle of radius --r in the top left corner of a box:

.box {
  background: radial-gradient(circle at 0 0, #000 var(--r, 50px), transparent 0);
}

It can be seen live in the demo below, where we’ve also given the box a red outline just so that we can see its boundaries:

See the Pen by thebabydino (@thebabydino) on CodePen.

We use the exact same gradient for our mask:

.box {
  /* same as before */
  /* any CSS background we wish */
  mask: radial-gradient(circle at 0 0, #000 var(--r, 50px), transparent 0);
}

Note that WebKit browsers still need the -webkit- prefix for the mask properties.

We then add the circles at the other corners:

$grad-list: radial-gradient(circle at   0    0 , #000 var(--r, 50px), transparent 0), 
            radial-gradient(circle at 100%   0 , #000 var(--r, 50px), transparent 0), 
            radial-gradient(circle at   0  100%, #000 var(--r, 50px), transparent 0), 
            radial-gradient(circle at 100% 100%, #000 var(--r, 50px), transparent 0);
.box {
  /* same as before */
  /* any CSS background we wish */
  mask: $grad-list
}

That’s insanely repetitive, either a lot of writing or a lot of copy-pasting, so let’s see what we can do about that.

First off, we use a CSS variable for the stop list. This eliminates repetition in the generated CSS.

$grad-list: radial-gradient(circle at   0    0 , var(--stop-list)), 
            radial-gradient(circle at 100%   0 , var(--stop-list)), 
            radial-gradient(circle at   0  100%, var(--stop-list)), 
            radial-gradient(circle at 100% 100%, var(--stop-list));

.box {
  /* same as before */
  /* any CSS background we wish */
  --stop-list: #000 var(--r, 50px), transparent 0;
  mask: $grad-list;
}

But it’s still not much better, so let’s generate the corners within a loop:

$grad-list: ();

@for $i from 0 to 4 {
  $grad-list: $grad-list, 
    radial-gradient(circle at ($i%2)*100% floor($i/2)*100%, var(--stop-list));
}

.box {
  /* same as before */
  /* any CSS background we wish */
  --stop-list: #000 var(--r, 50px), transparent 0;
  mask: $grad-list;
}

Much better as far as the code goes because now we don’t have to write anything multiple times and run the risk of not updating everywhere later. But the result so far isn’t what we were going for:

Screenshot. Shows how the code above masks out everything but the quarter circles in the corners (the opposite of what we want).
Result of the code above (live demo, no Edge support for now).

Here, we’re cutting out everything but the corners, which is the opposite of what we want.

One thing we can do is reverse the gradients, make the corner circles transparent and the rest black with:

--stop-list: transparent var(--r, 50px), #000 0;

This does the trick when we use just one gradient for just one corner:

Screenshot. Shows the result when we have an abrupt change from transparent to black in a masking radial gradient at a corner: a quarter circle gets masked out at that corner.
Result when using just one gradient (live demo, no Edge support for now).

However, when we stack up all four of them (or just even two), we get a black rectangle the size of our box for the mask, which means nothing actually gets masked out anymore.

Animated gif. When the mask's gradient list is empty, no masking happens. When we add full size radial gradient layer with a transparent quarter circle in the top left corner, this masks out the area of that transparent quarter circle as these masks are alpha masks, giving each pixel of the element the mask is applied to the alpha of the corresponding mask pixel at that position. When we add another such gradient with a transparent quarter circle at another corner, this covers the transparent corner of the first layer and we can see the non-transparent corner of the first layer through its own transparent corner. So now the resulting masks has no more trnsparent pixels and nothing gets masked out anymore.
Layering mask gradients (live demo, no Edge support for now).

So, we restrict each of these gradients to a quarter of our box – 50% of the width and 50% of the height, thus getting 25% (a quarter) of the area for each:

Illustration. Shows the full mask area being divided into 4 quarters, each being 50% of the width and 50% of the height. The first is in the top left corner, the second in the top right corner, the third in the bootom left corner and th fourth in the bottom right corner.
Our mask, split into four quarters (live).

This means we also need to set a mask-size of 50% 50%, a mask-repeat of no-repeat, and position each mask-image into the desired corner:

$grad-list: ();

@for $i from 0 to 4 {
  $x: ($i%2)*100%;
  $y: floor($i/2)*100%;
  $grad-list: $grad-list 
              radial-gradient(circle at $x $y, var(--stop-list)) /* mask image */
              $x $y; /* mask position */
}

.box {
  /* same as before */
  /* any CSS background we wish */
  --stop-list: transparent var(--r, 50px), #000 0;
  mask: $grad-list;
  mask-size: 50% 50%;
  mask-repeat: no-repeat;
}

Note that WebKit browsers still need the -webkit- prefix for mask properties.

But the big problem here is… the problem with division and rounding in general—our four quarters put together don’t always manage to make up a whole again, so we end up with gaps in between them.

Annotated screenshot. Shows and highlights the gaps in between the four quarters.
Sadly, we may get gaps in between the four quarters (live demo).

Oh well, it’s not like we can’t cover up those gaps with thin linear-gradient() strips or increase the mask-size to let’s say 51%:

Screenshot showing we don't have gaps in between the four quarters anymore after increasing their mask-size by 1%.
Increasing the mask-size for each gradient layer fixes the problem of gaps (live demo).

But isn’t there a more elegant way?

Well, there’s a mask-composite property that can help us if we set it to intersect when reverting back to the full size gradient layers.

$grad-list: ();

@for $i from 0 to 4 {
  $grad-list: $grad-list, 
              radial-gradient(circle at ($i%2)*100% floor($i/2)*100%, var(--stop-list));
}

.box {
  /* same as before */
  /* any CSS background we wish */
  --stop-list: transparent var(--r, 50px), #000 0;
  mask: $grad-list;
  mask-composite: exclude;
}

This is extremely cool because it’s a pure CSS, no SVG solution, but the not-so-good news is that support is limited to Firefox 53+ here.

Screenshot. Shows that when using mask-composite: intersect, the parts that don't belong to the intersection of all the layers (are not common) gat masked out. That means the quarter circles at the four corners in our case.
Result using mask-composite: intersect (live demo).

However, it’s still better than support for the final option we have when it comes to scooped corners.

The corner-shape option

Lea Verou came up with this idea some five years ago and even created a preview page for it. Sadly, not only is it not implemented by any browser yet, but the spec hasn’t advanced much in the meanwhile. It’s still something to keep in mind for the future, as it offers a lot of flexibility with very little code – recreating our effect would only require the following:

padding: var(--r);
corner-shape: scoop;
border-radius: var(--r);

No markup vomit, no long gradient lists, just this very simple piece of CSS. That is… when it finally gets supported by browsers!

The post Scooped Corners in 2018 appeared first on CSS-Tricks.

Ruby Sass to be put to pasture on March 26, 2019

Post pobrano z: Ruby Sass to be put to pasture on March 26, 2019

There have long been multiple implementations of Sass. Most notably, the canonical Ruby version, now at 3.5.6. Then there is LibSass, the C++ version, which is at version 3.4 and…

Current LibSass 3.4 should be compatible with Sass 3.4.

LibSass is notable because it powers the majority of Sass ports. Over 30 of them, apparently, including the most popular one: node-sass, which provides Sass for the bajillion projects out there that wanna run an npm-y JavaScript-based dev environment and avoid the Ruby dependency.

It’s a little unfortunate LibSass isn’t up-to-date with current canonical Sass, but I think it’s on freeze as it’s been stated that LibSass will never be canonical Sass. Update: it’s not on freeze. It was actually Ruby Sass that was once on freeze with the intention of allowing LibSass to catch up. As I write, LibSass is at 3.5.2, so it’s close.

Dart Sass just went 1.0.0, and is now 100% compatible with Ruby Sass 3.5.6. They announced that Ruby Sass has now begun deprecation and—after March 26th, 2019—will no longer be maintained.

The future of Dart Sass looks pretty good:

Another big announcement: as of today, I'm working full-time on @SassCSS. This has been a goal for my entire career and I'm thrilled that it's finally happening

— Blue Gay Carmen San Diego (@nex3) April 3, 2018

The Dart Sass compatibility is also great, because node-sass can now switch to Dart Sass bindings and become entirely up to date. Will it? I have no idea. The maintainer of LibSass and node-sass is the same person (Michael Mifsud), and with 30+ bindings to LibSass, I can’t imagine LibSass just going away. I guess we’ll just have to wait and see a while. I gotta imagine someone will jump on making a node version of Dart Sass one way or another.

I, for one, would love to see a Web Worker version.

The post Ruby Sass to be put to pasture on March 26, 2019 appeared first on CSS-Tricks.

On Paid Newsletters: An Interview With Adam Roberts of SitePoint’s Versioning

Post pobrano z: On Paid Newsletters: An Interview With Adam Roberts of SitePoint’s Versioning

You don’t often think of email as something you pay to get. If anything, most people would pay to get less of it. Of course, there are always emails you like to get and opt into on purpose. We have a newsletter right here on CSS-Tricks that we really try to make worth reading. It’s free, like the vast majority of email newsletters. We hope it helps a bit with engagement and we make it worth doing financially by showing the occasional advertisement. It’s certainly not a full-time job.

I spoke with Adam Roberts who is trying to make it a full-time job by running SitePoint’s Versioning newsletter as a paid subscription. I don’t know much about this world, so I find it all pretty fascinating. I know Ann Friedman has a paid newsletter with a free variant. I know theSkimm is a free newsletter but has a paid membership that powers their app. I was told Bill Bishop made six figures on his first day going paid, which is wild. In the tech space, Ben Thompson’s Stratechery is a paid newsletter.

Let’s hear from Adam on how it’s doing it. I’ll ask questions as headers and the paragraph text is Adam.


So you’re doing it! Making the transition from a free, advertising-supported newsletter to a paid, subscriber-based newsletter. There is a lot to dig into here. Is the motivation a more direct and honest relationship with your readers?

Yep, it’s crazy! Versioning provides devs, designers and web people curated links aimed at making them more productive and up-to-date with the bleeding edge of their industry. I’ve done the newsletter for nearly four years and, up until now, it’s been a thing I squeeze in for an hour or two during my day, as a break from my actual job (most recently, head of content for the site). Now, it’s no longer being squeezed, and is my actual job! I can now focus entirely on making it something people find valuable. They’ll know that everything I include is there because I think it’ll make their lives, skills or knowledge better. I’ve always set a high standard for myself when it comes to what I include—never something I’m 50/50 on (unless it’s an emerging tech) and I never include something because we have a deal or something. Now, this is an actual formal thing. Ads were always a means to an end, now we have a better means, and hopefully a better end!

Is it a straight cut? Anyone who doesn’t subscribe for a fee will stop getting it and have no way to read it?

If you sign up as a paid member, you’ll get the daily newsletter. It’s also viewable on the site, so what you are paying for is really the convenience of email. You’ll also get periodic members-only updates, like deep dives on an emerging subject, always-updated posts on important subjects, and media guides. If you sign up to receive free updates, you’ll get a weekly update plus other periodic free updates.

I’m sure there are financial concerns. Anyone in this position would be nervous that paid subscribers won’t match what was coming in from advertisers before. Is that a concern here? How in-depth did you get trying to figure out the economics of it? Is there potential that it’s even better business?

Given this is a SitePoint venture and not my own thing, we had to make sure it was worthwhile for subscribers and that the numbers were friendly! There’s definitely potential this will work better in a financial sense, while also be being better for subscribers—we wouldn’t be doing it otherwise!

Do you have a good sense of what your readers want from you? It seems to me Versioning is largely a link-dump, but with your hand-curation and light commentary. Did you come to that over time?

I have always had a fairly active reader base, with people dropping me a line via email or Twitter to thank me for something they liked. We also have the requisite creepy email analytics (e.g. opens and clicks), which help to spot trends and subjects to focus on or avoid. It’s a challenge to cover a few different subject areas well (like front-end and back-end development, design, etc.) but I think most readers working in a particular niche in our industry find it helpful to know what everyone else is up to. The world also evolves quickly—the first edition covered a jQuery library, for example. That’s not an area that’s stayed in the forefront of the news since! Mind you, the first edition also had a Star Wars link, so maybe some things do stay the same.

I struggle with even knowing what I want from a newsletter. Most days, give me some personality. I want news but I want to know why I should care and I want an expert to tell me. Then other days, I hate to say it, but I want less talk and more links. Cool story about a goat, but I’m here for the performance links (or whatever). Are you a newsletter connoisseur yourself? Are you writing a newsletter you wanna read?

I think if I ran into Versioning in the wild, I’d want to subscribe to it. I’m working to try to get the content balance right—providing the right stuff for people, plus commentary that’s enjoyable. The other day I had links to an article on understanding state in React (I think it was on some site called CCS-Tricks, am I spelling that right? 😉), an article on fake science gurus on Facebook, one on an Australian cyborg who tried to pay for a train with a chip in his hand, and the video for Warren G’s Regulate (an allusion to the likely response to the various Facebook crises).

I subscribe to so many newsletters, and they’re all different. I think consistency in each newsletter helps. If I was to drop the format and post a long, detailed screed about one subject, that would not go over well. My aim is to include one link that every reader wants to click. Often, that’s all you can handle as a reader, especially on mobile where the interface doesn’t make collecting tabs easy. That’s also why I include the destination domain in brackets next to every link—I don’t want people to end up somewhere they’re not expecting. Also, some sites (like the The New York Times, The New Yorker, and Wired) have limits on the number of free articles people can view. I don’t want people to accidentally run out of freebies because of me—I want them to realize how much they value a site and support it.

Do paid newsletters replace the traditional blog or do you see them complementing one another? We’ve obviously been using our newsletter to support the blog and vice versa, but I’m curious if adding a paid layer changes that relationship.

The formats have different, complementary strengths, and so I don’t think the paid layer necessarily changes this. Newsletters are good at highlighting particularly important things, putting them in context, and maybe taking a long view of a certain issue. Sites (or blogs) are good at adding interactive elements and keeping content up-to-date and accurate as things change.

In our case, one of the things our email platform, Substack, allows us to do is send a particular edition out as both a newsletter and a post. This means a member can access it wherever is best for them. It also means I can do things like send out an initial newsletter outlining a particular topic, then update the online version with new content. I will use this to produce updated, canonical posts for a particular subject or technology. And these formats can be either free to all, or only available to paid members. There’s a lot you can do with this level of flexibility, I’m sure I’m only scratching the surface. The key is to produce something worthwhile for an audience and the format is secondary.

What is it about newsletters that seems to be clicking with people lately? If someone asked you, hey, I have a ton to say about this general topic, and so I’m thinking of either starting a blog or a newsletter, would you say newsletter? Any SEO concerns there?

There is a backlash against the algorithmic tide. Instead of opening a feed and hoping for good content, why not find someone you trust, and whose opinion and taste you find interesting and useful, and sign up to consistently receive content from them. You’ll still get the „something new and cool” dopamine hit you would in a feed, but it’ll be more consistent and reliable. And they’re all separate entities; there’s no „if you followed this publication, maybe you should follow this other one” thing. And if you stop enjoying them, you can just unsubscribe.

Newsletters are intimate. Your inbox is your personal space, where you step back from the tumult and take stock of the stuff that you’ve decided matters most to you. That’s why spam and relentless, poorly-conceived marketing emails always feel like such a violation.

I think newsletters and podcasts are both growing in prominence for the same reasons. Both mediums reward consistency and reliability in format and topic, are built on personality, and have an intimate feel. Someone’s either talking into your ears for hours every week, or writing to you in your private space.

Speaking of concerns, SEO is a tricky one. Algorithms are part of the discussion here again. SitePoint has a pretty decent search footprint, but new and niche publications aren’t so lucky. I suspect there will be a mini-industry of newsletter curation services start to develop. I would actually love to be in that space.

Filter bubbles are another concern. Newsletters are another opportunity for people to only read the stuff they agree with. But it turns out algorithms and social networks aren’t so good at stopping that either!

I was very, very, very sad to see the end of the Awl (and the Hairpin). That was a site that was chock-full of amazing content that was not targeted to appeal to Facebook and such, and as a result, it ultimately wasn’t sustainable. It kind of feels like such cases—plus the re-tooling of Facebook’s feed away from publications and towards people, and the rise of newsletters—are all related. It’s reductive to say „newsletters are the new blogs,” but it’s probably not far off. I would 100% be telling someone to start a newsletter. Actually, I’d tell them to use Substack, but I would have to declare my bias!

Tech-wise, what tooling are you using to curate, create, and send here?

I love talking about this stuff! Uses This is one of my favorite sites. Honestly, it’s pretty low-tech at the moment, just busy. I have a Pocket account with a #versioning tag, so that often gives me a dozen or so links at the start of the day, sourced from my internet meanderings through the evening. I subscribe to a million newsletters, both in my work and personal accounts, on a hopefully both diverse and relevant range of topics.

I subscribe to quite a few RSS feeds using Feedly, too. Nuzzel, which sends you a daily/weekly digest of the most-shared links among people you’re following in Twitter and Facebook, is very useful here too. I have a personal Twitter/Nuzzel feed, plus one I’ve specifically set up for this purpose. Refind is another service trying to solve this problem. Its breadth and depth kind of give me a headache though. They’ve got a Nuzzel-like daily/weekly digest, a service for creating your own newsletters, a cryptocurrency—there’s a lot.

I also have the requisite very big Tweetdeck set-up to grab other links that catch my eye. Oh, and Initab is a new Chrome tab extension you can populate with feeds from certain subreddits and other place. I’ve been playing around with psuedo-Tweetdeck-for-Reddit services too. And Spectrum is a new community service thing I found last week, looks like it could be a winner too. And I need to be more active in Facebook groups. Also, Slack!

So yeah, there’s a lot. A bit of a combo of algorithms and people, hopefully I have the balance right. I also change newsletters, feeds, and other sources regularly, trying to find a better balance.

As for collecting and writing, it’s actually fairly simple—I find something I like, copy the URL into a Markdown doc, then write a description. I deliberately use a web-based Markdown editor (currently Stackedit, though I have used Dillinger and Classeur in the past). Something web-based is good because I can easily tab to it without having to switch to a new app. Stackedit is good because you can paste the generated preview directly into Campaign Monitor and (now) Substack and have formatting and links sorted. I then have a Google Doc to collect links I’ve already shared, and to gauge the reception in the audience—I want to spot trends like a rising interest in micro-services.

Building emails is something we all sort of love and loathe as front-end developers. How did you approach your email design and did you learn anything from building it?

Yes, email design is hard! Fortunately for me, the content and approach I’ve adopted lends itself to a stripped-back design with very little going on. Versioning is just text and a few images, so it required practically zero design. Our use of Campaign Monitor and now Substack meant we could sidestep some of the template work. In general terms though, my advice would be:

  • Focus on the purpose and content of the newsletter, produce a template based on that. It’s more important to produce something compelling, promote it in the right places, gain an audience, and then keep it (and grow it) by making sure you’re consistent in your production.
  • If you can (via a survey or through whatever data your email platform offers) work out what devices and platforms your audience uses to access email. People read email in all sorts of obscure ways, but you can likely cover the main ones for your audience with relatively little effort.
  • Don’t forget the plaintext user! Make sure your URLs are short, your images have alt tags, you’re generally nice to those in your audience who are in this boat. Versioning, given the niche, has a high proportion of these.
  • If all else fails, work with an expert or use one of a plethora of tools and services to do the work for you. Substack has a stripped-back CMS, Campaign Monitor and MailChimp have built-in template builders, and there are plenty of other services you could use. The compatibility issues with email are legendary. You could instead spend your time on things like a distinctive logo and branding or a landing page that communicates your newsletter’s value.

Ultimately people will enjoy a simple newsletter full of content they love presented in a way they can absorb. The design shouldn’t tie you in knots!

Let’s open this up to readers. Are you into the idea of paid newsletters?

The post On Paid Newsletters: An Interview With Adam Roberts of SitePoint’s Versioning appeared first on CSS-Tricks.

Compressive Images Revisited

Post pobrano z: Compressive Images Revisited

Tim Kadlec returns to the topic of how to make images on the web as performant as possible and looks at the technique called “Compressive Images” which is now not recommended for a bunch of reasons. Tim summarizes his point here:

By now the trade-off is pretty clear. Compressive images give us a reduced file size, but it greatly increases the memory footprint. Thanks to the standards that have been developed around responsive images, it’s a trade-off we no longer need to make.

If you’re interested in learning more then it’s hard not to recommend Jason Grigsby’s masterclass called Responsive Images 101, too.

Direct Link to ArticlePermalink

The post Compressive Images Revisited appeared first on CSS-Tricks.

React Code Style Guide

Post pobrano z: React Code Style Guide

I’ve been having the time of my life with React lately. But on my journey, I’ve had a hard time finding good code style guidelines to keep the mix of JSX and JS clean and readable. I’ve been coming up with my own style guides that I’d love to share. Maybe these will be useful to you and, of course, feel free to share similar guidelines in the comment thread below.

Rule #1: Destructure your props

One of my favorite ES6 features is destructuring. It makes assigning object properties to variables feel like much less of a chore. Let’s take a look at an example.

Say we have a dog that we want to display as a div with a class named after its breed. Inside the div is a sentence that notes the dog’s color and tells us if it’s a good dog or bad dog.

class Dog extends Component {
  render () {
    return <div className={this.props.breed}>My {this.props.color} dog is {this.props.isGoodBoy ? "good" : "bad"}</div>;
  }
}

That technically does everything we want, but it just seems like quite a big block of code for what really is only three variables and one HTML tag.

We can break it out by assigning all of the properties of props to local variables.

let breed = this.props.breed;
let color = this.props.color;
let isGoodBoy = this.props.isGoodBoy;

Using ES6, we can put it in one clean statement like this:

let { breed, color, isGoodBoy } = this.props;

To keep everything clean, we put our ternary operator (more on that later) in its own variable as well, and voila.

class Dog extends Component {
  render () {
    let { breed, color, isGoodBoy } = this.props;
    let identifier = isGoodBoy ? "good" : "bad";
    return <div className={breed}>My {color} dog is {identifier}</div>;
  }
}

Much easier to read.

Rule #2: One tag, one line

Now, we’ve all had that moment where we want to take our entire function and make it a mash of operators and tiny parameter names to make some uglified, superfast, unreadable utility function. However, when you’re making a stateless Component in React, you can fairly easily do the same thing while remaining clean.

class Dog extends Component {
  render () {
    let { breed, color, goodOrBad } = this.props;
    return <div className={breed}>My {color} dog is {goodOrBad}</div>;
  }
}

vs.

let Dog = (breed, color, goodOrBad) => <div className={breed}>My {color} dog is {goodOrBad}</div>;

If all you’re doing is making a basic element and placing properties in an HTML tag, then don’t worry about making such a big deal of all the functions and wrappers to get an entirely separate class going. One line of code will do.

You can even get creative with some ES6 spread functions if you pass an object for your properties. Using this.props.content will automatically put the string between the open and close tag.

let propertiesList = {
  className: "my-favorite-component",
  id: "myFav",
  content: "Hello world!"
};
let SimpleDiv = props => <div {... props} />;

let jsxVersion = <SimpleDiv props={propertiesList} />;

When to use the spread function:

  • No ternary operators required
  • Only passing HTML tag attributes and content
  • Can be used repeatedly

When not to use the spread function:

  • Dynamic properties
  • Array or object properties are required
  • A render that would require nested tags

Rule #3: The rule of 3’s

If you have three or more properties, then put them on their own line both in the instance and in the render function.

This would be fine to have just one line of properties:

class GalleryImage extends Component {
  render () {
    let { imgSrc, title } = this.props;
    return (
      <figure>
        <img src={imgSrc} alt=React Code Style Guide />
        <figcaption>
          <p>Title: React Code Style Guide</p>
        </figcaption>
      </figure>
    );
  }
}

But consider this:

class GalleryImage extends Component {
  render () {
    let { imgSrc, title, artist, clas, thumbnail, breakpoint } = this.props;
    return (
      <figure className={clas}>
        <picture>
          <source media={`(min-width: ${breakpoint})`} srcset={imgSrc} />
          <img src={thumbnail} alt=React Code Style Guide />
        </picture>
        <figcaption>
          <p>Title: React Code Style Guide</p>
          <p>Artist: {artist}</p>
        </figcaption>
      </figure>
    );
  }
}

Or the render:

<GalleryImage imgSrc="./src/img/vangogh2.jpg" title="Starry Night" artist="Van Gogh" clas="portrait" thumbnail="./src/img/thumb/vangogh2.gif" breakpoint={320} />

It can get to be too much of a codeblock to read. Drop each property to the next line for a clean, readable look:

let { imgSrc,
      title,
      artist,
      clas,
      thumbnail,
      breakpoint } = this.props;

and:

<GalleryImage
  imgSrc="./src/img/vangogh2.jpg"
  title="Starry Night"
  artist="Van Gogh" 
  clas="landscape"
  thumbnail="./src/img/thumb/vangogh2.gif"
  breakpoint={320} />

Rule #4: Too many properties?

Property management is tricky at any level, but with ES6 destructuring and React’s state-based approach, there are quite a few ways to clean up the look of a lot of properties.

Let’s say we’re making a mapping application that has a list of saved addresses and a GPS coordinate for your current location.

The current user information of position and proximity to favorite address should be in the parent Component of App like this:

class App extends Component {
  constructor (props) {
    super(props);
    this.state = {
      userLat: 0,
      userLon: 0,
      isNearFavoriteAddress: false
    };
  }
}

So, when we make an address and we want it to note how close you are to the address, we’re passing at least two properties from App.

In App render ():

<Address
  ... // Information about the address
  currentLat={this.state.userLat}
  currentLong={this.state.userLon} />

In the render function for Address Component:

render () {
  let { houseNumber,
        streetName,
        streetDirection,
        city,
        state,
        zip,
        lat,
        lon,
        currentLat,
        currentLon } = this.props;
  return ( ... );
}

Already, you can see how this is getting unwieldy. If we take the two sets of information and break them out into their own objects, it becomes much more manageable.

In our App constructor ():

this.state = {
  userPos: {
    lat: 0,
    lon: 0
  },
  isNearFavoriteAddress: false
};

At some point before App render ():

let addressList = [];
addressList.push({
  houseNumber: "1234",
  streetName: "Street Rd",
  streetDirection: "N",
  city: "City",
  state: "ST",
  zip: "12345",
  lat: "019782309834",
  lon: "023845075757"
});

In App render ():

<Address addressInfo={addressList[0]} userPos={this.state.userPos} />

In the render function for Address Component

render () {
  let { addressInfo, userPos } = this.props;
  let { houseNumber,
        streetName,
        streetDirection,
        city,
        state,
        zip,
        lat,
        lon } = addressInfo;
  return ( ... );
}

Much, much cleaner. React also has some great ways to ensure that object properties exist and are of a certain type using PropTypes that we don’t normally have in JavaScript, which is just a great OOP thing anyway.

Rule #5: Dynamic renders – Mapping out arrays

Quite often in HTML, we’re writing the same basic pieces of code over and over, just with a few key distinctions. This is why React was created in the first place. You make an object with properties that return a complex, dynamic HTML block, without having to write each part of it repeatedly.

JavaScript already has a great way to do lists of like information: arrays!

React uses the .map() function to lay out arrays in order, using one parameter from the arrays as a key.

render () {
  let pokemon = [ "Pikachu", "Squirtle", "Bulbasaur", "Charizard" ];
  return (
    <ul>
      {pokemon.map(name => <li key={name}>{name}</li>)}
    </ul>
  );
}

You can even use our handy-dandy spread functions to throw a whole list of parameters in by an object using Object.keys() (keeping in mind that we still need a key).

render () {
  let pokemon = {
    "Pikachu": {
      type: "Electric",
      level: 10
    },
    "Squirtle": {
      type: "Water",
      level: 10
    },
    "Bulbasaur": {
      type: "Grass",
      level: 10
    },
    "Charizard": {
      type: "Fire",
      level: 10
    }
  };
  return (
    <ul>
      {Object.keys(pokemon).map(name => <Pokemon key={name} {... pokemon[name]} />)}
    </ul>
  );
}

Rule #6: Dynamic renders – React ternary operators

In React, you can use operators to do a conditional render just like a variable declaration. In Rule #1, we looked at this for stating whether our dog was good or bad. It’s not entirely necessary to create an entire line of code to decide a one-word difference in a sentence, but when it gets to be large code blocks, it’s difficult to find those little ?’s and :’s.

class SearchResult extends Component {
  render () {
    let { results } = this.props;
    return (
      <section className="search-results">
        {results.length > 0 &&
          results.map(index => <Result key={index} {... results[index] />)
        }
        {results.length === 0 &&
          <div className="no-results">No results</div>
        }
      </section>
    );
  }
}

Or, in true ternary fashion

class SearchResult extends Component {
  render () {
    let { results } = this.props;
    return (
      <section className="search-results">
        {results.length > 0
          ? results.map(index => <Result key={index} {... results[index] />)
          : <div className="no-results">No results</div>
        }
      </section>
    );
  }
}

Even with our tidy result mapping, you can see how the brackets are already nesting quite densely. Now, imagine if our render had more than just one line. It can pretty quickly get unreadable. Consider an alternative:

class SearchResult extends Component {
  render () {
    let { results } = this.props;
    let outputJSX;
    if (results.length > 0) {
      outputJSX = (
        <Fragment>
          {results.map(index => <Result key={index} {... results[index] />)}
        </Fragment>
      );
    } else {
      outputJSX = <div className="no-results">No results</div>;
    }
    return <section className="search-results">{output}</section>;
  }
}

Ultimately, the code length is about the same, but there is one key distinction: with the first example, we’re rapidly switching back and forth between two different syntaxes, making visual parsing taxing and difficult, whereas the second is simply plain JavaScript with value assignments in one, consistent language and a one-line function return in another.

The rule of thumb in this situation is that if the JavaScript you’re putting into your JSX object is more than two words (e.g. object.property), it should be done before the return call.

Wrap up

The combination of syntax can get messy, and these are the most obvious situations where I saw my code going off the rails. Here are the basic concepts that these all come from and can be applied to any situation that wasn’t covered here:

  • Use ES6 features. Seriously. There are a lot of fantastic features that can make your job easier, faster, and much less manual.
  • Only write JSX on the right side of an = or a return.
  • Sometimes you need JavaScript in your JSX. If your JavaScript doesn’t fit on one line (like a .map() function or ternary operator), then it should be done beforehand.
  • If your code starts looking like (<{`${()}`} />), then you’ve probably gone too far. Take the lowest level outside the current statement and do it before this one.

The post React Code Style Guide appeared first on CSS-Tricks.

A CSS Approach to Trap Focus Inside of an Element

Post pobrano z: A CSS Approach to Trap Focus Inside of an Element

I recently read this article by Keith Grant which introduced the newly arrived <dialog>. Excited by this new UI element, I immediately sat down to experiment with it to see how it can be used effectively as a modal — the most common use of it. While experimenting, I discovered a neat CSS trick on how to trap focus within the <dialog> element, a common accessibility requirement for modals, and a notoriously difficult one.

Disclaimer: The <dialog> demos in this article are tested on Chrome and Firefox browsers only. Safari has some weird issue where not all elements are focused while doing a normal keyboard navigation with Tab key!

What is focus trapping?

First, a quote from the W3C documentation regarding what should happen following a key press inside a dialog:

Tab:

  • Moves focus to the next tab-able element inside the dialog.
  • If focus is on the last tab-able element inside the dialog, moves focus to the first tab-able element inside the dialog.

Shift + Tab

  • Moves focus to the previous tab-able element inside the dialog.
  • If focus is on the first tab-able element inside the dialog, moves focus to the last tab-able element inside the dialog.

To summarize, when inside a dialog, pressing Tab or Shift+Tab should cycle the focus within the dialog only—amongst the focusable elements inside the dialog.

This makes sense because when a dialog is open, a user is interacting only inside it and allowing the focus to escape outside the dialog would essentially be mixing contexts and possibly create a state where the user doesn’t know which element is in focus.

So, going back to the idea of a modal, our expectation would be that tabbing inside of the modal would only focus on elements inside of the modal. Anything outside of the context of the modal would be out of scope because the tab is only concerned with what is inside of it. This is what we mean by focus trapping.

An implementation with JavaScript

If we were to implement focus trapping inside a <dialog>, the most common approach would be to do the following when the dialog opens:

1. Grab all the focusable/tappable elements inside the dialog.
2. Listen for Tab and Shift+Tab keypresses and manually focus the next or previous element, respectively.
3. If the keypress happens on the first focusable element, then focus the last focusable element in the chain and vice versa.

This way, we create a loop on focus as the user presses Tab or Shift+Tab. See this W3C code snippet as an an example of how this might be approached with JavaScript. You’ll see it’s quite a bit of JavaScript.

Enter :focus-within

Back to my experiment with the new <dialog> element. When thinking about focus trapping, a CSS pseudo class (also very recent in browsers) immediately came to my mind : :focus-within.

If you have not heard about that before, it represents an element that has received focus or contains an element that has received focus. So, for example, you have a <div> and inside of it is an input element. If you want to style that <div> when the contained input has focus, you can do it like so:

div:focus-within {
 border: 2px solid red;
}

See the Pen :focus-within by Geoff Graham (@geoffgraham) on CodePen.

The CSS trick to focus trapping

Let’s exploit :focus-within and CSS transitions to implement a basic focus trap inside of a <dialog> element.

To summarise, here is how the trick works. When the focus is not within the dialog (and the dialog is open), we:

  1. trigger a CSS transition
  2. detect that transition completion in JavaScript
  3. focus the first element in the dialog

But, first let’s get set up. Here’s the basic dialog and opening functionality:

<button id="button">Open dialog</button>
<dialog id="modal">
  <form action="">
    <label>
      <input type="text" /> Username
    </label>
    <label>
      <input type="password" /> Password
    </label>
    <input type="submit" value="Submit" />
  </form>
</dialog>
button.onclick = () => {
  modal.showModal();
}

There we go. Clicking on the button should open our dialog. Just this much code required to make a basic working modal using the new <dialog> element!

See the Pen Dialog without focus trap by Kushagra Gour (@chinchang) on CodePen.

Note: As in the above example demo of dialog, you’ll notice some extra polyfill code to make <dialog> work in browsers where it isn’t supported.

If you opened the dialog in the example above and started tabbing several times, you may have already noticed the problem: the focus starts with elements in the dialog, but then leaves once the last element in the dialog has been passed.

This is the core of our trick. We somehow need to send the lost focus detected with :focus-within over to JavaScript so that we can send the focus back to the dialog. This is where CSS transitions come into play. A CSS transition is something that happens through CSS, but emits events in JavaScript too. In our case, we can trigger a transition on any property with a negligible (because it doesn’t matter in our case) visual difference and listen for the transition completion in JavaScript.

Note that we need to trigger this transition when the dialog is open but doesn’t have focus inside it.

dialog {
  background-color: rgb(255, 255, 255);
}
dialog[open]:not(:focus-within) {
  background-color: rgb(255, 255, 254);
  transition: background-color 0.01s;
}

Let’s see what that CSS is doing.

  1. We put a background-color of our choice on the dialog. This isn’t necessary, but ensures we have the same background color across browsers.
  2. The dialog[open]:not(:focus-within) selector applies when the dialog is open but doesn’t have focus on or inside it. This works because native <dialog> element puts an open attribute when it’s open.
  3. Inside this rule, we change the background-color by a minimum amount. This is the least change required to trigger a CSS animation and at the same time not causing any visual difference for the user (remember this is a dummy transition). Also, we set the transition property with a very small duration because we want it to finish as soon as possible and get detected in JavaScript.

A touch of JavaScript

Now, all we need to do is detect the end of our triggered CSS transition and focus back the first element inside the modal, like so:

modal.addEventListener('transitionend', (e) => {
  modal.querySelector('input').focus();
});

We attach a transitionend listener on the modal and inside the callback, we focus the first input inside the modal. Done!

See the Pen Dialog focus trapping with CSS by Kushagra Gour (@chinchang) on CodePen.

Limitations

This is a quick experiment I did to create a working proof-of-concept of focus trapping with the :focus-within pseudo class. It has several limitations compared to dedicated JavaScript solutions to achieve this. Nevertheless, something is better than nothing!

Here are a couple of things this implementation lacks:

  1. According to W3C guidelines, the focus should cycle on the focusable element. But we are always focusing on the first input element. This is because without writing more JavaScript, we cannot know whether the focus was lost from the first or last element.
  2. We are always focusing back to the first input element. But there are many more focusable HTML elements that might be present before input or maybe there is not input element at all inside the modal. Again, full-fledged JavaScript solutions detect and maintain a list of all focusable elements and focus the right one.

Better (JavaScript) implementations of focus trapping

  1. As mentioned earlier, one working example is available inside the W3C documentation itself.
  2. Here is another implementation by Rodney Rehm that also listens for tab.
  3. Greg Kraus has a library that achieves this. His implementation maintains a list of selectors for all valid focusable elements.
  4. One more lightweight library to create accessible modals.

That is all for this experiment. If you liked this trick, you can follow me on Twitter where I share more articles and side projects of mine.

The post A CSS Approach to Trap Focus Inside of an Element appeared first on CSS-Tricks.