Micro Frontends

One random day not long ago, I started hearing joke after joke about “micro frontends” — sort of how I first learned about Toast. I didn’t understand the source until asking around, which uncovered this article from Cam Jackson.

In this article we’ll describe a recent trend of breaking up frontend monoliths into many smaller, more manageable pieces, and how this architecture can increase the effectiveness and efficiency of teams working on frontend code.

I’d argue it should read “front-end monoliths” and “front-end code,” but I digress already.

The idea is similar to microservices, but for the front end. So, instead of one big front-end architecture (e.g. a React app), different parts of the front end are developed entirely independent of one another, have no dependencies on each other, and can be worked on and deployed independently.

It’s one of those things where you can’t quite tell if it’s really an interesting foretelling of the future, just a niche architectural choice that happened to work for a handful of large organizations, or even just a theoretical option.

The first place my mind goes is consistency and DRY-ness. Anywhere I’ve worked, these things are a big deal and it seems like the industry at large has had endless front-end problems with shipping designs that start and stay consistent and cohesive without repeating itself with shovelfuls of technical debt. Independent front-ends sound like they might be a problem if Team B is being blocked by Team A for something not directly related, but then it introduces the problem of Team B’s output drifting towards inconsistency with Team A’s output.

The article itself talks about a browse/search landing page, a details/ordering page, and a profile page, with all three of those tackled by different independent products/teams. It sounds kinda cool and interesting to me, and it also sounds like those teams better sit right next to each other at work; otherwise this app is going the way of Frankenstein’s monster in two weeks. Styling is only lightly addressed with a, …

A Peek at New Methods Coming to Promises

Promises are one of the most celebrated features introduced to JavaScript. Having a native asynchronous artifact baked right into the language has opened up a new era, changing not only how we write code but also setting up the base for other freat APIs — like fetch!

Let’s step back a moment to recap the features we gained when they were initially released and what new bells and whistles we’re getting next.

New to the concept of Promises? I highly recommend Jake Archibald’s article as a primer.

Features we have today

Let’s take a quick look at some of the things we can currently do with promises. When JavaScript introduced them, it gave us an API to execute asynchronous actions and react to their succesful return or failure, a way to create an association around some data or result which value we still don’t know.

Here are the Promises features we have today.

Handling promises

Every time an async method returns a promise — like when we use fetch — we can pipe then() to execute actions when the promise is fulfilled, and catch() to respond to a promise being rejected.

The classic use case is calling data from an API and either loading the data when it returns or displaying an error message if the data couldn’t be located.

fetch('//resource.to/some/data')
  .then(result => console.log('we got it', result.json()))
  .catch(error => console.error('something went wrong', error))

In addition, in its initial release we got two methods to handle groups of Promises.

Resolving and rejecting collections of promises

A promise can be fulfilled when it was successfully resolved, rejected when it was resolved with an error, and pending while there’s no resolution. A promise is considered settled when it has been resolved, disregarding the result.

As such, there are two methods we have to help with the behavior of handling a group of promises depending on the combination of states we obtain.

Promise.all is one or those methods. It fulfills only if all promises were resolved successfully, returning an array …

Finally… A Post on Finally in Promises

“When does finally fire in a JavaScript promise?” This is a question I was asked in a recent workshop and I thought I’d write up a little post to clear up any confusion.

The answer is, to quote Snape:

snape saying always

…always.

The basic structure is like this:

try {
  // I’ll try to execute some code for you
}
catch(error) {
  // I’ll handle any errors in that process
} 
finally {
  // I’ll fire either way
}

Take, for instance, this example of a Chuck Norris joke generator, complete with content populated from the Chuck Norris Database API. (Aside: I found this API from Todd Motto’s very awesome list of open APIs, which is great for demos and side projects.)

See the Pen
finally! chuck norris jokes!
by Sarah Drasner (@sdras)
on CodePen.

