Monday, 6 July 2020

Building Serverless GraphQL API in Node with Express and Netlify

I’ve always wanted to build an API, but was scared away by just how complicated things looked. I’d read a lot of tutorials that start with “first, install this library and this library and this library” without explaining why that was important. I’m kind of a Luddite when it comes to these things.

Well, I recently rolled up my sleeves and got my hands dirty. I wanted to build and deploy a simple read-only API, and goshdarnit, I wasn’t going to let some scary dependency lists and fancy cutting-edge services stop me¹.

What I discovered is that underneath many of the tutorials and projects out there is a small, easy-to-understand set of tools and techniques. In less than an hour and with only 30 lines of code, I believe anyone can write and deploy their very own read-only API. You don’t have to be a senior full-stack engineer — a basic grasp of JavaScript and some experience with npm is all you need.

At the end of this article you’ll be able to deploy your very own API without the headache of managing a server. I’ll list out each dependency and explain why we’re incorporating it. I’ll also give you an intro to some of the newer concepts involved, and provide links to resources to go deeper.

Let’s get started!

A rundown of the API concepts

There are a couple of common ways to work with APIs. But let’s begin by (super briefly) explaining what an API is all about: reading and updating data.

Over the past 20 years, some standard ways to build APIs have emerged. REST (short for REpresentational State Transfer) is one of the most common. To use a REST API, you make a call to a server through a URL — say api.example.com/rest/books — and expect to get a list of books back in a format like JSON or XML. To get a single book, we’d go back to the server at a URL — like api.example.com/rest/books/123 — and expect the data for book #123. Adding a new book or updating a specific book’s data means more trips to the server at similar, purpose-defined URLs.

That’s the basic idea of two concepts we’ll be looking at here: GraphQL and Serverless.

GraphQL

Applications that do a lot of getting and updating of data make a lot of API calls. Complicated software, like Twitter, might make hundreds of calls to get the data for a single page. Collecting the right data from a handful of URLs and formatting it can be a real headache. In 2012, Facebook developers starting looking for new ways to get and update data more efficiently.

Their key insight was that for the most part, data in complicated applications has relationships to other data. A user has followers, who are each users themselves, who each have their own followers, and those followers have tweets, which have replies from other users. Drawing the relationships between data results in a graph and that graph can help a server do a lot of clever work formatting and sending (or updating) data, and saving front-end developers time and frustration. Graph Query Language, aka GraphQL, was born.

GraphQL is different from the REST API approach in its use of URLs and queries. To get a list of books from our API using GraphQL, we don’t need to go to a specific URL (like our api.example.com/graphql/books example). Instead, we call up the API at the top level — which would be api.example.com/graphql in our example — and tell it what kind of information we want back with a JSON object:

{
  books {
    id
    title
    author
  }
}

The server sees that request, formats our data, and sends it back in another JSON object:

{
  "books" : [
    {
      "id" : 123
      "title" : "The Greatest CSS Tricks Vol. I"
      "author" : "Chris Coyier"
    }, {
      // ...
    }
  ]
}

Sebastian Scholl compares GraphQL to REST using a fictional cocktail party that makes the distinction super clear. The bottom line: GraphQL allows us to request the exact data we want while REST gives us a dump of everything at the URL.

Concept 2: Serverless

Whenever I see the word “serverless,” I think of Chris Watterston’s famous sticker.

Similarly, there is no such thing as a truly “serverless” application. Chris Coyier nice sums it up his “Serverless” post:

What serverless is trying to mean, it seems to me, is a new way to manage and pay for servers. You don’t buy individual servers. You don’t manage them. You don’t scale them. You don’t balance them. You aren’t really responsible for them. You just pay for what you use.

The serverless approach makes it easier to build and deploy back-end applications. It’s especially easy for folks like me who don’t have a background in back-end development. Rather than spend my time learning how to provision and maintain a server, I often hand the hard work off to someone (or even perhaps something) else.

It’s worth checking out the CSS-Tricks guide to all things serverless. On the Ideas page, there’s even a link to a tutorial on building a serverless API!

