Category: Design

Amplify, Amplified

First, quickly: AWS Amplify has a new Admin UI. Amplify always had a CLI that helps you build projects by setting up stuff like auth, storage, and APIs. That’s super useful, but now, you can do those things with the new Admin UI. And more, like model your data (!!), right from a local UI. That’s great for people like… me (I like my GUIs).

Now, slower.

Let’s start with the idea of Jamstack. Static Hosting + Services, right? Amplify is that: static hosting is part of the offering. You connect an Amplify project with a Git repo (you don’t have to, you could upload a zip, but let’s be real here). When you push to the designated branch on that repo (probably main or master), it deploys. That’s part of the magic of development today that we all know and love expect.

Static hosting might be all you need. Done.

But a lot of sites need more. Maybe your site is client-side rendered (for some of it), so the JavaScript hits an API for data and then renders. What data? What API? AWS has these things for you. For us front-enders, that’s probably AWS AppSync, which is like real-time GraphQL (cool). How do you set that up? Well, you can do it in the CLI, but it’s now way easier with the Amplify Admin UI.

Say you’re building a blog structure. Blogs have Posts, Posts have Comments. And so:

I’ll tell ya, coming from a WordPress upbringing and identifying mostly as a front-end developer, this feels doable to me. It’s not far from using Advanced Custom Fields in WordPress to model some data for a Custom Post Type. No wonder the line is so gray between front-end and back-end development.

Now that the Amplify Admin UI has this data modeled out, I can yank it down into my project and the whole schema is mocked out.

I’m bullish on GraphQL, but I can tell ya, all the setup of it is generally over my head. I’m generally very happy just being a consumer of a GraphQL API that is already set up, or doing minor tweaks. This, though, feels doable for me. The visual builder and the freebie scaffolding of the schema… yes please.

At this point then you have this project you can test and deploy. Once it’s deployed, there is a real data store in the cloud ready for data. How do you use it? It’s CRUD time! Create, Replicate, Update, and Delete, the core tenants of all good websites, right? Well, It’s Just JavaScript™. Here’s how you create a new blog, then a post in that blog:

import { DataStore } from '@aws-amplify/datastore'; import { Blog } from './models';  const newBlog = await  new Blog({    "name": "Name of Blog"  }) );  await  new Post({    "title": "Blog Post Title",    "blogID":  }) ); 

That all works because the database exists and our app knows all about the data model. But what is DataStore in AWS Amplify? That’s yet another thing that AWS Amplify helps with. They have libraries to make all this easier. You don’t have to manually write fetch calls and do error handling and all that… Amplify libraries make life easier with all sorts of helpers (like you see above).

With all that setup, this slide I saw in their developer preview I got a peak at should make sense

AWS Amplify: Getting it Done

Back to the Jamstack thing… now we’ve got Static Hosting going and we can deploy our website to it. By the way, that can be anything. A vanilla HTML/CSS/JavaScript thing. A React, Vue, or Angular app. Native apps too. Amplify doesn’t care, it just helps with the deployment and services.

Here’s a look at the Admin UI, where you can see the navigation with all the services you can set up, deployment activity, the ability to model (and edit) data, etc.:

What else is in there? With auth for one. If you’re storing data and managing it with API’s, it’s highly likely you’ll be dealing with authentication as well. Amplify has you covered. Need some to run some code server-side? You’ve got your functions right in there of course. Lambdas (serverless functions) are AWS bread and butter. Analytics? You bet.

Another thing you’ll surely be interested in is the different development stories. Like what is local development like? Well, it’s super good. Guess what?! Those screenshots above of the Admin UI… those aren’t some online dashboard in the AWS console, those are locally hosted on your own site. All this data modeling and storage and editing and such happens locally. Then you can push to live to any environment. Production, of course, but also whatever sort of staging environments you need.

When you need production data pulled down locally, you just… do that (with a command given to you right in the Admin UI).

You can join the Amplify team to find out more – they’ll be demoing on Twitch with Q&A this week:

Thursday,  Dec. 3rd at 10-11am PST/ 7pm GMT
Friday,  Dec. 4th at 1-3pm PST / 9pm GMT