async function getData() {
  try {
    let chuckJokes = await fetch(`https://api.chucknorris.io/jokes/random`)
      .then(res => res.json())
    
    console.log('I got some data for you!')
    document.getElementById("quote").innerHTML = chuckJokes.value;
  } 
  catch(error) {
    console.warn(`We have an error here: ${error}`)
  
  finally {
    console.log('Finally will fire no matter what!')
  
}

In the console:

Console that says: I got some data for you! and Finally will fire no matter what!

Now, let’s introduce a typo to the API and accidentally put a bunch of r‘s in the URL of the API. This will result in our try statement failing, which means the catch now throws an error.

async function getData() {
  try {
    // let's mess this up a bit
    let chuckJokes = await fetch(`https://api.chucknorrrrris.io/jokes/random`)
      .then(res => res.json())
    
    console.log('I got some data for you!')
    document.getElementById("quote").innerHTML = chuckJokes.value;
  } 
  catch(error) {
    console.warn(`We have an error here: ${error}`)
  }
  finally {
    console.log('Finally will fire no matter what!')
  }
}

Console:

Console that has a failed GET request and then a warning that says We have an error here, Typeerror: failed to fetch, and then on a new line, Finally will fire no matter what!

One giant important piece that the example doesn’t illustrate is that the finally block will run even if in the try or catch block, a return or break statement stops the code.

When would you use this?

I’ve found it particularly useful in two different situations, though I’m sure there are others:

  • When I otherwise would duplicate code that’s need in the try and catch blocks. Here’s

So, you think you’ve got project management nailed down

(This is a sponsored post.)

Who needs a project manager? You’re an organized person who can keep track of your own work, right?

Wrong.

Well, wrong if you’re part of a team. The thing about being self-organized is that it’s related to project management but not synonymous with it. Case in point: what happens if your project relies on someone else’s involvement? Sure you’re organized, but can you always say the same about your co-workers? Chances are you need something to keep everyone in sync so that a project stays on course.

That’s where you should consider trying monday.com.

monday.com is project management, but with a human touch. Sure, there’s task lists, assignments, milestones, due dates, and such like you would expect from any project management tool. That’s a given. That said, monday.com takes things up a notch by stripping away the barriers that prevent team members from collaborating with one another. For example, monday.com includes real-time messaging, file sharing, reporting, and a slew of other features that bridge the gaps between people and tasks so that everyone has purview into the progress of a project. Plus, it’s so pretty to look at.

There’s so much more than meets the eye because monday.com goes beyond project management. There’s resource management that ensures you have the right tools for a project, forecasting to affirm the prospect of a business opportunity, and even client management services. Seriously, your team and perhaps company can lean into monday.com and get a ton of use out of it.

You know what to do from here. Give monday.com a try. There’s a free trial and we’re sure you’ll find it to be so useful that you’ll want to stick with it well beyond.

Get Started

Direct Link to ArticlePermalink

The post So, you think you’ve got project management nailed down appeared first on CSS-Tricks.

from CSS-Tricks https://synd.co/2Jrcs8A…

Managing Multiple Backgrounds with Custom Properties

One cool thing about CSS custom properties is that they can be a part of a value. Let’s say you’re using multiple backgrounds to pull off a a design. Each background will have its own color, image, repeat, position, etc. It can be verbose!

You have four images:

body {
  
  background-position:
    top 10px left 10px,
    top 10px right 10px,
    bottom 10px right 10px,
    bottom 10px left 10px;
  
  background-repeat: no-repeat;
  
  background-image:
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-left.svg),
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-right.svg),
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-right.svg),
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-left.svg);
  
}

You want to add a fifth in a media query:

@media (min-width: 1500px) {
  body {
    /* REPEAT all existing backgrounds, then add a fifth. */
  }
}

That’s going to be super verbose! You’ll have to repeat each of those four images again, then add the fifth. Lots of duplication there.

One possibility is to create a variable for the base set, then add the fifth much more cleanly:

body {
  --baseBackgrounds: 
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-left.svg),
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-right.svg),
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-right.svg),
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-left.svg);

  background-position:
    top 10px left 10px,
    top 10px right 10px,
    bottom 10px right 10px,
    bottom 10px left 10px;
  
  background-repeat: no-repeat;
  
  background-image: var(--baseBackgrounds);
}
@media (min-width: 1500px) {
  body {
    background-image: 
      var(--baseBackgrounds),
      url(added-fifth-background.svg);
  }
}

But, it’s really up to you. It might make more sense and be easier manage if you made each background image into a variable, and then pieced them together as needed.

body {
  --bg1: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-left.svg);
  --bg2: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-right.svg);
  --bg3: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-right.svg);
  --bg4: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-left.svg);
  --bg5: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-left.svg);
  
  background-image: var(--bg1), var(--bg2), var(--bg3), var(--bg4);
}
@media (min-width: 1500px) {
  body {
    background-image: var(--bg1), var(--bg2), var(--bg3), var(--bg4), var(--bg5);
  }
}