Picking our tools

If you browse through that serverless guide you’ll see there’s no shortage of tools and resources to help us on our way to building an API. But exactly which ones we use requires some initial thought and planning. I’m going to cover two specific tools that we’ll use for our read-only API.

Tool 1: NodeJS and Express

Again, I don’t have much experience with back-end web development. But one of the few things I have encountered is Node.js. Many of you are probably aware of it and what it does, but it’s essentially JavaScript that runs on a server instead of a web browser. Node.js is perfect for someone coming from the front-end development side of things because we can work directly in JavaScript — warts and all — without having to reach for some back-end language.

Express is one of the most popular frameworks for Node.js. Back before React was king (How Do You Do, Fellow Kids?), Express was the go-to for building web applications. It does all sorts of handy thing like routing, templating, and error handling.

I’ll be honest: frameworks like Express intimidate me. But for a simple API, Express is extremely easy to use and understand. There’s an official GraphQL helper for Express, and a plug-and-play library for making a serverless application called serverless-http. Neat, right?!

Tool 2: Netlify functions

The idea of running an application without maintaining a server sounds too good to be true. But check this out: not only can you accomplish this feat of modern sorcery, you can do it for free. Mind blowing.

Netlify offers a free plan with serverless functions that will give you up to 125,000 API calls in a month. Amazon offers a similar service called Lambda. We’ll stick with Netlify for this tutorial.

Netlify includes Netlify Dev which is a CLI for Netlify’s platform. Essentially, it lets us run a simulation of our in a fully-featured production environment, all within the safety of our local machine. We can use it to build and test our serverless functions without needing to deploy them.

At this point, I think it’s worth noting that not everyone agrees that running Express in a serverless function is a good idea. As Paul Johnston explains, if you’re building your functions for scale, it’s best to break each piece of functionality out into its own single-purpose function. Using Express the way I have means that every time a request goes to the API, the whole Express server has to be booted up from scratch — not very efficient. Deploy to production at your own risk.

Let’s get building!

Now that we have out tools in place, we can kick off the project. Let’s start by creating a new folder, navigating to fit in terminal, then running npm init  on it. Once npm creates a package.json file, we can install the dependencies we need. Those dependencies are:

  1. Express
  2. GraphQL and express-graphql. These allow us to receive and respond to GraphQL requests.
  3. Bodyparser. This is a small layer that translates the requests we get to and from JSON, which is what GraphQL expects.
  4. Serverless-http. This serves as a wrapper for Express that makes sure our application can be used on a serverless platform, like Netlify.

That’s it! We can install them all in a single command:

npm i express express-graphql graphql body-parser serverless-http

We also need to install Netlify Dev as a global dependency so we can use it as a CLI:

npm i -g netlify-dev

File structure

There’s a few files that are required for our API to work correctly. The first is netlify.toml which should be created at the project’s root directory. This is a configuration file to tell Netlify how to handle our project. Here’s what we need in the file to define our startup command, our build command and where our serverless functions are located:

[build]


  # This command builds the site
  command = "npm run build"


  # This is the directory that will be deployed
  publish = "build"


  # This is where our functions are located
  functions = "functions"

That functions line is super important; it tells Netlify where we’ll be putting our API code.

Next, let’s create that /functions folder at the project’s root, and create a new file inside it called api.js.  Open it up and add the following lines to the top so our dependencies are available to use and are included in the build:

const express = require("express");
const bodyParser = require("body-parser");
const expressGraphQL = require("express-graphql");
const serverless = require("serverless-http");

Setting up Express only takes a few lines of code. First, we’ll initial Express and wrap it in the serverless-http serverless function:

const app = express();
module.exports.handler = serverless(app);

These lines initialize Express, and wrap it in the serverless-http function. module.exports.handler lets Netlify know that our serverless function is the Express function.

Now let’s configure Express itself:

app.use(bodyParser.json());
app.use(
  "/",
  expressGraphQL({
    graphiql: true
  })
);