I’m thinking this new Admin UI world is going to open up AWS Amplify to a lot more people. Having a UI to manage your site just feels better. For someone like me, it gives me a more complete understanding of what is going on with the backend and services, and more control over things. And yet, give me total freedom on the front end to do what I want to do, and also handle so many of the things I don’t (deployment, SSL, etc.) 👏

The post Amplify, Amplified appeared first on CSS-Tricks.

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



How to Make an Area Chart With CSS

You might know a few ways to create charts with pure CSS. Some of them are covered here on CSS-Tricks, and many others can be found on CodePen, but I haven’t seen many examples of “area charts” (imagine a line chart with the bottom area filled in), particularly any in HTML and CSS alone. In this article, we’ll do just that, using a semantic and accessible HTML foundation.

A red area chart against a dark gray background.

Let’s start with the HTML

To simplify things, we will be using <ul> tags as wrappers and <li> elements for individual data items. You can use any other HTML tag in your project, depending on your needs.

<ul class="area-chart">   <li> 40% </li>   <li> 80% </li>   <li> 60% </li>   <li> 100% </li>   <li> 30% </li> </li>

CSS can’t retrieve the inner HTML text, that is why we will be using CSS custom properties to pass data to our CSS. Each data item will have a --start and an --end custom properties.

<ul class="area-chart">   <li style="--start: 0.1; --end: 0.4;"> 40% </li>   <li style="--start: 0.4; --end: 0.8;"> 80% </li>   <li style="--start: 0.8; --end: 0.6;"> 60% </li>   <li style="--start: 0.6; --end: 1.0;"> 100% </li>   <li style="--start: 1.0; --end: 0.3;"> 30% </li> </li>

Here’s what we need to consider…

There are several design principles we ought to consider before moving into styling:

  • Units data: We will be using unit-less data in our HTML (i.e. no px, em , rem , % or any other unit). The --start and --end custom properties will be numbers between 0 and 1.
  • Columns width: We won’t set a fixed width for each <li> element. We won’t be using % either, as we don’t know how many items are there. Each column width will be based on the main wrapper width, divided by the total number of data items. In our case, that’s the width of the <ul> element divided by the number of <li> elements.
  • Accessibility: The values inside each <li> is optional and only the --start and --end custom properties are required. Still, it’s best to include some sort of text or value for screen readers and other assistive technologies to describe the content.

Now, let’s start styling!

Let’s start with general layout styling first. The chart wrapper element is a flex container, displaying items in a row, stretching each child element so the entire area is filled.

.area-chart {   /* Reset */   margin: 0;   padding: 0;   border: 0;    /* Dimensions */   width: 100%;   max-width: var(--chart-width, 100%);   height: var(--chart-height, 300px);    /* Layout */   display: flex;   justify-content: stretch;   align-items: stretch;   flex-direction: row; }

If the area chart wrapper is a list, we should remove the list style to give us more styling flexibility.

ul.area-chart, ol.area-chart {   list-style: none; }

This code styles all of the columns in the entire chart. With bar charts it’s simple: we use background-color and height for each column. With area charts we are going to use the clip-path property to set the region that should be shown.

First we set up each column:

.area-chart > * {   /* Even size items */   flex-grow: 1;   flex-shrink: 1;   flex-basis: 0;    /* Color */   background: var(--color, rgba(240, 50, 50, .75)); }

To create a rectangle covering the entire area, we will reach for the clip-path property and use its polygon() function containing the coordinates of the area. This basically doesn’t do anything at the moment because the polygon covers everything:

.area-chart > * {   clip-path: polygon(     0% 0%,     /* top left */     100% 0%,   /* top right */     100% 100%, /* bottom right */     0% 100%    /* bottom left */   ); }

Now for the best part!

To show just part of the column, we clip it to create that area chart-like effect. To show just the area we want, we use the --start and --end custom properties inside the clip-path polygon:

.area-chart > * {   clip-path: polygon(     0% calc(100% * (1 - var(--start))),     100% calc(100% * (1 - var(--size))),     100% 100%,     0% 100%   ); }

Seriously, this one bit of CSS does all of the work. Here’s what we get:

Working with multiple datasets

