Tutorials on Composition

Learn about Composition from fellow newline community members!

  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL
  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL

Creating A Split Component

Photo by  Cassie Matias  on  Unsplash For the longest time, floats were the go-to tool for putting two things next to each other. Unfortunately, since this is not what floats were designed for, this created as many problems as it solved. Luckily, modern CSS makes this much easier to solve. Let's take the following layout: In this layout we need to be able to split the two children into fractional parts of the partents width while maintaining a gutter between them. Let's say we start with the following basic markup. What we need to do is build a Split component that will fractionally split the width of the outer dive between the div  that is wrapping the h2  and span  and the Form  component. There is a couple of ways we could tackle this, but the easiest would be to use CSS grid: In the above code, first we set the display  property to grid  and set the gap property to 1rem . This will create a grid container that puts a gap of 1rem  between each of the children of the Split component. In the final line we are setting the   grid-template-columns  property. The grid-template-columns property allows us to define how many column tracks we have and how wide they should be. We define the width of each column track using any valid CSS size unit, and the quantity of tracks is determined by how many sizes we assign to the property. For example, if we wanted three column tracks of 30px , 50% , and 2rem , It would look like this: Looking back at the Split component above, you will notice that we are using a special size unit that you might not recognize. The fr unit is a unique size unit only available when using CSS grid. The fr unit (or the fraction unit as it is sometimes called) says to the browser, "give me X fraction(s) of the remaining space available." If we set the grid-template-columns to be 1fr 1fr , which will result in two columns with a 50/50 split, like this: It is essential to distinguish that fr is not the same as % . When we use % , we are saying give me a percentage of the total width of my parent component. What that doesn't take into account is the gutter between the elements. So using 50% 50% would result in an overflow, where 1fr 1fr would not. The mockup above doesn't call for a 50/50 split though. The requirement is to split it into thirds, with the first column taking up only 1/3. Also, hard-coding column tracks do not make for a useful primitive. We need something more configurable that we can adjust to the situation. So let's make the following changes: Now, instead of hard-coding values, we have named our fractions according to the ratio we want them to take and now we can update our FormSideBar component like this: Now we have a component that lets us fractionally split anything among two children.  The Split component works great for any time you want to put two elements next to each other, such as for side bars.

Thumbnail Image of Tutorial Creating A Split Component

How to Build a Composable Stack Component

Photo by  Sean Stratton  on  Unsplash One of the simplest and yet most common layout patterns found on the web is putting one element on top of another element with consistent space between them. From form labels, to paragraphs of text, to social media feeds. They all need to stack one thing on top of another with uniform space between them.  Let's say we are building the following component: As you will notice, we have a few parts to this widget. There is a title section and a form section made up of two input groups and a button. The one thing that they all have in common is that they follow the same pattern. They all stack vertically with space between them. Here is the same mockup with the different space sizes pointed out. What we need is a way to enforce that all the items will stack in the block direction. We also need a way to provide consistent space between the elements without creating space around the stacked elements themselves. That way, the stack can remain composable in any other environment. (I will be using Styled Components  in these examples, but everything can easily be translated to any flavor of CSS, including vanilla CSS.) Let's start with some basic markup. And this is what that looks like: The first problem we want to solve is to get the labels to stack on top of our inputs. This problem is easily solved with a single line of CSS: We create a new Stack component and set the display property to grid , thereby implicitly setting a single column track for items inside the Stack. Each item that is placed in that column creates an implicit row. We can then use this new Stack a component like this: Our component has already taken a major step in the right direction: The first thing you will notice is that not only are the labels stacked on top of each other, they also now take up the entire width of the column. All we need to do now is set the space between the items. We set the space between items using the gap property, which takes any valid sizing unit, such as px , % , or rem . To make it configurable via props, we will take advantage of the styled-components string interpolation and derive the value from props, like this: (If the syntax above is unfamiliar to you, it uses tagged template literals that are part of ES2015. You can find out more about tagged template literals over at MDN ) When we use styled.div we are calling a tagged template literal that will let us pass in a function inside the ${} that gives us access to the component props . We can then customize what the CSS looks like depending on the value of the props . The above code takes the value of the gutter prop and uses that as the value of the gap property. We could have used any name for the prop , such as space or even gap . I chose to use gutter as it is a common term when talking about page layouts. If no value is passed to gutter , it will fall back to 1rem . This means we can rewrite our Subscribe  component like this: And now our component looks like the final version: We have a component that will universally stack all of its children and will separate them via a configurable value that passed into the gutter prop. We could stop here, but I would recommend one more tweak to the gutter prop. Right now, we are allowing any value passed into the gutter. It is considered best practice to adopt a spacing scheme when you are laying out items on the web for consistency. Choosing a good spacing scheme is beyond the scope of this post. For simplicity, let's use a spacing scheme based on t-shirt sizes and looks something like this: Now, all we need to do is adjust our Stack component slightly, like this: and update our Subscribe  component like this: The Stack component is a straightforward yet powerful tool that allows you to compose vertical stacks of elements on your page.  

Thumbnail Image of Tutorial How to Build a Composable Stack Component

I got a job offer, thanks in a big part to your teaching. They sent a test as part of the interview process, and this was a huge help to implement my own Node server.

This has been a really good investment!

Advance your career with newline Pro.

Only $30 per month for unlimited access to over 60+ books, guides and courses!

Learn More

Composing Layouts