These two declarations tell Express what middleware we’re running. Middleware is what we want to happen between the request and response. In our case, we want to parse JSON using bodyparser, and handle it with express-graphql. The graphiql:true configuration for express-graphql will give us a nice user interface and playground for testing.

Defining the GraphQL schema

In order to understand requests and format responses, GraphQL needs to know what our data looks like. If you’ve worked with databases then you know that this kind of data blueprint is called a schema. GraphQL combines this well-defined schema with types — that is, definitions of different kinds of data — to work its magic.

The very first thing our schema needs is called a root query. This will handle any data requests coming in to our API. It’s called a “root” query because it’s accessed at the root of our API— say, api.example.com/graphql.

For this demonstration, we’ll build a hello world example; the root query should result in a response of “Hello world.”

So, our GraphQL API will need a schema (composed of types) for the root query. GraphQL provides some ready-built types, including a schema, a generic object², and a string.

Let’s get those by adding this below the imports:

const {
  GraphQLSchema,
  GraphQLObjectType,
  GraphQLString
} = require("graphql");

Then we’ll define our schema like this:

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: 'HelloWorld',
    fields: () => ({ /* we'll put our response here */ })
  })
})

The first element in the object, with the key query, tells GraphQL how to handle a root query. Its value is a GraphQL object with the following configuration:

  • name – A reference used for documentation purposes
  • fields – Defines the data that our server will respond with. It might seem strange to have a function that just returns an object here, but this allows us to use variables and functions defined elsewhere in our file without needing to define them first³.
const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: "HelloWorld",
    fields: () => ({
      message: {
        type: GraphQLString,
        resolve: () => "Hello World",
      },
    }),
  }),
});

The fields function returns an object and our schema only has a single message field so far. The message we want to respond with is a string, so we specify its type as a GraphQLString. The resolve function is run by our server to generate the response we want. In this case, we’re only  returning “Hello World” but in a more complicated application, we’d probably use this function to go to our database and retrieve some data.

That’s our schema! We need to tell our Express server about it, so let’s open up api.js and make sure the Express configuration is updated to this:

app.use(
  "/",
  expressGraphQL({
    schema: schema,
    graphiql: true
  })
);

Running the server locally

Believe it or not, we’re ready to start the server! Run netlify dev in Terminal from the project’s root folder. Netlify Dev will read the netlify.toml configuration, bundle up your api.js function, and make it available locally from there. If everything goes according to plan, you’ll see a message like “Server now ready on http://localhost:8888.” 

If you go to localhost:8888 like I did the first time, you might be a little disappointed to get a 404 error.

But fear not! Netlify is running the function, only in a different directory than you might expect, which is /.netlify/functions. So, if you go to localhost:8888/.netlify/functions/api, you should see the GraphiQL interface as expected. Success!

Now, that’s more like it!

The screen we get is the GraphiQL playground and we can use it to test out the API. First, clear out the comments in the left pane and replace them with the following:

{
  message
}

This might seem a little… naked… but you just wrote a GraphQL query! What we’re saying is that we’d like to see the message field we defined in api.js. Click the “Run” button, and on the righth, you’ll see the following:

{
  "data": {
    "message": "Hello World"
  }
}

I don’t know about you, but I did a little fist pump when I did this the first time. We built an API!

Bonus: Redirecting requests

One of my hang-ups while learning about Netlify’s serverless functions is that they run on the /.netlify/functions path. It wasn’t ideal to type or remember it and I nearly bailed for another solution. But it turns out you can easily redirect requests when running and deploying on Netlfiy. All it takes is creating a file in the project’s root directory called _redirects (no extension necessary) with the following line in it:

/api /.netlify/functions/api 200!

This tells Netlify that any traffic that goes to yoursite.com/api should be sent to /.netlify/functions/api. The 200! bit instructs the server to send back a status code of 200 (meaning everything’s OK).

Deploying the API

To deploy the project, we need to connect the source code to Netlfiy. I host mine in a GitHub repo, which allows for continuous deployment.

