Css Tricks

Syndicate content
Tips, Tricks, and Techniques on using Cascading Style Sheets.
Updated: 13 hours 31 min ago

Rendering Spectrum

19 hours 52 min ago

Here are the big categories of rendering websites:

  • Client: ship a <div id="root"></div> and let a JavaScript template render all of it.
  • Static: pre-render all the HTML.
  • Server: let a live server process requests and generate the HTML response.

They are not mutually exclusive.

  • A website could statically pre-render 75% of it’s pages (say, blog posts), but the other 25% have a server respond to (say, forums).
  • A website could statically pre-render all the pages, but have a couple of empty <div>s in there that have client-side rendered content in them (e.g. a dynamically generated menu based on the logged-in user).
  • A website could be primarily server-rendered, but has caching in front of it such that it behaves statically.
  • A website could render statically, but then “hydrate” itself into an entirely client-rendered site.
  • A website could be a mix of server and static rendering, but have dynamic parts similar to client-side rendering, but actually happen in an edge function, so it ends up more like server-side rendering.

Next.js is interesting in that it can do all three. Here’s Tim Neutkens in a recent interview:

Next.js allows you to pre-render pages. It creates HTML on a server at build time with static site generation or uses run-time rendering on the server side. Next allows you to do a hybrid of those. Unlike most other frameworks, you are not bound by, oh, I’m going to build my app completely statically generated. Instead, you’re allowed to have some pages be server-side rendered and some pages be statically generated.

In the new release we make it possible to update these statically generated pages without having to run a new build, rebuilding your whole app.

Cool. Love to see that happening at the framework level. Seems like having to go all-in on one rendering style isn’t practical for a lot of sites.

Client rendering is the most flexible, but comes with all these serious downsides like worse performance, worse reliability, more strain on devices, bad SEO, etc. Static pre-rendering is the most robust, speedy, and secure, but is the most limited. Edge functions on top of static is starting to open doors, but server-rendering is the classic mix of flexibility and speed that has dominated the web for good reason.

Client rendering also opens the door for that “SPA” (Single Page App) feel. I still like that, personally. I like the no-page-refresh feel. It’s makes a site feel snappy and opens the door for page transitions. Gatsby is famous for popularizing hydration, where you get the pre-rendered static bonus, but then the upgrade into SPA as the JavaScript downloads.

I’d love to see the web get to the point where we get all that “good feel” bonus of an SPA without actually having to build an SPA. It’s notable when frameworks provide SPA feels without having to manage much of that yourself, but still, something is managing it and that something is a bunch of JavaScript.

Tom MacWright wrote about that recently in his “If not SPAs, What?” post. Some of today’s alternatives:

Turbolinks … what is the bare minimum you need to do to get the SPA experience without any cooperation from your application?

Turbolinks is like… click link, click is intercepted, Ajax request for new page is made, JavaScript flops out the content on the page with the new content. Super easy to implement, but it’s still JavaScript, and not particularly intelligent about sending less data across the wire.

barba.js and instant.page are alternative approaches to the same sort of problem.

Barba is all about getting page transitions going (more detail on that concept). instant.page is all about pre-loading/rendering pages right before you click then, so even though you get a page refresh, it feels less intrusive (particularly with paint holding). Both are cool, but not quite one-to-one replacements for an SPA. (Even with paint holding, pre-rendering, and lightweight pages, I still don’t think the experience is quite a smooth as an SPA. For example, you still get the page loading spinner.)

So… is the anything else cooking? Kinda. There is <portal>. Possibly too simplified, but here goes: portals are like iframes. They can even be visually displayed just like an iframe. That means the rendering of the URL in the portal is already done. Then you can “promote” the portal to be the active page, and even animate the portal itself while doing so.

I don’t hate it. I can imagine someone building a turbolinks-like library on portals so they are “easy to use” and make a site more SPA-like.

Still, animating a rectangle into position isn’t often what is desired from animated page transitions. Just look at Sarah’s “Native-Like Animations for Page Transitions on the Web” article. That’s what the people want (at least the possibility of it). That’s why Jeremy said not portals the other day when he cheekily said that “[m]ost single page apps are just giant carousels.” He also points to Jake’s navigation-transitions proposal from a few years back.

I love this proposal. It focuses on user needs. It also asks why people reach for JavaScript frameworks instead of using what browsers provide. People reach for JavaScript frameworks because browsers don’t yet provide some functionality: components like tabs or accordions; DOM diffing; control over styling complex form elements; navigation transitions. The problems that JavaScript frameworks are solving today should be seen as the R&D departments for web standards of tomorrow. (And conversely, I strongly believe that the aim of any good JavaScript framework should be to make itself redundant.)

So what’s the best rendering method? Whatever works best for you, but perhaps a hierarchy like this makes some general sense:

  1. Static HTML as much as you can
  2. Edge functions over static HTML so you can do whatever dynamic things
  3. Server generated HTML what you have to after that
  4. Client-side render only what you absolutely have to

The post Rendering Spectrum appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

The Core Web Vitals hype train

Tue, 11/24/2020 - 5:42am

Some baby bear thinking from Katie Sylor-Miller:

my excitement for Core Web Vitals is tempered with a healthy skepticism. I’m not yet convinced that Largest Contentful Paint (LCP), First Input Delay (FID), and Cumulative Layout Shift (CLS) are the right metrics that all sites should be measuring themselves against. I worry that the outsized emphasis placed on Core Web Vitals by including them in SEO scoring will result in developers focusing solely on those three numbers without truly understanding what they mean and, more importantly, what they don’t mean.

Katie is pro-Web Core Vitals because of their correlation with real user experiences, but there is a lot more to think about. If we focus only on these metrics (because we have now an extremely strong incentive to do so) we’re missing out on a lot. They may not be the analytics that matter most to us or that correlate with business goals.

The horse’s mouth says the SEO implications don’t start until May 2021.

I admit I’ve been on the hype train myself a little bit. I like all of Katie’s points but I think I’ll still call it a step forward for web analytics. Robin also mentioned Sentry could do the tracking the other day.

Jeremy mentions the proliferation of initials:

Personally, my beef with core web vitals is that they introduce even more uneccessary initialisms (see, for example, Harry’s recent post where he uses CWV metrics like LCP, FID, and CLS—alongside TTFB and SI—to look at PLPs, PDPs, and SRPs. I mean, WTF?).

Direct Link to ArticlePermalink

The post The Core Web Vitals hype train appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Creating UI Components in SVG

Mon, 11/23/2020 - 1:35pm

I’m thoroughly convinced that SVG unlocks a whole entire world of building interfaces on the web. It might seem daunting to learn SVG at first, but you have a spec that was designed to create shapes and yet, still has elements, like text, links, and aria labels available to you. You can accomplish some of the same effects in CSS, but it’s a little more particular to get positioning just right, especially across viewports and for responsive development.

What’s special about SVG is that all the positioning is based on a coordinate system, a little like the game Battleship. That means deciding where everything goes and how it’s drawn, as well as how it’s relative to each other, can be really straightforward to reason about. CSS positioning is for layout, which is great because you have things that correspond to one another in terms of the flow of the document. This otherwise positive trait is harder to work with if you’re making a component that’s very particular, with overlapping and precisely placed elements.

Truly, once you learn SVG, you can draw anything, and have it scale on any device. Even this very site uses SVG for custom UI elements, such as my avatar, above (meta!).

That little half circle below the author image is just SVG markup.