Composition, simply put, is when you build something greater than the sum of its parts. For example, an organism is composed of organs, which are composed of organ parts, which are composed of cells, which are composed of atoms. A musical composition can be broken down to nothing more than masterfully applying rhythm and tempo to 12 unique notes, creating all of our musical masterpieces. Composition also applies to web layout. Complex layouts can be broken down into simpler "layout primitives," as described by Heydon Pickering . These layout primitives are single-purpose layout components that do one thing and one thing well. It is by strategically combining these primitives that we achieve more complex layout structures. Let's take the below hero layout, for example: Naively we might choose to do something like this: Several CSS methodologies like BEM , Object-Oriented CSS(OOCSS) , or Atomic CSS  can help create more consistent class names and are generally useful in managing our CSS style sheets at scale. Unfortunately, those methodologies can only get you so far. When we approach our component's layout as something unique for each component, we miss a fantastic opportunity to define a consistent visual structure in our application. Instead, all of our layouts are treated as unique things that need to be built from scratch over and over again. Instead of looking at our Hero component as one isolated element, let's break it up into smaller, single-purpose layout components, like this: (Don't worry about how these components are implemented right now. Just focus on the intended outcome of the components.) Then we can apply these layout components like this: In code, this would translate to something like this: These "layout primitives" can be applied in a signup form, a blog post feed, a feature page, or any other part of our web page. Most of the layouts we use every day are not that unique and can be broken down, at least in part, to one of a handful of layout patterns. Thinking in terms of layout composition can feel strange at first. Probably one of the more difficult parts is knowing **where** you should apply your style rules in your component.

Thumbnail Image of Tutorial Composing Layouts

Encapsulated CSS

Photo by  Mika Baumeister  on  Unsplash Most modern frameworks, like React, use components as their foundation. They do this for a few reasons, but a crucial one is that components allow you to break your app into simple single-purpose parts that can then be composed together to solve more complex needs. Unfortunately, CSS was invented to solve problems from the top down,  starting with more general rules to more specific rules . Components encourage you to start from the bottom up, breaking your pages down into the more specific parts first, often in isolation to the whole, and then composing them together.  Many tools and naming conventions have been created to help us maintain our style sheets like BEM, SASS, Less, CSS-Modules, and CSS-in-JS, but they all fall short in the one problem that tooling can never solve:  Which component should be in charge of which styles? The answer to this question is key to making composition work, especially where web layout is concerned. That answer is Encapsulated CSS. Encapsulated CSS is a term that summarizes the rules of how to apply CSS styles in a composable way. It’s based on the programming principle of encapsulation. If we were to define encapsulation in a language-agnostic way, encapsulation involves grouping related things and restricting access to those things except through appropriate channels. For example, many program languages utilize a module system, which follows the principles of encapsulation. When you import a module like React , you get a group of functions that help you build a React application, but you don’t have access to the actual internals that make a React applications work.  Encapsulated CSS is based on that same principle. It’s a methodology that helps group-related styles at the correct component level and only applies styles through appropriate channels. There are two essential principles of Encapsulated CSS: The first principle is:  “Elements do not lay themselves out.”  When I say that elements don’t lay themselves out, I am specifically speaking to an element's position, size, and margin. The second principle is:  “Elements style themselves and layout only their immediate children.”  Properties that involve the border-box and inward are considered part of the component and therefore they should be applied at the element level. This also includes the layout environment of the component’s immediate children. Therefore, it is the parent component’s responsibility to set its direct children's position, size, and margin. If a component shouldn’t set its own layout properties, how do you set them? I mentioned earlier that encapsulation allows you to access properties through appropriate channels. These appropriate channels in components are props and the direct child combinator. In React, we use props as inputs to our component, much like functions use arguments. Our components use these props in our components. Just like we can expose a label or an onClick prop, we can expose layout properties like margin-top or min-width: Using props in this manner works well with one or two properties, but it becomes unwieldy quickly as you expose more and more properties. The props of your component should also be a reflection of what your component does. Having an arbitrary marginLeft prop doesn’t make sense on a calendar component. The other channel for adding styles is using the direct child combinator in the parent component. This tool allows us to select any or all of our parent containers’ immediate children and apply the layout styling we need.  Let’s take the following Blog Post component: Applying styles that follow the principles of Encapsulated CSS, we could do something like this: In the above stylesheet, the .blog-post and .blog-title classes set their own non-layout-related styles. However, when we needed to set layout properties on any of the elements, we used the direct child combinator to select the appropriate children of the .blog-post to set those properties. For example, we use  .blog-post > h2 to select the h2 tags that were direct children of the .blog-post class to set the layout properties we needed. At this point, one might start to ask why bother to go through this ceremony of adding a separate rule for the direct children just to add a layout property? One could argue that you could write less CSS by just applying the layout properties to the corresponding element.  First of all, because we didn’t add any layout properties to the .blog-post class, this blog post component can safely be placed in any context and not interfere with the layout environment that it is being put. The children can also now be refactored into components, if needed, and won’t bring along the baggage of the layout environment it was initially created in. It also helps with debugging. One of the most significant difficulties of debugging CSS is determining where your styles are coming from. It is easier to track down styles if you have rules in place where those style properties originate. If the style you are looking for is layout-related, you know that the style must be on the parent element. Encapsulated CSS is about creating restrictions that make sense and encourages you to write code that is easier to maintain and refactor. By following these rules, your components will become much easier to refactor and compose anywhere in your app.

Thumbnail Image of Tutorial Encapsulated CSS