After connecting the repository to Netlfiy, the rest is automatic: the code is processed and deployed as a serverless function! You can log into the Netlify dashboard to see the logs from any function.

Conclusion

Just like that, we are able to create a serverless API using GraphQL with a few lines of JavaScript and some light configuration. And hey, we can even deploy — for free. 

The possibilities are endless. Maybe you want to create your own personal knowledge base, or a tool to serve up design tokens. Maybe you want to try your hand at making your own PokéAPI. Or, maybe you’re interesting in working with GraphQL.

Regardless of what you make, it’s these sorts of technologies that are getting more and more accessible every day. It’s exciting to be able to work with some of the most modern tools and techniques without needing a deep technical back-end knowledge.

If you’d like to see at the complete source code for this project, it’s available on GitHub.

Some of the code in this tutorial was adapted from Web Dev Simplified’s “Learn GraphQL in 40 minutes” article. It’s a great resource to go one step deeper into GraphQL. However, it’s also focused on a more traditional server-full Express.


  1. If you’d like to see the full result of my explorations, I’ve written a companion piece called “A design API in practice” on my website.
  2. The reasons you need a special GraphQL object, instead of a regular ol’ vanilla JavaScript object in curly braces, is a little beyond the scope of this tutorial. Just keep in mind that GraphQL is a finely-tuned machine that uses these specialized types to be fast and resilient.
  3. Scope and hoisting are some of the more confusing topics in JavaScript. MDN has a good primer that’s worth checking out.

The post Building Serverless GraphQL API in Node with Express and Netlify appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2VTEbGh
via IFTTT

WordPress Contributors Seek Sponsorship for Improving Gutenberg Developer Docs

A couple of WordPress contributors are currently looking for folks to sponsor them to work on the documentation for the WordPress block editor (often referred to as “Gutenberg”) and this is your chance to support them.

If you’ve developed blocks for the WordPress block editor — or at least have tried to — then you have likely struggled to find any meaningful documentation. Heck, just look at two recent posts here at CSS-Tricks where Dmitry Mayorov explains block variations and Leonardo Losoviz adds a welcome guide to the block editor. They both lament the lack of documentation and describe how they had to work around it. Chris has even experimented with different build approaches, from create-gluten-block to wp-cli to ACF Blocks. It’s sortuva Wild West out there and documented standards with examples would be a huge win, both for WordPress and for developers.

Now, I don’t think it’s worth getting into a debate into why the documentation doesn’t already exist a year since the block editor was released. There are lots of reasons for that and none of them help move things forward.

We flipped the switch to enable the WordPress block editor here at CSS-Tricks earlier this year and haven’t looked back. Where several of us on the team would write drafts in Dropbox Paper, Google Docs, or even a code editor, I think we’ve all started writing directly in WordPress because, well, it’s just so gosh-darned nice. I know I’m looking forward to contributing whatever I can to help this make this tool more accessible to developers — that’s the best way to spark new ideas and innovations for the future of blocks.

Direct Link to ArticlePermalink

The post WordPress Contributors Seek Sponsorship for Improving Gutenberg Developer Docs appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2YRKwDZ
via IFTTT

Posters! (for CSS Flexbox and CSS Grid)

Any time I chat with a fellow web person and CSS-Tricks comes up in conversation, there is a good chance they’ll say: oh yeah, that guide on CSS flexbox, I use that all the time!

Indeed that page, and it’s cousin the CSS grid guide, are among our top trafficked pages. I try to take extra care with them making sure the information on them is current, useful, and the page loads speedily and properly. A while back, in a round of updates I was doing on the guides, I reached out to Lynn Fisher, who always does incredible work on everything, to see if she’d be up for re-doing the illustrations on the guides. Miraculously, she agreed, and we have the much more charismatic illustrations that live on the guides today.

In a second miracle, I asked Lynn again if she’d be up for making physical paper poster designs of the guides, and see agreed again! And so they live!

Here they are:

You better believe I have it right next to me in my office:

They are $25 each which includes shipping anywhere in the world.