Here’s a basic version of that, including a supports query:

See the Pen
Multiple BGs with Custom Properties
by Chris Coyier (@chriscoyier)
on CodePen.

Dynamically changing just the part of a value is a huge strength of CSS custom properties!

Note, too, that with backgrounds, it might be best to include the entire shorthand as the variable. That way, it’s much easier to piece everything together at once, rather than needing something like…

--bg_1_url: url();
--bg_1_size: 100px;
--bg_1_repeat: no-repeat;
/* etc. */

It’s easier to put all of the …

Build a Chat App Using React Hooks in 100 Lines of Code

We’ve looked at React Hooks before, around here at CSS-Tricks. I have an article that introduces them as well that illustrates how to use them to create components through functions. Both articles are good high-level overviews about the way they work, but they open up a lot of possibilities, too.

So, that’s what we’re going to do in this article. We’re going to see how hooks make our development process easier and faster by building a chat application.

Specifically, we are building a chat application using Create React App. While doing so, we will be using a selection of React Hooks to simplify the development process and to remove a lot of boilerplate code that’s unnecessary for the work.

There are several open source Reacts hooks available and we’ll be putting those to use as well. These hooks can be directly consumed to build features that otherwise would have taken more of code to create. They also generally follow well-recognized standards for any functionality. In effect, this increases the efficiency of writing code and provides secure functionalities.

Let’s look at the requirements

The chat application we are going to build will have the following features:

  • Get a list of past messages sent from the server
  • Connect to a room for group chatting
  • Get updates when people disconnect from or connect to a room
  • Send and receive messages

We’re working with a few assumptions as we dive in:

  • We’ll consider the server we are going to use as a blackbox. Don’t worry about it working perfectly as we’re going to communicate with it using simple sockets.
  • All the styles are contained in a single CSS file, can be copied to the src directory. All the styles used within the app are linked in the repository.

Getting set up for work

OK, we’re going to want to get our development environment ready to start writing code. First off, React requires both Node and npm. You can set them up here.

Let’s spin up a new project from the Terminal:…

Position Sticky and Table Headers

You can’t position: sticky; a <thead>. Nor a <tr>. But you can sticky a <th>, which means you can make sticky headers inside a regular ol’ <table>. This is tricky stuff, because if you didn’t know this weird quirk, it would be hard to blame you. It makes way more sense to sticky a parent element like the table header rather than each individiaul element in a row.

The issue boils down to the fact that stickiness requires position: relative to work and that doesn’t apply to <thead> and <tr> in the CSS 2.1 spec.

There are two very extreme reactions to this, should you need to implement sticky table headers and not be aware of the <th> workaround.

  • Don’t use table markup at all. Instead, use different elements (<div>s and whatnot) and other CSS layout methods to replicate the style of a table, but not locked out of using position: relative and creating position: sticky parent elements.
  • Use table elements, but totally remove all their styling defaults with new display values.

The first is dangerous because you aren’t using semantic and accessible elements for the content to be read and navigated. The second is almost the same. You can go that route, but need to be really careful to re-apply semantic roles.

Anyway, none of that matters if you just stick (get it?!) to using a sticky value on those <th> elements.

See the Pen
Sticky Table Headers with CSS
by Chris Coyier (@chriscoyier)
on CodePen.

It’s probably a bit weird to have table headers as a row in the middle of a table, but it’s just illustrating the idea. I was imagining colored header bars separating players on different sports teams or something.

Anytime I think about data tables, I also think about how tricky it can be to make them responsive. Fortunately, there are a variety of ways, all depending on the best way to group and explore the data in them.

The post Position Sticky

Color Inputs: A Deep Dive into Cross-Browser Differences

In this article, we’ll be taking a look at the structure inside <input type='color'> elements, browser inconsistencies, why they look a certain way in a certain browser, and how to dig into it. Having a good understanding of this input allows us to evaluate whether a certain cross-browser look can be achieved and how to do so with a minimum amount of effort and code.

Here’s exactly what we’re talking about:

But before we dive into this, we need to get into…

Accessibility issues!

We’ve got a huge problem here: for those who completely rely on a keyboard, this input doesn’t work as it should in Safari and in Firefox on Windows, but it does work in Firefox on Mac and Linux (which I only tested on Fedora, so feel free to yell at me in the comments if it doesn’t work for you using another distribution).