We won’t cover everything about SVGs in this post (you can learn some of those fundamentals here, here, here and here), but in order to illustrate the possibilities that SVG opens up for UI component development, let’s talk through one particular use case and break down how we would think about building something custom.

The timeline task list component

Recently, I was working on a project with my team at Netlify. We wanted to show the viewer which video in a series of videos in a course they were currently watching. In other words, we wanted to make some sort of thing that’s like a todo list, but shows overall progress as items are completed. (We made a free space-themed learning platform and it’s hella cool. Yes, I said hella.)

Here’s how that looks:

So how would we go about this? I’ll show an example in both Vue and React so that you can see how it might work in both frameworks.

The Vue version

We decided to make the platform in Next.js for dogfooding purposes (i.e. trying out our own Next on Netlify build plugin), but I’m more fluent in Vue so I wrote the initial prototype in Vue and ported it over to React.

Here is the full CodePen demo:

CodePen Embed Fallback

Let’s walk through this code a bit. First off, this is a single file component (SFC), so the template HTML, reactive script, and scoped styles are all encapsulated in this one file.

We’ll store some dummy tasks in data, including whether each task is completed or not. We’ll also make a method we can call on a click directive so that we can toggle whether the state is done or not.

<script> export default { data() { return { tasks: [ { name: 'thing', done: false }, // ... ] }; }, methods: { selectThis(index) { this.tasks[index].done = !this.tasks[index].done } } }; </script>

Now, what we want to do is create an SVG that has a flexible viewBox depending on the amount of elements. We also want to tell screen readers that this a presentational element and that we will provide a title with a unique id of timeline. (Get more information on creating accessible SVGs.)

<template> <div id="app"> <div> <svg :viewBox="`0 0 30 ${tasks.length * 50}`" xmlns="http://www.w3.org/2000/svg" width="30" stroke="currentColor" fill="white" aria-labelledby="timeline" role="presentation"> <title id="timeline">timeline element</title> <!-- ... --> </svg> </div> </div> </template>

The stroke is set to currentColor to allow for some flexibility — if we want to reuse the component in multiple places, it will inherit whatever color is used on the encapsulating div.

Next, inside the SVG, we want to create a vertical line that’s the length of the task list. Lines are fairly straightforward. We have x1 and x2 values (where the line is plotted on the x-axis), and similarly, y1 and y2.

<line x1="10" x2="10" :y1="num2" :y2="tasks.length * num1 - num2" />

The x-axis stays consistently at 10 because we’re drawing a line downward rather than left-to-right. We’ll store two numbers in data: the amount we want our spacing to be, which will be num1, and the amount we want our margin to be, which will be num2.

data() { return { num1: 32, num2: 15, // ... } }

The y-axis starts with num2, which is subtracted from the end, as well as the margin. The tasks.length is multiplied by the spacing, which is num1.

Now, we’ll need the circles that lie on the line. Each circle is an indicator for whether a task has been completed or not. We’ll need one circle for each task, so we’ll use v-for with a unique key, which is the index (and is safe to use here as they will never reorder). We’ll connect the click directive with our method and pass in the index as a param as well.

CIrcles in SVG are made up of three attributes. The middle of the circle is plotted at cx and cy, and then we draw a radius with r. Like the line, cx starts at 10. The radius is 4 because that’s what’s readable at this scale. cy will be spaced like the line: index times the spacing (num1), plus the margin (num2).

Finally, we’ll put use a ternary to set the fill. If the task is done, it will be filled with currentColor. If not, it will be filled with white (or whatever the background is). This could be filled with a prop that gets passed in the background, for instance, where you have light and dark circles.

<circle @click="selectThis(i)" v-for="(task, i) in tasks" :key="task.name" cx="10" r="4" :cy="i * num1 + num2" :fill="task.done ? 'currentColor' : 'white'" class="select"/>

Finally, we are using CSS grid to align a div with the names of tasks. This is laid out much in the same way, where we’re looping through the tasks, and are also tied to that same click event to toggle the done state.

<template> <div> <div @click="selectThis(i)" v-for="(task, i) in tasks" :key="task.name" class="select"> {{ task.name }} </div> </div> </template> The React version

Here is where we ended up with the React version. We’re working towards open sourcing this so that you can see the full code and its history. Here are a few modifications:

  • We’re using CSS modules rather than the SCFs in Vue
  • We’re importing the Next.js link, so that rather than toggling a “done” state, we’re taking a user to a dynamic page in Next.js
  • The tasks we’re using are actually stages of the course —or “Mission” as we call them — which are passed in here rather than held by the component.

Most of the other functionality is the same :)

import styles from './MissionTracker.module.css'; import React, { useState } from 'react'; import Link from 'next/link'; function MissionTracker({ currentMission, currentStage, stages }) { const [tasks, setTasks] = useState([...stages]); const num1 = [32]; const num2 = [15]; const updateDoneTasks = (index) => () => { let tasksCopy = [...tasks]; tasksCopy[index].done = !tasksCopy[index].done; setTasks(tasksCopy); }; const taskTextStyles = (task) => { const baseStyles = `${styles['tracker-select']} ${styles['task-label']}`; if (currentStage === task.slug.current) { return baseStyles + ` ${styles['is-current-task']}`; } else { return baseStyles; } }; return ( <div className={styles.container}> <section> {tasks.map((task, index) => ( <div key={`mt-${task.slug}-${index}`} className={taskTextStyles(task)} > <Link href={`/learn/${currentMission}/${task.slug.current}`}> {task.title} </Link> </div> ))} </section> <section> <svg viewBox={`0 0 30 ${tasks.length * 50}`} className={styles['tracker-svg']} xmlns="http://www.w3.org/2000/svg" width="30" stroke="currentColor" fill="white" aria-labelledby="timeline" role="presentation" > <title id="timeline">timeline element</title> <line x1="10" x2="10" y1={num2} y2={tasks.length * num1 - num2} /> {tasks.map((task, index) => ( <circle key={`mt-circle-${task.name}-${index}`} onClick={updateDoneTasks(index)} cx="10" r="4" cy={index * +num1 + +num2} fill={ task.slug.current === currentStage ? 'currentColor' : 'black' } className={styles['tracker-select']} /> ))} </svg> </section> </div> ); } export default MissionTracker; Final version

You can see the final working version here:

See Site

This component is flexible enough to accommodate lists small and large, multiple browsers, and responsive sizing. It also allows the user to have better understanding of where they are in their progress in the course.

But this is just one component. You can make any number of UI elements: knobs, controls, progress indicators, loaders… the sky’s the limit. You can style them with CSS, or inline styles, you can have them update based on props, on context, on reactive data, the sky’s the limit! I hope this opens some doors on how you yourself can develop more engaging UI elements for the web.

The post Creating UI Components in SVG appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Graphery SVG

Mon, 11/23/2020 - 1:33pm

I’ve compared SVG and Canvas before. If you’re trying to decide between them, read that. I’d say the #1 difference between them is vector (SVG) versus raster (Canvas). But the #2 difference is how you work with them. SVG is declarative, as in, literal elements that express what they are through attributes and content. Canvas is imperative, as in, you script instructions for it to follow.

Canvas is a JavaScript API, so it may jive well with JavaScript developers or environments where the UI being built is otherwise JavaScript-based. But SVG is in the (and has a) DOM, and the DOM has APIs too! That means you can script SVG if you like. It’s just, arguably, not particularly convenient. I just saw Graphery SVG which is clearly an attempt to rectify that.

How you’d script the creation of a pink rectangle with standard DOM APIs:

const div = document.querySelector('#drawing'); const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); svg.setAttribute('width', '100%'); svg.setAttribute('height', '100%'); div.appendChild(svg); const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); rect.setAttribute('x', '10'); rect.setAttribute('y', '10'); rect.setAttribute('width', '90'); rect.setAttribute('height', '90'); rect.setAttribute('fill', '#F06'); svg.appendChild(rect);

With Graphery SVG:

const svg = gySVG().width('100%').height('100%'); const rect = svg.add('rect').x(10).y(10).width(90).height(90).fill('#f06'); svg.attachTo('#drawing');

Gotta love that chaining. High five, jQuery.

Direct Link to ArticlePermalink

The post Graphery SVG appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

What’s Missing from CSS?

Sat, 11/21/2020 - 9:44am

The survey results from the State of CSS aren’t out yet, but they made this landing page that randomly shows you what one person wrote to answer that question. Just clicking the reload button a bunch, I get the sense that the top answers are:

  • Container Queries
  • Parent Selectors
  • Nesting
  • Something extremely odd that doesn’t really make sense and makes me wonder about people

Direct Link to ArticlePermalink

The post What’s Missing from CSS? appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

How You Might Build a Modern Day Webring

Fri, 11/20/2020 - 11:18am

I’m sure different people picture different things when they think about webrings, so let me clarify what I picture. I see an element on a website that:

  1. Signifies this site is part of a webring
  2. Allows you to move to the next or previous site of the webring
  3. Maybe has other functionality like going to a “random” site or seeing the complete list

But then another major thing:

  1. Site owners don’t have to do much. They just plop (it?) on the site and a functional webring UI is there.

So like this:

A Calvin & Hobbes webring UI that comes up all the time when you search the web about webrings

How did it used to work? You know what? I have no idea. My guess is that it was an ancient <frameset><frame /></frameset> situation, but this stuff is before my time a bit. How might we do this today?

Well, we could use an <iframe>, I guess. That’s what sites like YouTube do when they give “embed code” as an HTML snippet. Sites like Twitter and CodePen give you a <div> (or whatever semantic HTML) and a <script>, so that there can be fallback content and the script enhances it into an <iframe>. An <iframe> might be fine, as it asks very little of the site owner, but they are known to be fairly bad for performance. It’s a whole document inside another document, after all. Plus, they don’t offer much by the way of customization. You get what you get.

Another problem with an iframe is that… how would it know what site it is currently embedded on? Maybe a URL parameter? Maybe a postMessage from the parent page? Not super clean if you ask me.

I think a Web Component might be the way to go here, as long as we’re thinking modern. We could make a custom element like <webring-*>. Let’s do that, and make it for CSS sites specifically. That’ll give us the opportunity to send in the current site with an attribute, like this:

<webring-css site="http://css-tricks.com"> This is gonna boot itself up into webring in a minute. </webring-css>

That solves the technology choice. Now we need to figure out the global place to store the data. Because, well, a webring needs to be able to be updated. Sites need to be able to be added and removed from the webring without the other sites on the webring needing to do anything.

For fairly simple data like this, a JSON file on GitHub seems to be a perfectly modern choice. Let’s do that.

Now everyone can see all the sites in the webring in a fairly readable fashion. Plus, they could submit Pull Requests against it to add/remove sites (feel free).

Getting that data from our web component is a fetch away:

fetch(`https://raw.githubusercontent.com/CSS-Tricks/css-webring/main/webring.json`) .then((response) => response.json()) .then((sites) => { // Got the data. });

We’ll fire that off when our web component mounts. Let’s scaffold that…

const DATA_FOR_WEBRING = `https://raw.githubusercontent.com/CSS-Tricks/css-webring/main/webring.json`; const template = document.createElement("template"); template.innerHTML = ` <style> /* styles */ </style> <div class="webring"> <!-- content --> </div>`; class WebRing extends HTMLElement { connectedCallback() { this.attachShadow({ mode: "open" }); this.shadowRoot.appendChild(template.content.cloneNode(true)); fetch(DATA_FOR_WEBRING) .then((response) => response.json()) .then((sites) => { // update template with data }); } } window.customElements.define("webring-css", WebRing);

The rest of this isn’t so terribly interesting that I feel like we need to go through it step by step. I’ll just blog-sketch it for you:

  1. Pull the attribute off the web component so we can see what the current site is
  2. Match the current site in the data
  3. Build out Next, Previous, and Random links from the data in a template
  4. Update the HTML in the template

And voilà!

CodePen Embed Fallback Could you do a lot more with this, like error handling, better design, and better everything?

Yes.

The post How You Might Build a Modern Day Webring appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

console.log({ myVariable });

Thu, 11/19/2020 - 12:30pm

I think this might be my most popular tweet of all time, but I’m not sure how to verify that these days. I’ll restate this neat little trick here because blogging is cool and fun.

I used to do this a lot while debugging JavaScript:

console.log("myVariable: ", myVariable);

But now I do this because it’s just easier to type quickly:

console.log({ myVariable });

And you don’t miss out on anything in DevTools:

Now that this is a blog post, I can elaborate a smidge…

The output display there (and really, console.log itself) is a DevTools thing, but the syntax isn’t. By using curly brackets in JavaScript, I’m creating an object. I don’t have to assign an object to anything, it can just be.

{ foo: "bar" }

You see that a lot when passing an object to a function, like myFunction({ config: options });. The “trick” is that when you’re making an object, you can “shorthand” it by providing only a variable, which makes it implied). So like:

const fruit = "apple"; // Shorthand let x = { fruit } console.log(x); // Normal way, literally the same exact thing x = { "fruit": fruit } console.log(x); // identical

When you have a variable and you log it like console.log({ myVariable }); you’re using that shorthand object creation syntax and it gets logged like the object it becomes.

One strike against this idea is that sometimes DevTools chooses to output it as ▶ Object and you have to click to open to see the value. I don’t know what the heuristics are of when it chooses to do that and when it doesn’t. If you don’t like that, or the output format of an object in general, you might prefer the console.table({ myVariable }); format:

The post console.log({ myVariable }); appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

mediastack

Thu, 11/19/2020 - 12:05pm

Have you ever had the idea for a website or new app that involved showing news content? You don’t have to create content yourself to have the right to build an innovative news reading experience. I remember when Flipboard came out. They didn’t (and still don’t) actually produce content — they just made a fantastic experience for reading it, and did very well with that.

Where do you get that news content? mediastack. You’re going to need a great API for delivering news content, and that’s exactly what mediastack is.

You sign up and get an API key. It’s free to use for 500 requests/month, which is enough to prototype what you’re building, particularly if you’re being smart about caching responses. Then, when you need more requests, it scales up very reasonably in price.

Gotta love a good API that does exactly what you need it to do, so you can get to work.

Another thing I like about mediastack is that it’s from apilayer, who have been doing APIs like this for a long time. Their whole business is about providing purpose-built APIs for tasks that developers need to do. I like it when companies are incentivized to do a good job for you because you’re very directly their customer and using their product for exactly what it’s for.

The post mediastack appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

grid-auto-flow : CSS Grid :: flex-direction : Flexbox

Wed, 11/18/2020 - 3:11pm

When setting a parent element to display: flex, its child elements align left-to-right like this:

CodePen Embed Fallback

Now, one of the neat things we can do with flexbox is change the direction so that child elements are stacked vertically on top of each other in a column. We can do that with the flex-direction property (or with the flex-flow shorthand):

CodePen Embed Fallback

Okay, cool. But how would I do something like this with CSS Grid? As in, let’s say I want all those child elements to be aligned like this:

1 3 5 7 -------- 2 4 6 8

…instead of this:

1 2 3 4 -------- 5 6 7 8

By default, when I set a parent element to use CSS Grid, the elements will be positioned left-to-right just like flexbox. In the example below I’m telling the grid to have 6 columns and 2 rows, then let the child elements fill up each column of the first row before they fill up the columns of the second. You know, standard line wrapping behavior.

.parent { display: grid; grid-template-columns: repeat(6, 1fr); grid-template-rows: repeat(2, 150px); gap: 20px; } CodePen Embed Fallback

Basically what I want here is the opposite: I want our child elements to fill up column 1, row 1 and row 2, then move on to the next column. In other words, column wrapping! I know that if I create a grid with rows and columns I could individually place those elements into those positions. Like so:

.parent { display: grid; grid-template-columns: repeat(6, 1fr); grid-template-rows: repeat(6, 150px); } .child-1 { grid-column: 1; grid-row: 1; } .child-2 { grid-column: 1; grid-row: 2; } .child-3 { grid-column: 2; grid-row: 1; } /* etc, etc. */ CodePen Embed Fallback

Okay, neat! This gets me what I want but it’s a giant pain having to individually set the position of each item. It feels like I’m using position: absolute and it doesn’t feel particularly smart. So what if I just wanted this layout to be done for me, so that each new child element would align into the correct spot…correctly?

What I’m asking for (I think) is this: is there a CSS Grid version of flex-direction: column?

Well, after searching around a bit, Rachel Andrew pointed me to the correct answer in her rather excellent playground, Grid by Example. And as you can see in this demo, Rachel shows us how to do just that:

CodePen Embed Fallback

Neato! Rachel does this with the grid-auto-flow property: it tells a grid container how to fill the unoccupied space with child elements. So I can do that just by writing this:

.parent { display: grid; grid-auto-flow: column; /* set up columns and rows here */ }

By default, child elements of a grid will fill up each column until a row is filled, then it’ll flow into the next beneath it. This is why the default for grid-auto-flow is set to row because we’re filling up rows of the grid first. But if we set it to column, then each new element will fill up all the space of column 1 before moving on to column 2, etc.

.parent { display: grid; grid-auto-flow: column; grid-template-columns: repeat(6, 1fr); grid-template-rows: repeat(2, 150px); } CodePen Embed Fallback

This is what the flow part of grid-auto-flow means and for the longest time I ignored the property because it seemed (don’t laugh) scary. Just reading the word grid-auto-flow is enough to make me want to shut off my laptop and walk into the ocean.

But! It’s a pretty useful property and makes a ton of sense, especially if you think of it as the CSS Grid version of flex-direction.

The post grid-auto-flow : CSS Grid :: flex-direction : Flexbox appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Firefox 83

Wed, 11/18/2020 - 1:26pm

There’s a small line in the changelog that is is big news for CSS:

We’ve added support for CSS Conic Gradients (bug 1632351) and (bug 1175958).

&#x1f389;&#x1f389;&#x1f389;

Conic gradients are circular, just like their radial counterpart, but place color stops around the circle instead of from the center of the circle.

CodePen Embed Fallback

Adding more color stops gives it a “cone-like” appearance that’s fitting of the name:

CodePen Embed Fallback

Prior to Firefox 83, cross-browser support for conic gradients meant using a polyfill, like this one from Lea Verou. But browser support is much nicer with Firefox in the mix.

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

DesktopChromeFirefoxIEEdgeSafari6983No7912.1Mobile / TabletAndroid ChromeAndroid FirefoxAndroidiOS Safari86No8112.2-12.4

And wouldn’t you know it! We just so happen to have a brand-spankin’ new CSS Gradients guide that not only covers conic gradients, but linear, radial, and repeating gradients as well, including explanations, examples and, of course, plenty of CSS tricks sprinkled in along the way.

One of those tricks? Using hard color stops to create a pie chart.

CodePen Embed Fallback

Direct Link to ArticlePermalink

The post Firefox 83 appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Thinking Outside the Box with CSS Grid

Wed, 11/18/2020 - 1:23pm

Great tutorial from Alex Trost (based on some demos, like this one, from Andy Barefoot) showcasing how, while CSS grid has straight grid lines across and down, you can place items across grid lines creating a staggered effect that looks pretty rad. Grid-like, but it appears to align to diagonal lines rather than horizontal and vertical lines because of the staggering. And you still get all the flexibility of grid!

Direct Link to ArticlePermalink

The post Thinking Outside the Box with CSS Grid appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Upptime

Wed, 11/18/2020 - 5:48am

GitHub Actions are like free computers.

Well, there is pricing, but even free plans get 2,000 minutes a month. You write configuration files for what you want these computers to do. Those configuration files go into a repo, so typically they do things specific to that repo. I’m sure that CI/CD is vast majority of GitHub Actions usage. That is, running your tests, and deploying your code. Which is absolutely fantastic.

But like I said, GitHub Actions are computers, so you can have them run whatever code you like. (I’m sure there is EULA stuff you are bound to, but you know what I mean.) Just like everybody’s favorite, serverless functions, GitHub Actions can do that same stuff. Wanna run a build process? Hit an API? Optimize images? Screenshot a URL? Do it up. Most actions are tied to specific events, like “run this code when I commit to a branch” or “run this code against this pull request.” But you can also schedule them on a cron schedule.

So you’ve got a free computer for 2,000 minutes a month you can run on a schedule. I’m sure that will breed some pretty interesting creativity, especially since GitHub Actions is a marketplace. Allow me to get around to the title of this post… I find Upptime an incredible clever usage of all this. You essentially get a free configurable uptime monitor for whatever you want.

Direct Link to ArticlePermalink

The post Upptime appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Measuring Core Web Vitals with Sentry

Tue, 11/17/2020 - 12:13pm

Chris made a few notes about Core Web Vitals the other day, explaining why measuring these performance metrics are so gosh darn important:

I still think the Google-devised Core Web Vitals are smart. When I first got into caring about performance, it was all: reduce requests! cache things! Make stuff smaller! And while those are all very related to web performance, they are abstractly related. Actual web performance to users are things like how long did I have to wait to see the content on the page? How long until I can actually interact with the page, like type in a form or click a link? Did things obnoxiously jump around while I was trying to do something? That’s why Core Web Vitals are smart: they measure those things.

There’s certainly a lot of tools out there that help you measure these extremely important metrics. Chris’ post was timely because where I work at Sentry¹, we’re launching our own take on this. My favorite once-a-year-blogger and mentor at Sentry, Dora Chan, explained why using real user data is important when it comes to measuring Web Vitals and how our own product is approaching it:

Google Web Vitals can be viewed using the Google Chrome Lighthouse extension. You may be asking yourself, “Why would I need Sentry to see what these are if I already have Google?” Good question. Google provides synthetic lab data, where you can directly control your environment, device, and network speed. This is good and all, but it only paints part of the picture. Paint. Get it?

Sentry gathers aggregate field data on what your users actually experience when they engage with your application. This includes context on variable network speed, browser, device, region, and so forth. With Web Vitals, we can help you understand what’s happening in the wild, how frequently it’s happening, why, and what else is connected to the behavior.

Sentry breaks down all these transactions into the most important metrics so you can see how your customers are experiencing performance problems. Perhaps 42% of the time a transaction has an input delay of more than 301ms. Sentry would show that problem and how it correlates with other performance issues.

I think this is the power of tying Core Web Vitals with user data — or what Dora calls “field data” — because some of our users are experiencing a fast app! They have great wifi! All the wifis! That’s great and all, but there are still users on the other side who put up with a more miserable experience, and having a visual based on actual user data allows us to see which specific actions are slowing things down. This information is what gives us the confidence to hop into the codebase and then fix the problem, but it also helps prioritize these problems in the first place. That’s something we don’t really talk about when it comes to performance.

What’s the most important performance problem with your app right now? This is a trickier question than we might like to admit. Perhaps a First Paint of five seconds isn’t a dealbreaker on the settings page of your app but three seconds on the checkout page is unbearable for the business and customers alike.

So, yeah, performance problems are weird like that; the same result of a metric can mean different things based on the context. And some metrics are more important than others depending on that context.

That’s really why I’m so excited about all these tools. Viewing how users are experiencing an app in real time and then, subsequently, visualizing how the metrics change over time — that’s just magic. Lighthouse scores are fine and dandy, and, don’t get me wrong, they are very useful. They’re just not an extremely accurate measure of how users actually use your app based on your data.

This is where another Sentry feature comes into play. After you’ve signed up and configured everything, head to the Performance section and you’ll see which transactions are getting better over time and which have regressed, or gotten slower:

Tony Xiao is an engineer at Sentry and he wrote about how he used this feature to investigate a front-end problem. That’s right: we use Sentry to measure our Sentry work (whoa, inception). By looking at the Most Regressed Transactions report, Tony was able to dig into the specific transaction that triggered a negative result and identify the problem right then and there. Here’s how he described it:

To a fault, code is loyal to its author. It’s why communicating with your code is critical. And it’s why trends in performance monitoring is so valuable: it not only helps you understand the ups and downs, but it can help point you in the right direction.

Anyway, I’m not really trying to sell you on Sentry here. I’m more interested in how the field of front-end development is changing and I think it’s super exciting that all of these tools in the industry are coming together at this moment in time. It feels like our understanding of performance problems is getting better — the language, the tools, the techniques are all evolving and a tide is turning in our industry.

And that’s something to celebrate.

  1. Yes, I do work at Sentry but this is not a sponsored post. The topic of Core Web Vitals just so happens to be something I’m paying attention to and I had some follow-up thoughts after reading the post by Chris. ↩️

The post Measuring Core Web Vitals with Sentry appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Measuring Core Web Vitals with Sentry

Tue, 11/17/2020 - 12:13pm

Chris made a few notes about Core Web Vitals the other day, explaining why measuring these performance metrics are so gosh darn important:

I still think the Google-devised Core Web Vitals are smart. When I first got into caring about performance, it was all: reduce requests! cache things! Make stuff smaller! And while those are all very related to web performance, they are abstractly related. Actual web performance to users are things like how long did I have to wait to see the content on the page? How long until I can actually interact with the page, like type in a form or click a link? Did things obnoxiously jump around while I was trying to do something? That’s why Core Web Vitals are smart: they measure those things.

There’s certainly a lot of tools out there that help you measure these extremely important metrics. Chris’ post was timely because where I work at Sentry¹, we’re launching our own take on this. My favorite once-a-year-blogger and mentor at Sentry, Dora Chan, explained why using real user data is important when it comes to measuring Web Vitals and how our own product is approaching it:

Google Web Vitals can be viewed using the Google Chrome Lighthouse extension. You may be asking yourself, “Why would I need Sentry to see what these are if I already have Google?” Good question. Google provides synthetic lab data, where you can directly control your environment, device, and network speed. This is good and all, but it only paints part of the picture. Paint. Get it?

Sentry gathers aggregate field data on what your users actually experience when they engage with your application. This includes context on variable network speed, browser, device, region, and so forth. With Web Vitals, we can help you understand what’s happening in the wild, how frequently it’s happening, why, and what else is connected to the behavior.

Sentry breaks down all these transactions into the most important metrics so you can see how your customers are experiencing performance problems. Perhaps 42% of the time a transaction has an input delay of more than 301ms. Sentry would show that problem and how it correlates with other performance issues.

I think this is the power of tying Core Web Vitals with user data — or what Dora calls “field data” — because some of our users are experiencing a fast app! They have great wifi! All the wifis! That’s great and all, but there are still users on the other side who put up with a more miserable experience, and having a visual based on actual user data allows us to see which specific actions are slowing things down. This information is what gives us the confidence to hop into the codebase and then fix the problem, but it also helps prioritize these problems in the first place. That’s something we don’t really talk about when it comes to performance.

What’s the most important performance problem with your app right now? This is a trickier question than we might like to admit. Perhaps a First Paint of five seconds isn’t a dealbreaker on the settings page of your app but three seconds on the checkout page is unbearable for the business and customers alike.

So, yeah, performance problems are weird like that; the same result of a metric can mean different things based on the context. And some metrics are more important than others depending on that context.

That’s really why I’m so excited about all these tools. Viewing how users are experiencing an app in real time and then, subsequently, visualizing how the metrics change over time — that’s just magic. Lighthouse scores are fine and dandy, and, don’t get me wrong, they are very useful. They’re just not an extremely accurate measure of how users actually use your app based on your data.

This is where another Sentry feature comes into play. After you’ve signed up and configured everything, head to the Performance section and you’ll see which transactions are getting better over time and which have regressed, or gotten slower:

Tony Xiao is an engineer at Sentry and he wrote about how he used this feature to investigate a front-end problem. That’s right: we use Sentry to measure our Sentry work (whoa, inception). By looking at the Most Regressed Transactions report, Tony was able to dig into the specific transaction that triggered a negative result and identify the problem right then and there. Here’s how he described it:

To a fault, code is loyal to its author. It’s why communicating with your code is critical. And it’s why trends in performance monitoring is so valuable: it not only helps you understand the ups and downs, but it can help point you in the right direction.

Anyway, I’m not really trying to sell you on Sentry here. I’m more interested in how the field of front-end development is changing and I think it’s super exciting that all of these tools in the industry are coming together at this moment in time. It feels like our understanding of performance problems is getting better — the language, the tools, the techniques are all evolving and a tide is turning in our industry.

And that’s something to celebrate.

  1. Yes, I do work at Sentry but this is not a sponsored post. The topic of Core Web Vitals just so happens to be something I’m paying attention to and I had some follow-up thoughts after reading the post by Chris. ↩️

The post Measuring Core Web Vitals with Sentry appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Copyediting with Semantic HTML

Tue, 11/17/2020 - 5:56am

Tracking changes is a quintessential copyediting feature for comparing versions of content. While we’re used to tracking changes in a word processing document, we actually have HTML elements capable of that. There are a lot of elements that we can use for this process. The main ones we’ll look at are <del>, <ins> and <mark>. But, as we’ll see, pairing them with other elements — including <u>, <aside> and custom markup — we can get the same sort of visual tracking changes features as something like Word, Google Docs, or even WordPress.

Different apps have different ways of tracking changes.

Let’s start with the <ins> element.

The <ins> designates text that should be or has been inserted. The verb tense gets a little wonky here because while the <ins> tag is suggesting an edit, it has to have, by virtue of being in the <ins> tag, already been inserted. It’s sorta like saying, “Hey, insert this things that’s technically already there.”

CodePen Embed Fallback

Notice how the browser underlines the inserted text for us. It’s nice to have that sort of visual indication, even if it could be mistaken as an underline using the <u> element, a link, or the CSS text-decoration property.

Let’s pair the insertion with the <del> element, which suggests text that should be or has been deleted.

CodePen Embed Fallback

The browser styles <del> like a strikethrough (<s>) element, but they mean different things. <del> is for content that should be removed/edited out (like that creepy seeming section above) while <s> is for content that’s no longer true or inaccurate (like the letter writer’s belief that that section would be endearing).

OK, great, so we have these semantic HTML elements and they produce some light visual indicators for content that is either inserted or deleted. But there’s something you might not know about these elements: they accept a cite  attribute that can be used to annotate the change.

cite takes a properly formatted URL that provides points somewhere to find the reasons why the change was made. That somewhere could even be an anchor on the existing page.

CodePen Embed Fallback

That’s cool, but one issue is that the citation URL isn’t actually visible or clickable. We could use some CSS magic to display it. But even then, it still won’t take you to the citation when clicked… nor can it be copied. 

CodePen Embed Fallback

That said, it does make semantically clear what’s part of the edit and what is not. If we wrap <ins> and <del> in a link (or even the other way around) it still is not clear whether the link is supposed to be part of the edited content or not.

But! There’s a second attribute that <ins> and <del> both share: datetime. And this is how we can indicate when an edit was made. Again, this is not immediately available to a user, but it keeps semantically clear what is part of the edit and what isn’t. 

CodePen Embed Fallback

HTML’s datetime format, as a machine readable date and time, requires precision and can thus be a bit, well, cranky, But it’s general tenants aren’t too hard. It’s worth noting though that, while datetime is used on other elements, such as <time>, formatting the value in a way that doesn’t include at least a specific day, month, and year on <ins> and <del> would be problematic, obscuring the date and time of an edit rather than provide clarity.

We can make things clearer with a little more CSS magic. For example, we can reveal the datetime value on hover:

CodePen Embed Fallback

Checkboxes work too:

CodePen Embed Fallback

But good editing is far more than simply adding and deleting content. It’s asking questions and figuring out what the heck the author intended. (For me personally, it’s also about saving me from embarrassing spellling and grammar mistooks).

So, meet the <mark> element.

<mark> points out text of special interest to the reader. It usually renders as a yellow background behind the content. 

CodePen Embed Fallback

If you’re the editor and want to write a note to the writer (let’s name that person Stanley Meagher) with suggestions to make Stanly’s letter more awesome (or less creepy, at the very least) and that note is large enough to warrant flow content (i.e. block level elements), then the note can be an <aside> element.

<aside class="note">Mr. Meagher, I highly recommend you remove this list of preferred cheeses and replace it with things you love about the woman you are writing to. While I'm sure there are many people for whom your list would be interesting if not welcome, that list rarely includes a romantic interest in the midst of your profession of love. Though, honestly, if she is as perfect for you as you believe, it may be the exact thing you need to test that theory.</aside>

But often you’ll want to do something inline in order to point something out or make a comment about sentence structure or word choice. Unfortunately there’s no baked in way to do that in HTML, but with a little ingenuity and some CSS you can add a note.

<span class="note">Cheesecake isn't really a "cheese"</span>

The <u> element — long an anathema to web developers for fear of confusion with a link — does actually have a use (I know, I was surprised too). It can be used to point out a misspelling (apparently squiggly and red underlines aren’t a standard browser rendering feature). It should still not be used anywhere it might be confused with an actual link and, when used, it definitely should use a color that distinguishes it from links. Red color may be appropriate to indicate an error. 

<p>Please, <u>Lura</u> tell me your answer. Will you wear my mathlete letter jacket?</p>

As we’ve seen throughout this article, the browser’s default styles for the elements we’ve covered so far are certainly helpful but can also be confusing since they are barely distinguishable from other types of content. If a user does not know that the document is showing edits, then the styling may be misconstrued or misunderstood by the user. I’d therefore suggest some additional or alternate styles to help make it clear what’s going on.

ins {   padding: 0 0.125em;   text-decoration: none;   background-color: lightgreen } del {   padding: 0 0.125em;   text-decoration: none;   background-color: pink; } mark {   padding: 0 0.125em; } .note {   padding: 0 0.125em;   background-color: lightblue; } aside.note {   padding: 0.5em 1em; } u {   text-decoration: none;   border-bottom: 3px red dashed; } CodePen Embed Fallback

I ask myself the same question every time I learn something new in HTML: How can I needlessly animate this?

It would be great if we could fade up the changes so that when you clicked a checkbox the edits would fade in as well.

CodePen Embed Fallback

The notes and text in <del> tags can’t be faded in with CSS the same way that background colors and paddings can. Also, display: none  results in no fading at all. Everything pops back in place, including the backgrounds. But using a combining the CSS visibility property with a set height and width value of 0 allows the backgrounds to smoothly fade in.

And there you have it: specifications and a few strategies for keeping track of edits on the web (plus an excellent example of how not to write a love letter (or, perhaps, how to write one so perfect that responding positively to it is a sign you’re soulmates).

The post Copyediting with Semantic HTML appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Copyediting with Semantic HTML

Tue, 11/17/2020 - 5:56am

Tracking changes is a quintessential copyediting feature for comparing versions of content. While we’re used to tracking changes in a word processing document, we actually have HTML elements capable of that. There are a lot of elements that we can use for this process. The main ones we’ll look at are <del>, <ins> and <mark>. But, as we’ll see, pairing them with other elements — including <u>, <aside> and custom markup — we can get the same sort of visual tracking changes features as something like Word, Google Docs, or even WordPress.

Different apps have different ways of tracking changes.

Let’s start with the <ins> element.

The <ins> designates text that should be or has been inserted. The verb tense gets a little wonky here because while the <ins> tag is suggesting an edit, it has to have, by virtue of being in the <ins> tag, already been inserted. It’s sorta like saying, “Hey, insert this things that’s technically already there.”

CodePen Embed Fallback

Notice how the browser underlines the inserted text for us. It’s nice to have that sort of visual indication, even if it could be mistaken as an underline using the <u> element, a link, or the CSS text-decoration property.

Let’s pair the insertion with the <del> element, which suggests text that should be or has been deleted.

CodePen Embed Fallback

The browser styles <del> like a strikethrough (<s>) element, but they mean different things. <del> is for content that should be removed/edited out (like that creepy seeming section above) while <s> is for content that’s no longer true or inaccurate (like the letter writer’s belief that that section would be endearing).

OK, great, so we have these semantic HTML elements and they produce some light visual indicators for content that is either inserted or deleted. But there’s something you might not know about these elements: they accept a cite  attribute that can be used to annotate the change.

cite takes a properly formatted URL that provides points somewhere to find the reasons why the change was made. That somewhere could even be an anchor on the existing page.

CodePen Embed Fallback

That’s cool, but one issue is that the citation URL isn’t actually visible or clickable. We could use some CSS magic to display it. But even then, it still won’t take you to the citation when clicked… nor can it be copied. 

CodePen Embed Fallback

That said, it does make semantically clear what’s part of the edit and what is not. If we wrap <ins> and <del> in a link (or even the other way around) it still is not clear whether the link is supposed to be part of the edited content or not.

But! There’s a second attribute that <ins> and <del> both share: datetime. And this is how we can indicate when an edit was made. Again, this is not immediately available to a user, but it keeps semantically clear what is part of the edit and what isn’t. 

CodePen Embed Fallback

HTML’s datetime format, as a machine readable date and time, requires precision and can thus be a bit, well, cranky, But it’s general tenants aren’t too hard. It’s worth noting though that, while datetime is used on other elements, such as <time>, formatting the value in a way that doesn’t include at least a specific day, month, and year on <ins> and <del> would be problematic, obscuring the date and time of an edit rather than provide clarity.

We can make things clearer with a little more CSS magic. For example, we can reveal the datetime value on hover:

CodePen Embed Fallback

Checkboxes work too:

CodePen Embed Fallback

But good editing is far more than simply adding and deleting content. It’s asking questions and figuring out what the heck the author intended. (For me personally, it’s also about saving me from embarrassing spellling and grammar mistooks).

So, meet the <mark> element.

<mark> points out text of special interest to the reader. It usually renders as a yellow background behind the content. 

CodePen Embed Fallback

If you’re the editor and want to write a note to the writer (let’s name that person Stanley Meagher) with suggestions to make Stanly’s letter more awesome (or less creepy, at the very least) and that note is large enough to warrant flow content (i.e. block level elements), then the note can be an <aside> element.

<aside class="note">Mr. Meagher, I highly recommend you remove this list of preferred cheeses and replace it with things you love about the woman you are writing to. While I'm sure there are many people for whom your list would be interesting if not welcome, that list rarely includes a romantic interest in the midst of your profession of love. Though, honestly, if she is as perfect for you as you believe, it may be the exact thing you need to test that theory.</aside>

But often you’ll want to do something inline in order to point something out or make a comment about sentence structure or word choice. Unfortunately there’s no baked in way to do that in HTML, but with a little ingenuity and some CSS you can add a note.

<span class="note">Cheesecake isn't really a "cheese"</span>

The <u> element — long an anathema to web developers for fear of confusion with a link — does actually have a use (I know, I was surprised too). It can be used to point out a misspelling (apparently squiggly and red underlines aren’t a standard browser rendering feature). It should still not be used anywhere it might be confused with an actual link and, when used, it definitely should use a color that distinguishes it from links. Red color may be appropriate to indicate an error. 

<p>Please, <u>Lura</u> tell me your answer. Will you wear my mathlete letter jacket?</p>

As we’ve seen throughout this article, the browser’s default styles for the elements we’ve covered so far are certainly helpful but can also be confusing since they are barely distinguishable from other types of content. If a user does not know that the document is showing edits, then the styling may be misconstrued or misunderstood by the user. I’d therefore suggest some additional or alternate styles to help make it clear what’s going on.

ins {   padding: 0 0.125em;   text-decoration: none;   background-color: lightgreen } del {   padding: 0 0.125em;   text-decoration: none;   background-color: pink; } mark {   padding: 0 0.125em; } .note {   padding: 0 0.125em;   background-color: lightblue; } aside.note {   padding: 0.5em 1em; } u {   text-decoration: none;   border-bottom: 3px red dashed; } CodePen Embed Fallback

I ask myself the same question every time I learn something new in HTML: How can I needlessly animate this?

It would be great if we could fade up the changes so that when you clicked a checkbox the edits would fade in as well.

CodePen Embed Fallback

The notes and text in <del> tags can’t be faded in with CSS the same way that background colors and paddings can. Also, display: none  results in no fading at all. Everything pops back in place, including the backgrounds. But using a combining the CSS visibility property with a set height and width value of 0 allows the backgrounds to smoothly fade in.

And there you have it: specifications and a few strategies for keeping track of edits on the web (plus an excellent example of how not to write a love letter (or, perhaps, how to write one so perfect that responding positively to it is a sign you’re soulmates).

The post Copyediting with Semantic HTML appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Copyediting with Semantic HTML

Tue, 11/17/2020 - 5:56am

Tracking changes is a quintessential copyediting feature for comparing versions of content. While we’re used to tracking changes in a word processing document, we actually have HTML elements capable of that. There are a lot of elements that we can use for this process. The main ones we’ll look at are <del>, <ins> and <mark>. But, as we’ll see, pairing them with other elements — including <u>, <aside> and custom markup — we can get the same sort of visual tracking changes features as something like Word, Google Docs, or even WordPress.

Different apps have different ways of tracking changes.

Let’s start with the <ins> element.

The <ins> designates text that should be or has been inserted. The verb tense gets a little wonky here because while the <ins> tag is suggesting an edit, it has to have, by virtue of being in the <ins> tag, already been inserted. It’s sorta like saying, “Hey, insert this things that’s technically already there.”

CodePen Embed Fallback

Notice how the browser underlines the inserted text for us. It’s nice to have that sort of visual indication, even if it could be mistaken as an underline using the <u> element, a link, or the CSS text-decoration property.

Let’s pair the insertion with the <del> element, which suggests text that should be or has been deleted.

CodePen Embed Fallback

The browser styles <del> like a strikethrough (<s>) element, but they mean different things. <del> is for content that should be removed/edited out (like that creepy seeming section above) while <s> is for content that’s no longer true or inaccurate (like the letter writer’s belief that that section would be endearing).

OK, great, so we have these semantic HTML elements and they produce some light visual indicators for content that is either inserted or deleted. But there’s something you might not know about these elements: they accept a cite  attribute that can be used to annotate the change.

cite takes a properly formatted URL that provides points somewhere to find the reasons why the change was made. That somewhere could even be an anchor on the existing page.

CodePen Embed Fallback

That’s cool, but one issue is that the citation URL isn’t actually visible or clickable. We could use some CSS magic to display it. But even then, it still won’t take you to the citation when clicked… nor can it be copied. 

CodePen Embed Fallback

That said, it does make semantically clear what’s part of the edit and what is not. If we wrap <ins> and <del> in a link (or even the other way around) it still is not clear whether the link is supposed to be part of the edited content or not.

But! There’s a second attribute that <ins> and <del> both share: datetime. And this is how we can indicate when an edit was made. Again, this is not immediately available to a user, but it keeps semantically clear what is part of the edit and what isn’t. 

CodePen Embed Fallback

HTML’s datetime format, as a machine readable date and time, requires precision and can thus be a bit, well, cranky, But it’s general tenants aren’t too hard. It’s worth noting though that, while datetime is used on other elements, such as <time>, formatting the value in a way that doesn’t include at least a specific day, month, and year on <ins> and <del> would be problematic, obscuring the date and time of an edit rather than provide clarity.

We can make things clearer with a little more CSS magic. For example, we can reveal the datetime value on hover:

CodePen Embed Fallback

Checkboxes work too:

CodePen Embed Fallback

But good editing is far more than simply adding and deleting content. It’s asking questions and figuring out what the heck the author intended. (For me personally, it’s also about saving me from embarrassing spellling and grammar mistooks).

So, meet the <mark> element.

<mark> points out text of special interest to the reader. It usually renders as a yellow background behind the content. 

CodePen Embed Fallback

If you’re the editor and want to write a note to the writer (let’s name that person Stanley Meagher) with suggestions to make Stanly’s letter more awesome (or less creepy, at the very least) and that note is large enough to warrant flow content (i.e. block level elements), then the note can be an <aside> element.

<aside class="note">Mr. Meagher, I highly recommend you remove this list of preferred cheeses and replace it with things you love about the woman you are writing to. While I'm sure there are many people for whom your list would be interesting if not welcome, that list rarely includes a romantic interest in the midst of your profession of love. Though, honestly, if she is as perfect for you as you believe, it may be the exact thing you need to test that theory.</aside>

But often you’ll want to do something inline in order to point something out or make a comment about sentence structure or word choice. Unfortunately there’s no baked in way to do that in HTML, but with a little ingenuity and some CSS you can add a note.

<span class="note">Cheesecake isn't really a "cheese"</span>

The <u> element — long an anathema to web developers for fear of confusion with a link — does actually have a use (I know, I was surprised too). It can be used to point out a misspelling (apparently squiggly and red underlines aren’t a standard browser rendering feature). It should still not be used anywhere it might be confused with an actual link and, when used, it definitely should use a color that distinguishes it from links. Red color may be appropriate to indicate an error. 

<p>Please, <u>Lura</u> tell me your answer. Will you wear my mathlete letter jacket?</p>

As we’ve seen throughout this article, the browser’s default styles for the elements we’ve covered so far are certainly helpful but can also be confusing since they are barely distinguishable from other types of content. If a user does not know that the document is showing edits, then the styling may be misconstrued or misunderstood by the user. I’d therefore suggest some additional or alternate styles to help make it clear what’s going on.

ins {   padding: 0 0.125em;   text-decoration: none;   background-color: lightgreen } del {   padding: 0 0.125em;   text-decoration: none;   background-color: pink; } mark {   padding: 0 0.125em; } .note {   padding: 0 0.125em;   background-color: lightblue; } aside.note {   padding: 0.5em 1em; } u {   text-decoration: none;   border-bottom: 3px red dashed; } CodePen Embed Fallback

I ask myself the same question every time I learn something new in HTML: How can I needlessly animate this?

It would be great if we could fade up the changes so that when you clicked a checkbox the edits would fade in as well.

CodePen Embed Fallback

The notes and text in <del> tags can’t be faded in with CSS the same way that background colors and paddings can. Also, display: none  results in no fading at all. Everything pops back in place, including the backgrounds. But using a combining the CSS visibility property with a set height and width value of 0 allows the backgrounds to smoothly fade in.

And there you have it: specifications and a few strategies for keeping track of edits on the web (plus an excellent example of how not to write a love letter (or, perhaps, how to write one so perfect that responding positively to it is a sign you’re soulmates).

Edit: Adrian Roselli adds some excellent accessibility information in the comments. Before you implement these ideas in production, be sure to consider those suggestions.

The post Copyediting with Semantic HTML appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Jetpack Backup

Tue, 11/17/2020 - 5:54am

It’s no secret that CSS-Tricks is a WordPress site. And as such, we like to keep things WordPress-y, like enabling the block editor and creating some custom blocks. We also rely on Jetpack for a number of things, which if you haven’t tried, is definitely worth your time as it’s become a linchpin of this site for everything from search and security scans to social integrations and it’s own set of awesome blocks, like the slideshow block.

But one powerful feature we haven’t talked much about is Jetpack Backup and whoo-boy is it awesome. Sure, code is pretty easy to back up — we’ve got GitHub for that. But what about your assets, like images and other files? Or, gosh, what about the database? These things are super important and losing them would be, well, devastating!

Enter Jetpack Backup. It copies all that stuff, offering two plans, including one for daily backups and the other for real-time backups. Most sites can probably get away with daily backups, but it’s nice to know there’s a real-time option, especially if you’re running an active site, like forums where updates happen regularly, or some eCommerce shop where restoring lost orders would be crucial.

Another thing that makes Jetpack Backup great: it’s sold à la carte. So if backups are all you want from Jetpack, then you can get just that and that alone. But if you need additional features, like all the ones we use around here, then they’re easily accessible and enabled with a few clicks.

You even get a little activity log which is nice to not just see what’s happening on your site, but because it’s another way to pinpoint where things might have gone wrong.

Ugh, Geoff screwing everything up as per usual. &#x1f61d;

So, yeah, check it out! If you want a deep dive into how it all works, here’s Chris walking through our setup.

Get Jetpack Backup

The post Jetpack Backup appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Jetpack Backup

Tue, 11/17/2020 - 5:54am

It’s no secret that CSS-Tricks is a WordPress site. And as such, we like to keep things WordPress-y, like enabling the block editor and creating some custom blocks. We also rely on Jetpack for a number of things, which if you haven’t tried, is definitely worth your time as it’s become a linchpin of this site for everything from search and security scans to social integrations and it’s own set of awesome blocks, like the slideshow block.

But one powerful feature we haven’t talked much about is Jetpack Backup and whoo-boy is it awesome. Sure, code is pretty easy to back up — we’ve got GitHub for that. But what about your assets, like images and other files? Or, gosh, what about the database? These things are super important and losing them would be, well, devastating!

Enter Jetpack Backup. It copies all that stuff, offering two plans, including one for daily backups and the other for real-time backups. Most sites can probably get away with daily backups, but it’s nice to know there’s a real-time option, especially if you’re running an active site, like forums where updates happen regularly, or some eCommerce shop where restoring lost orders would be crucial.

Another thing that makes Jetpack Backup great: it’s sold à la carte. So if backups are all you want from Jetpack, then you can get just that and that alone. But if you need additional features, like all the ones we use around here, then they’re easily accessible and enabled with a few clicks.

You even get a little activity log which is nice to not just see what’s happening on your site, but because it’s another way to pinpoint where things might have gone wrong.

Ugh, Geoff screwing everything up as per usual. &#x1f61d;

So, yeah, check it out! If you want a deep dive into how it all works, here’s Chris walking through our setup.

Get Jetpack Backup

The post Jetpack Backup appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

A Complete Guide to CSS Gradients

Mon, 11/16/2020 - 1:40pm

The background-size property in CSS is one of the most useful — and most complex — of the background properties. There are many variations and different syntaxes you can use for this property, all of which have different use cases. Here’s a basic example:

html { background: url(greatimage.jpg); background-size: 300px 100px; }

That’s an example of the two-value syntax for background size. There are four different syntaxes you can use with this property: the keyword syntax, the one-value syntax, the two-value syntax, and the multiple background syntax.

Keywords

In addition to the default value (auto), there are two keywords you can use with background-size: cover and contain

The difference

cover tells the browser to make sure the image always covers the entire container, even if it has to stretch the image or cut a little bit off one of the edges. contain, on the other hand, says to always show the whole image, even if that leaves a little space to the sides or bottom.

The default keyword — auto — tells the browser to automatically calculate the size based on the actual size of the image and the aspect ratio.

One Value

If you only provide one value (e.g. background-size: 400px) it counts for the width, and the height is set to auto. You can use any CSS size units you like, including pixels, percentages, ems, viewport units, etc.

Two Values

If you provide two values, the first sets the background image’s width and the second sets the height. Like the single value syntax, you can use whatever measurement units you like.

Multiple Images

You can also combine any of the above methods and apply them to multiple images, simply by adding commas between each syntax. Example:

html { background: url(greatimage.jpg), url(wonderfulimage.jpg); background-size: 300px 100px, cover; /* first image is 300x100, second image covers the whole area */ }

Keep background image stacking order in mind when using multiple images.

Demo

This demo shows examples of cover, contain, and multiple background images with a mix of pixel and keyword values.

See the Pen background-size by CSS-Tricks (@css-tricks) on CodePen.

Related More Resources Browser Support Chrome Safari Firefox Opera IE Android iOS 3+ 4.1+ 3.6+ 10+ 9+ 2.3+ 4.0+

The post A Complete Guide to CSS Gradients appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

©2003 - Present Akamai Design & Development.