Now that we know the basics, let’s create an area chart with multiple datasets. Area charts often measure more than one set of data and the effect is a layered comparison of the data.

This kind of chart requires several child elements, so we are going to replace our <ul> approach with a <table>.

<table class="area-chart">   <tbody>     <tr>       <td> 40% </td>       <td> 80% </td>     </tr>     <tr>       <td> 60% </td>       <td> 100% </td>     </tr>   </tbody> </table>

Tables are accessible and search engine friendly. And if the stylesheet doesn’t load for some reason, all the data is still visible in the markup.

Again, we will use the --start and --end custom properties with numbers between 0 and 1.

<table class="area-chart">   <tbody>     <tr>       <td style="--start: 0; --end: 0.4;"> 40% </td>       <td style="--start: 0; --end: 0.8;"> 80% </td>     </tr>     <tr>       <td style="--start: 0.4; --end: 0.6;"> 60% </td>       <td style="--start: 0.8; --end: 1.0;"> 100% </td>     </tr>   </tbody> </table>

So, first we will style the general layout for the wrapping element, our table, which we’ve given an .area-chart class:

.area-chart {   /* Reset */   margin: 0;   padding: 0;   border: 0;    /* Dimensions */   width: 100%;   max-width: var(--chart-width, 600px);   height: var(--chart-height, 300px); } 

Next, we will make the <tbody> element a flex container, displaying the <tr> items in a row and evenly sized:

.area-chart tbody {   width: 100%;   height: 100%;    /* Layout */   display: flex;   justify-content: stretch;   align-items: stretch;   flex-direction: row; } .area-chart tr {   /* Even size items */   flex-grow: 1;   flex-shrink: 1;   flex-basis: 0; }

Now we need to make the <td> elements cover each other, one element on top of each other so we get that layered effect. Each <td> covers the entire area of the <tr> element that contains it.

.area-chart tr {   position: relative; } .area-chart td {   position: absolute;   top: 0;   right: 0;   bottom: 0;   left: 0; }

Let’s put the magical powers of clip-path: polygon() to use! We’re only displaying the area between the --start and --end custom properties which, again, are values between 0 and 1:

.area-chart td {   clip-path: polygon(     0% calc(100% * (1 - var(--start))),     100% calc(100% * (1 - var(--end))),     100% 100%,     0% 100%   ); }

Now let’s add color to each one:

.area-chart td {   background: var(--color); } .area-chart td:nth-of-type(1) {   --color: rgba(240, 50, 50, 0.75); } .area-chart td:nth-of-type(2) {   --color: rgba(255, 180, 50, 0.75); } .area-chart td:nth-of-type(3) {   --color: rgba(255, 220, 90, 0.75); }

It’s important to use colors with opacity to get a nicer effect, which is why we’re using rgba() values. You could use hsla() here instead, if that’s how you roll.

And, just like that:

Wrapping up

It doesn’t matter how many HTML elements we add to our chart, the flex-based layout makes sure all the items are equally sized. This way, we only need to set the width of the wrapping chart element and the items will adjust accordingly for a responsive layout.

We have covered one technique to create area charts using pure CSS. For advanced use cases, you can check out my new open source data visualization framework, See the Area Chart section to see how area charts can be customized with things like different orientations, axes, and even a reversed order without changing the HTML markup, and much more!

The post How to Make an Area Chart With CSS appeared first on CSS-Tricks.

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



Painting With the Web

Matthias Ott, comparing how painter Gerhard Richter paints (do stuff, step back, take a look) to what can be the website building process and what can wreck it:

[…] this reminds me of designing and building for the Web: The unpredictability, the peculiarities of the material, the improvisation, the bugs, the happy accidents. There is one crucial difference, though. By using static wireframes and static layouts, by separating design and development, we are often limiting our ability to have that creative dialogue with the Web and its materials.

Love that. I’ve long thought that translating a mockup directly to code, while fun in its own way, is a left-brained task and doesn’t encourage as much creativity as either playing around in a design tool or playing around in the code while you build without something specific in mind as you do it. You don’t just, like, entirely re-position things and make big bold changes as much when your brain is in that mode of making something you see in one place (a mockup) manifest itself in another place (the code).