The post Posters! (for CSS Flexbox and CSS Grid) appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/31OgaUP
via IFTTT

Sunday, 5 July 2020

USA.css

Lots of fun with gradients from Bennet Feely: stars, stripes, banners, bursts… I love being able to use nice patterns with either no image requests at all, or very little SVG.

And important reminder: Bennet does all sorts of cool stuff. I’ve probably used Clippy about a million times.

Direct Link to ArticlePermalink

The post USA.css appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/3eZNegi
via IFTTT

Saturday, 4 July 2020

The Thirteenth Fourth

Well boy howdy. The 13th birthday of CSS-Tricks has rolled around. A proper teenager now, howabouthat? I always take the opportunity to do a bit of a state of the union address at this time, so let’s get to it!

Design

Technically, we’re still on v17 of the site design. This was the first design that I hired first-class help to do, and I’m still loving it, so I haven’t had much of an itch to do massive changes to it. Although it is quite different¹ today than it was on launch day.

For example…

Maybe next year we’ll do something different again. My list is starting to grow for some behind-the-scenes tech stuff I wanna re-jigger, and sometimes that goes hand in hand with redesign work.

Closed Forums

The forums on this site have been a mental weight on me for literally years. Earlier this year I finally turned them off. They are still there, and probably always will be (so the URLs are maintained), but nobody can post new threads or replies.

It was a painful move. Even as I did it, there was still some regular daily activity there and I’m sure it didn’t feel good to those people to have a place they have invested time in shut down. Here’s why I did it:

  • Nobody here, including me, checked in on the forums with any regularity. Unmoderated public forums on the internet are not acceptable to me.
  • The spam volume was going up. There were periods where most posts, even after the automatic spam blocking I get from Akismet, where spam that required manual removal. Even if we had a dedicated forums employee, that’s no fun, and since we didn’t, it was just a random job for me and I don’t need a time sink like that.
  • The forums represent a certain level of technical debt. They need to be updated. Their design needs to be functional in the context of this site. At one point I ripped out all custom styles and left it be the default theme, which was a good step toward reducing technical debt, but in the end it wasn’t enough.

I can handle some work and some technical debt, of course. But when you combine those things with the fact that the forums don’t contribute much to what I consider to be the success of the site. They don’t exactly drive page views or advertising demand. There isn’t really money to hire help specifically for the forums. But that’s a small part of it. I want this site to help people. I think we can do that best if we focus on publishing with as little divided attention as possible. I think there are places on the internet that are better for forum-like discourse.

Now that they’ve been off a number of months, I can report that the lifting of the mental weight feels very good to me and there is been little if any major negatives.

Social

Here’s another mental weight I lifted: I stopped hand-managing the Twitter account (@css). I still think it’s good that we have a Twitter account (and that we have that cool handle), but I just don’t spend any time on it directly like I used to.

In the past, I’d queue up special articles with commentary and graphics and stuff and make sure the days were full with a spread of what I thought would be interesting tweets about web design and development. That’s fine and all, but it began to feel like a job without a paycheck.

We don’t get (or seem to drive) a lot of traffic from Twitter. Google Analytics shows social media accounts for less than 1% of our traffic. Investing time in “growing” Twitter just doesn’t have enough of an upside for me. Not to mention the obvious: Twitter can be terribly toxic and mentally draining.

So now, all our posts to Twitter are automated through the Jetpack social media connection (we really use Jetpack for tons of stuff). We hit publish on the site and the article is auto-tweeted. So if you use Twitter like an RSS feed of sorts (just show me the news!), you got it.

The result? Our follower count goes up at the same rate it always did. Engagement there is the same, or higher, than it ever was. What a relief. Do ten times less work for the same benefit.

When I have the urge to share a link with commentary I use the same system we’ve always had here: I write it up as a link blog post instead. Now we’re getting even more benefit: long-term content building, which is good for the thing that we actually have on our side: SEO.

Someday we could improve things by hand-writing the auto-tweet text with a bit more joie de vivre, crediting the author more clearly, and, #stretchgoal, a custom or fancy-generated social media graphic.