In Firefox on Windows, we can Tab to the input to focus it, press Enter to bring up a dialog… which we then cannot navigate with the keyboard!

I’ve tried tabbing, arrow keys, and every other key available on the keyboard… nothing! I could at least close the dialog with good old Alt + F4. Later, in the bug ticket I found for this on Bugzilla, I also discovered a workaround: Alt + Tab to another window, then Alt + Tab back and the picker dialog can be navigated with the keyboard.

Things are even worse in Safari. The input isn’t even focusable (bug ticket) if VoiceOver isn’t on. And even when using VoiceOver, tabbing through the dialog the inputs opens is impossible.

If you’d like to use <input type='color'> on an actual website, please let browsers know this is something that needs to be solved!

How to look inside

In Chrome, we need to bring up DevTools, go to Settings and, in the Preferences section under Elements, check the Show user agent shadow DOM option.

How to view the structure inside an input in Chrome.

Then, when we …

Weekly Platform News: HTML Inspection in Search Console, Global Scope of Scripts, Babel env Adds defaults Query

In this week’s look around the world of web platform news, Google Search Console makes it easier to view crawled markup, we learn that custom properties aren’t computing hogs, variables defined at the top-level in JavaScript are global to other page scripts, and Babel env now supports the defaults query — plus all of last month’s news compiled into a single package for you.

Easier HTML inspection in Google Search Console

The URL Inspection tool in Google Search Console now includes useful controls for searching within and copying the HTML code of the crawled page.

Note: The URL Inspection tool provides information about Google’s indexed version of a specific page. You can access Google Search Console at https://search.google.com/search-console.

(via Barry Schwartz)

CSS properties are computed once per element

The value of a CSS custom property is computed once per element. If you define a custom property --func on the <html> element that uses the value of another custom property --val, then re-defining the value of --val on a nested DOM element that uses --func won’t have any effect because the inherited value of --func is already computed.

html {
  --angle: 90deg;
  --gradient: linear-gradient(var(--angle), blue, red);
}

header {
  --angle: 270deg; /* ignored */
  background-image: var(--gradient); /* inherited value */
}

(via Miriam Suzanne)

The global scope of scripts

JavaScript variables created via let, const, or class declarations at the top level of a script (<script> element) continue to be defined in subsequent scripts included in the page.

Note:Axel Rauschmayer calls this the global scope of scripts.”)

(via Surma)

Babel env now supports the defaults query

Babel’s env preset (@babel/preset-env) now allows you to target browserslist’s default browsers (which are listed at browsersl.ist). Note that if you don’t specify your target browsers, Babel env will run every syntax transform on your code.

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": { "browsers": "defaults" }
      }
    ]
  ]
}

(via Nicolò Ribaudo)

All the June 2019 news that’s fit

Protecting Vue Routes with Navigation Guards

Authentication is a necessary part of every web application. It is a handy means by which we can personalize experiences and load content specific to a user — like a logged in state. It can also be used to evaluate permissions, and prevent otherwise private information from being accessed by unauthorized users.

A common practice that applications use to protect content is to house them under specific routes and build redirect rules that navigate users toward or away from a resource depending on their permissions. To gate content reliably behind protected routes, they need to build to separate static pages. This way, redirect rules can properly handle redirects.

In the case of Single Page Applications (SPAs) built with modern front-end frameworks, like Vue, redirect rules cannot be utilized to protect routes. Because all pages are served from a single entry file, from a browser’s perspective, there is only one page: index.html. In a SPA, route logic generally stems from a routes file. This is where we will do most of our auth configuration for this post. We will specifically lean on Vue’s navigation guards to handle authentication specific routing since this helps us access selected routes before it fully resolves. Let’s dig in to see how this works.

Roots and Routes

Navigation guards are a specific feature within Vue Router that provide additional functionality pertaining to how routes get resolved. They are primarily used to handle error states and navigate a user seamlessly without abruptly interrupting their workflow.

There are three main categories of guards in Vue Router: Global Guards, Per Route Guards and In Component Guards. As the names suggest, Global Guards are called when any navigation is triggered (i.e. when URLs change), Per Route Guards are called when the associated route is called (i.e. when a URL matches a specific route), and Component Guards are called when a component in a route is created, updated or destroyed. Within each category, there are additional methods that gives you more fine grained control of application …