Direct Link to ArticlePermalink

The post Painting With the Web appeared first on CSS-Tricks.

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



A Microsite Showcasing Coding Fonts

We made one! It’s open source if you want to make it better or fix things.

There are quite a few purpose-built fonts for writing code. The point of this site is to show you some of the nicest options so you can be aware of them and perhaps pick one out to try that suites your taste.

We used screenshots of the code to display just so we could show off some of the paid fonts without managing a license just for this site, and for fonts without a clear way to link them up (like San. Also because setting up the screenshotting process was kinda fun.

High Fives

Special high five to Jonathan Land who helped a ton getting the site together including literally all the design work. Also to Sendil Kumar who had the original idea for a blog post like this, before the idea grew up into a full blown microsite. And finally to all the contributors so far.


There are still more fonts to add. If you want to add one, feel free to make a PR. Or if you’re unsure if it will be accepted or not, open an issue first. I’d like to keep any of the fonts we add fairly high quality. There is also a current bug with some of the ligatures not showing properly in the screenshots of some of the fonts. I’m sure we’ll sort it out eventually, but I’d love an assist there if you are particularly knowledgeable in that area.

Open issues here.

The post A Microsite Showcasing Coding Fonts appeared first on CSS-Tricks.

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


, , ,

Under-Engineered Responsive Tables

I first blogged about responsive data tables in 2011. When responsive web design was first becoming a thing, there were little hurdles like data tables that had to be jumped. The nature of <table> elements are that they have something a minimum width depending on the content they contain and that can easily exceed the width of a small screen device.

This image I made then still covers the issue pretty well:

Except… maybe they don’t equally suck. If that image on the left were scrollable, then maybe that’s actually… not so bad. In fact, that’s what I’ve done right here on CSS-Tricks recently. I think it’s the safest way of handling responsive tables when you have no idea what content the table contains. That’s the case here, where I need to set up base table styles that apply to any blog post which may contain a table.

The crux of the idea of a scrollable table is to wrap it in a <div> that has overflow: auto; on it. That way the <table> inside is free to exceed the width of the parent, but it won’t “blow out the width” and instead triggers a scrollbar. This isn’t quite enough though, so here’s Adrian Roselli with the real scoop. The wrapping <div> needs to be focusable and labelled, so:

<div role="region" aria-labelledby="Caption01" tabindex="0">   <table>     <caption id="Caption01">Appropriate caption</caption>     <!-- ...  -->   </table> </div>

Then apply the scrolling and focus styles, in the condition you’ve done everything else right:

[role="region"][aria-labelledby][tabindex] {   overflow: auto; }  [role="region"][aria-labelledby][tabindex]:focus {   outline: .1em solid rgba(0,0,0,.1); }

If you’re going to further engineer responsive tables, there are all sorts of options. One of the classics is to display: block a lot of the elements, meaning that all the data in a row (<tr>) ends up as a chunk of stacked content together that stands less of a chance of breaking the parent element’s width. You can get all the data labels properly with pseudo-elements. But, this only makes sense when individual rows of content make perfect sense alone. That’s not the case with every table. A table’s purpose might be cross-referencing data, and in that case, you’ve ruined that with this approach. So again, there are nice approaches for responsive tables when you know exactly the content and purpose of the table. But the best responsive solution when you don’t know is to just make sure they are swipeable.

Direct Link to ArticlePermalink

The post Under-Engineered Responsive Tables appeared first on CSS-Tricks.

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


, ,

How to Add Text in Borders Using Basic HTML Elements

Some HTML elements come with preset designs, like the inconveniently small squares of <input type="checkbox"> elements, the limited-color bars of <meter> elements, and the “something about them bothers me” arrows of the <details> elements. We can style them to match the modern aesthetics of our websites while making use of their functionalities. There are also many elements that rarely get used as both their default appearance and functionality are less needed in modern web designs.

One such HTML element is <fieldset>, along with its child element <legend>.

A <fieldset> element is traditionally used to group and access form controls. We can visually notice the grouping by the presence of a border around the grouped content on the screen. The caption for this group is given inside the <legend> element that’s added as the first child of the <fieldset>.

This combination of <fieldset> and <legend> creates a unique ready-made “text in border” design where the caption is placed right where the border is and the line of the border doesn’t go through the text. The border line “breaks” when it encounters the beginning of the caption text and resumes after the text ends.

In this post, we’ll make use of the <fieldset> and <legend> combo to create a more modern border text design that’s quick and easy to code and update.

For the four borders, we need four <fieldset> elements, each containing a <legend> element inside. We add the text that will appear at the borders inside the <legend> elements.

<fieldset><legend>Wash Your Hands</legend></fieldset> <fieldset><legend>Stay Apart</legend></fieldset> <fieldset><legend>Wear A Mask</legend></fieldset> <fieldset><legend>Stay Home</legend></fieldset>

To begin, we stack the <fieldset> elements on top of each other in a grid cell and give them borders. You can stack them using any way you want — it doesn’t necessarily have to be a grid.

Only the top border of each <fieldset> element is kept visible while the remaining edges are transparent since the text of the <legend> element appears at the top border of the <fieldset> by default.

Also, we give all the <fieldset> elements a box-sizing property with a value of border-box so the width and height of the <fieldset> elements include their border and padding sizes too. Doing this later creates a leveled design, when we style the <legend> elements.

body {   display: grid;    margin: auto; /* to center */   margin-top: calc(50vh - 170px); /* to center */   width: 300px; height: 300px;  }  fieldset {   border: 10px solid transparent;    border-top-color: black;    box-sizing: border-box;    grid-area: 1 / 1; /* first row, first column */   padding: 20px;    width: inherit;  }

After this, we rotate the last three <fieldset> elements in order to use their top borders as the side and bottom borders of our design.

/* rotate to right */ fieldset:nth-of-type(2){ transform: rotate(90deg); } /* rotate to bottom */ fieldset:nth-of-type(3){ transform: rotate(180deg); } /* rotate to left */ fieldset:nth-of-type(4){ transform: rotate(-90deg); }

Next up is styling the <legend> elements. The key to create smooth border text using a <legend> element is to give it a zero (or small enough) line-height. If it has a large line height, that will displace the position of the border it’s in, pushing the border down. And when the border moves with the line height, we won’t be able to connect all the four sides of our design and will need to readjust the borders.

legend {   font: 15pt/0 'Averia Serif Libre';    margin: auto; /* to center */   padding: 0 4px;  }  fieldset:nth-of-type(3) > legend {    transform: rotate(180deg); }

I used the font shorthand property to give the values for the font-size, line-height and font-family properties of the <legend> elements.

The <legend> element that adds the text at the bottom border of our design, fieldset:nth-of-type(3)>legend, is upside-down because of its rotated <fieldset> parent element. Flip that <legend> element vertically to show its text right-side-up.

Add an image to the first <fieldset> element and you get something like this:

Lateral margins can move the text along the border. Left and right margins with auto values will center the text, as seen in the above Pen. Only the left margin with an auto value will flush the text to the right, and vice versa, for the right margin.

Bonus: After a brief geometrical detour, here’s an octagonal design I made using the same technique:

The post How to Add Text in Borders Using Basic HTML Elements appeared first on CSS-Tricks.

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


, , , , ,

Design Deals For The Week


Native CSS Masonry Layout In CSS Grid

Rachel Andrew introducing the fact that masonry layout is going to be a thing in native CSS via CSS grid layout. The thing with masonry is that we can already do it for the most part, but there is just one thing that makes it hard: doing the vertical-staggering and having a left-to-right source order. So that’s what this new ability will solve in addition to it just being less hacky in general.

You can already test a partial implementation in Firefox Nightly by enabling layout.css.grid-template-masonry-value.enabled.

.container {   display: grid;   grid-template-columns: repeat(4, 1fr);   grid-template-rows: masonry; }

I like the grid-template-rows: masonry; syntax because I think it clearly communicates: “You aren’t setting these rows. In fact, there aren’t even really rows at all anymore, we’ll take care of that.” Which I guess means there are now rows to inherit in subgrid, which also makes sense.

The post Native CSS Masonry Layout In CSS Grid appeared first on CSS-Tricks.

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


, , ,

Super Tiny Icons

, ,

Lots of Ways to Use Math.random() in JavaScript

Math.random() is an API in JavaScript. It is a function that gives you a random number. The number returned will be between 0 (inclusive, as in, it’s possible for an actual 0 to be returned) and 1 (exclusive, as in, it’s not possible for an actual 1 to be returned).

Math.random(); // returns a random number lower than 1

This is incredibly useful for gaming, animations, randomized data, generative art, random text generation, and more! It can be used for web development, mobile applications, computer programs, and video games.

Whenever we need randomization in our work, we can use this function! Let’s look at eight different ways we can use it. These examples are all from different authors doing something interesting with this API.


To spawn an object and animate it, we use Math.random. The neon lines form spontaneous hexagons but randomization is also in its generative sparks. 

Computer-generated music

This program takes the traditional melody of “Auld Lang Syne” and plays random notes from it in piano. A change package is created from the count data and a random number is generated to select a value. The octave is also randomly selected.

Display a random image

Images are stored in an array. A number is generated and multiplied by the number of images in the array via array.length. Then Math.floor rounds the value to a round number and sets the image src in the HTML when the page is loaded or the button is clicked.

Random background color

This is where the magic happens:

const random = (min, max) => {   return Math.floor(Math.random() * (max - min + 1)) + min; }

The first line of code randomly shuffles the array and the second line returns a random umber between 0 and 10. In the example of a random color background, the range of colors and specifics such as hues, saturations, and shades can be set. 

For another method for generating a random hex color, check out this article by Chris Coyer. 

Generative art

In this morphing fractal curve, Math.random is used twice to set the colors for the gradient and once more for the max radius of the curves. This is a great way to construct an entirely new appearance with every iteration!

Word generator 

We replace the header with a randomly selected word from an array using Math.random:

var word = words[Math.floor(Math.random() * words.length)] + "!";

This is a lot like the random image example — the perfect sort of practice for beginners! 

API key generator

Here’s a super real-world practical use case for random numbers! The demo generates 16 random numbers to create a universally unique identifier (UUID) that can be used as a key that provides access to an API.

Text scramble

A few phrases are stored and displayed in sequence, separated by an animation that appears to scramble the letters with random characters between phrases that are selected by Math.random.

Rock Paper Scissors

In this childhood classic game of Rock Paper Scissors, Math.random is used to generate a randomized move for the computer playing as the opponent. It makes a pick from the three available moves.

Strong Password Generator

This password generator uses Math.random to get a password array filled with uppercase and lowercase letters then adds random digits to the generated password. This is another great practical example!

A couple of notes…

It’s possible you have questions after seeing Math.random in these examples. There are a couple I see come up often…

Is Math.random() really random? 

Not exactly. Math.random() returns a pseudo-random number. This algorithm is called a pseudo-random number generator (or PRNG). This means its randomization can be reproduced under certain circumstances. 

The randomization is based on the algorithm xorshift128+, which is likely running on your browser.

So, it’s random-ish.

How do you handle repeated values?

There are many methods to achieve unique values without repetition. The Fisher-Yates is one great way to prevent getting the same number twice by shuffling the sequence. Math.random will select a value from the shuffled array of a finite sequence demonstrated by the code snippet below.

function shuffle (array) {   var i = 0     , j = 0     , temp = null    for (i = array.length - 1; i > 0; i -= 1) {     j = Math.floor(Math.random() * (i + 1))     temp = array[i]     array[i] = array[j]     array[j] = temp   } }

Is Math.random() the same as WebCrypto? 

As you’ve seen from this article, Math.random() is awesome! However, if you dealing with sensitive applications and need a more secure method of randomization, I’d recommend WebCrypto. Reasons you may want to use WebCrypto include temporary verification codes, random password generation, randomized lottery numbers, etc. 

If you need randomization for the purposes of cybersecurity, cryptography, or statistics ,  use the function window.crypto.getRandomValues and check out Mozilla’s documentation on the WebCrypto API.

The post Lots of Ways to Use Math.random() in JavaScript appeared first on CSS-Tricks.

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


, , ,