Opened Up Design Possibilities

One aspect of this site that I’ve been happy with is the opportunity to do custom design on content. Here are some examples of that infrastructure.

On any given blog post, we can pick a template. Some of those templates are very specific. For example, my essay The Great Divide is a template all to itself.

In the code base, I have a PHP template and a CSS file that are entirely dedicated to that post. I think that’s a fine way to handle a post you want to give extra attention to, although the existence of those two files is a bit of technical debt.

I learned something in the creation of that particular essay: what I really need to open up the art direction/design possibility on a post is a simple, stripped-down template to start from. So that’s what we call a “Fancy Post” now, another template choice for any particular post. Fancy Posts have a hero image and a centered column for the content of the post. From there, we can use custom CSS to style things right within WordPress itself.

For example, my recent post on DX is styled as a Fancy Post with Custom CSS applied right within the block editor.

The Block Editor itself is a huge deal for us. That was one of my goals for the year, and we’ve really exceeded how far we’d get with it. I think writing and editing posts in the block editor is a million miles ahead of the old editor.

The hardest challenge was (and still is really) getting the block transforms set up for legacy content. But once you have the power to build and customize blocks, that alone opens up a ton of design possibility within posts that is too big of a pain in the butt and too heavy on technical debt otherwise.

Another door we opened for design possibilities is a classic one: using categories. A sort of freebie you get in WordPress is the ability to create templates for all sorts of things that just sort of automatically work if they are named correctly. So for example I have a filed called category-2019-end-of-year-thoughts.php and that fully gives me control over making landing pages for groups of posts, like our end-of-year thoughts homepage. Not to mention our “Guide Collection” pages which are another way to programmatically build collections of pages.

That’s a lot of tools to do custom work with, and I’m really happy with that. It feels like we’ve given ourselves lots of potential with these tools, and only started taking advantage of it.

Speaking of which, another aspect of custom design we have available is the new book format…

eCommerce

We’re using WooCommerce here on the site now again. I just got done singing the praises of the Block Editor and how useful that is been… WooCommerce is in the same boat. I feel like I’m getting all this powerful functionality with very little effort, at a low cost, and with little technical debt. It makes me very happy to have this site on WordPress and using so much of suite of functionality that offers.

So for one thing, I can sell products with it, and we have products now! Lynn Fisher designed a poster for our CSS Flexbox guide and designed a poster for our CSS Grid guide, which you can now buy and ship anywhere in the world for $25 each. Look, with the Block Editor I can put a block for a poster right here in this post:

Another thing we’re using WooCommerce for is to sell our new book, The Greatest CSS Tricks Vol. I. If we actually made it into a proper eBook format, WooCommerce could absolutely deliver those files digitally to you, but we haven’t done that yet. We’ve take another path, which is publishing the book as chapters here on the site behind a membership paywall we’re calling MVP supporters. The book is just one of the benefits of that.

WooCommerce helps:

  • Build a membership system and sell memberships. Membership can lock certain pages to members-only as has programmatic hooks I can use for things like removing ads.
  • Sell subscriptions to those memberships, with recurring billing.
  • Sell one-off products

And I’m just scratching the surface of course. WooCommerce can do anything eCommerce wise.

Analytics

They are fine. Ha! That’s how much I worry about our general site analytics. I like to check in on them from time to time to make sure we’re not tanking or anything scary, but we never are (knock on wood). We’re in the vicinity of 8m page views a month, and year-over-year traffic is a bit of a dance.

Sponsors

THANK YOU THANK YOU THANK YOU

That’s what I have to say to all our sponsors. We’re so damn lucky to work with a lineup of sponsors that I wholeheartedly endorse as well as literally use their products. We have different sponsors all the time, but these are the biggest and those who have been with us the longest.

  • Automattic: Thanks for building great software for the WordPress ecosystem. This site is made possible by a heaping helping of that software.
  • Netlify: Thanks for bringing the Jamstack world to life. I’m also a big fan of this way of building websites, and think that Jamstack should be the foundation for most websites. Beyond that, you’ve redefined modern developer experience.
  • Flywheel: Thank you for hosting this website, being a high-quality host I can trust and who has been helpful to me countless times. This is what high-quality WordPress hosting looks like.
  • Frontend Masters: Thank you for being an education partner that does things right and helps me have the best possible answer for people when they are searching a more structured formal education about doing web work: go try Frontend Masters.

If you’re trying to reach front-end developers with your products, that’s literally how I make a living and can help.

My Other Projects

CodePen is no spring chicken either, being over 8 years old itself. I repeat myself a lot with this particular aspect of talking about CodePen: we’ve got a ton of ideas, a ton of work to do, and we can’t wait to show you the CodePen of tomorrow. 2020 for CodePen has been a lot different than the last 2-3 years of CodePen. Some technical choices we’ve made have been starting to pay off. The team is vibing very well and absolutely tearing through work faster than I would have thought possible a few years ago, and we haven’t even unlocked some of the biggest doors yet. I know that’s vague, but we talk in more detail about stuff on CodePen Radio.

ShopTalk, as ever, is going strong. That’s 420 episodes this week, friends. Dave has me convinced that our format as it is, is good. We aren’t an instruction manual. You don’t listen to any particular episode because we’re going to teach you some specific subject that we’ve explicitly listed out. It’s more like water cooler talk between real world developers who develop totally different things in totally different situations, but agree on more than we disagree. We might evolve what ShopTalk show is over time, but this format will live on because there is value in discussion in this format.

Life

My wife Miranda and I are still in Bend, Oregon and our Daughter Ruby is two and a half. She’s taking a nap and I’m looking at the monitor as I type.

We have the virus here like everywhere else. It’s sad to think that we’re this far into it and our local hospital is pleading with people to be careful this holiday weekend because they are very near capacity and can’t take much more. Here’s hoping we can get past this painful period. Stay safe and stay cool, friends, thanks for reading.


  1. I always feel bad when I make design changes away from an actual professional designer’s work. Is the site design better today than Kylie’s original? Uhm probably not (sorry for wrecking it Kylie!), but sometimes I just have an itch to fiddle with things and give things a fresh look. But the biggest driver of change is the evolving needs of the site and my desire to manage things with as little technical debt as possible, and sometimes simplifying design things helps me get there.

The post The Thirteenth Fourth appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2BGSHu3
via IFTTT

Friday, 3 July 2020

Fluid Images in a Variable Proportion Layout

Creating fluid images when they stand alone in a layout is easy enough nowadays. However, with more sophisticated interfaces we often have to place images inside responsive elements, like this card:

Screenshot. A horizontal card element with an image of two strawberries against a light blue background to the left of text that contains a heading and two sentences.

For now, let’s say this image is not semantic content, but only decoration. That’s a good use for background-image. And because in this context the image contains an object, we can’t allow any parts to be cropped out when it’s responsive, so we’d pick background-size: contain.

Here’s where it starts to get tricky: on mobile devices, this card shifts direction and becomes vertical, with the image on top. We can make that happen with any sort of CSS layout technique, and probably best handled with CSS grid or flexbox.

Screenshot. The same strawberry card but in a vertical format.

But as we test for smaller screens, because of the contain property, this is what we get:

The same card element in vertical but now the strawberry image is not flush with the top border of the card.
Hey, get back up there!

That’s not very nice. The image resizes to maintain its aspect ratio without cutting off any details, and if the image is important content and should not be cropped, we can’t change background-size to cover.

At this point, our next attempt might be familiar to you: placing the image inline, instead the background. 

On desktop, this works fine:

It’s not bad on mobile either:

But on smaller screens, because of all the fixed sizes, the image’s proportions get distorted.

Screenshot. The vertical card element with the strawberry image out of proportion, causing the strawberries to appear stretched vertically.
Hmm, those strawberries are not as appetizing when stretched.

We could spend hours fiddling with the image, the card, the flex properties, going back and forth. Or, we could…

Separate main content from the background

This is the base for obtaining much more flexibility and resilience when it comes to responsive images. It might not be possible 100% of the time but, in many cases, it can be achieved with a little effort on the design side of things, especially if this approach is planned beforehand.

For our next iteration, we’re placing our strawberries image on a transparent background and setting what was the blue color in the raster image with CSS instead. Go ahead and play with viewport sizes in this demo by adjusting the size of the sample space!

Looking deeper at the styles, notice that we’ve also added padding to the div that holds the image, so the strawberries don’t come too close to the edges. We have full control of how close or distant we want them to be, through this padding.

Note how we’re also using negative margins to compensate for the padding on our outer card wrapper, otherwise we’d get white space all around the image.

Use the object-fit property for inline images

As much as the previous demo works, we can still improve the approach. Up to now, we’ve assumed that the image was un-semantical content — but with this layout, it’s also likely that the image illustration could be more than decoration.

If that’s the case, we definitely don’t want the image to get cut off because that would essentially amount to data loss. It’s semantically better to put the image inline instead of a background to prevent that, and we can use the object-fit property to make it happen.

We’ve extracted the strawberries from the background and it’s now an inline <img> element, but we kept the background color in that same image div. 

Finally, combining the object-fit: contain with a 100% width makes it possible to resize the window and keep the aspect ratio of the strawberries. The caveat of this approach, however, is that we need to set a fixed height for the image on the desktop version — otherwise it’s going to follow the proportion of the set width (and reducing it will alter the layout). That might make things too constrained if we need to generate these cards with a variable amount of text that breaks into several lines.

Coming soon: aspect-ratio

The solution for the concern above might be just around the corner with the upcoming aspect-ratio property. This will enable setting a fixed ratio for an element, like this:

.el {
  aspect-ratio: 16 / 9;
}

This means we’ll be able to eliminate fixed height and replace it with our calculated aspect ratio. For example, the dimensions in the desktop breakpoint of our last example looked like this:

.image {
  /* ... */
  height: 184px;
  width: 318px;
}

With aspect-ratio, we could remove the height declaration and do the math to get the closest ratio that amounts to 184:

.image {
  /* ... */
  width: 318px; /*  Base width */
  height: unset; /* Resets the height that was set outside the media query */
  aspect-ratio: 159 / 92; /* Amounts close to a 184px height */
}

The upcoming property is better explored in this article, if you want to learn more about it.

In the end, there are multiple ways to achieve reliably responsive images in a variable proportion layout. However, the trick to make this job easier — and better — does not necessarily lie with CSS; it can be as simple as adapting your images, whether that’s by separating the foreground from background (like we did) or selecting specific images that will still work if a fair portion of the edges get cropped.

The post Fluid Images in a Variable Proportion Layout appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/3f3tVTu
via IFTTT

Settling down in a Jamstack world

One of the things I like about Jamstack is that it’s just a philosophy. It’s not particularly prescriptive about how you go about it. To me, the only real requirement is that it’s based on static (CDN-backed) hosting. You can use whatever tooling you like. Those tools, though, tend to be somewhat new, and new sometimes comes with issues. Some pragmatism from Sean C Davis here:

I have two problems with solving problems using the newest, best tool every time a problem arises.

1. It’s simply not productive. Introducing new processes and tools takes time. Mastery and efficiency are built over time. If we’re trying to run a profitable business, we shouldn’t start from scratch every time.

2. We can’t know everything, all the time. With the rapidity at which we’re seeing new tools, there’s simply no way of knowing the best tool for the job because there’s no way to know all the tools available.

The trick is to settle into some tools you’ve proved that work and then keep using them to increase that level of expertise.

The post Settling down in a Jamstack world appeared first on CSS-Tricks.



from CSS-Tricks https://ift.tt/2YTOpIA
via IFTTT

Passkeys: What the Heck and Why?

These things called  passkeys  sure are making the rounds these days. They were a main attraction at  W3C TPAC 2022 , gained support in  Saf...