Using CSS Grid to create custom API video call layouts

Learn how we used CSS Grid Layout to develop our custom Daily.co video chat API demo.

We're proud to announce that the Daily.co API now supports custom layout control. You can now customize the styling and layout of any API-generated video call!

This means that you can customize the styling of interface elements such as: buttons, labels, video feeds, informational overlays and more. Fit our video calls into your product, not your product into our video calls.

API customers can choose the layout approach that fits their goals:

1. **No code embedding:** Drop in a finished video chat widget. Simply add an `iframe` to your site using helper methods in our javascript front-end library. [Embedded API demo](https://www.daily.co/api/demo).
2. **Custom layout:** Customize the video call interface with your own CSS and HTML. [Custom API demos](https://daily-co.github.io/daily-js/).

Our layout approach makes customization easy. Contrasted with other APIs — which require heavy lifting to design a UI — our Daily.co API gives teams layout control via CSS and HTML.

## What's a custom layout?

A custom layout means that you can customize the styling of interface elements such as: buttons, labels, video feeds, informational overlays and more. Fit our video calls into your product, not your product into our video calls.

Need to use your brands typography, iconography, or more broadly, design language? Have at it!
With custom layout control — and CSS Grid Layout — you're in complete control over your users' experience.

To help illustrate what's possible, here is a screenshot of a demo we built using CSS Grid Layouts. Check out the [live demo](https://daily-co.github.io/daily-js/demo/demo-css-grid.html) in your browser, now.

Custom layout demo
Custom layout demo created using CSS Grid Layout

# Getting started

Here are some quick links to help you get learn more about this demo and custom layout control.

- Fork our [daily-js GitHub repo](https://github.com/daily-co/daily-js)
- [View all of our custom demos](https://daily-co.github.io/daily-js/). *This post highlights, **Custom CSS Grid Demo**.*
- [Open the CSS Grid Demo](https://daily-co.github.io/daily-js/demo/demo-css-grid.html) in your browser
- [View HTML code](https://github.com/daily-co/daily-js/blob/master/demo/demo-css-grid.html)
- [View CSS code](https://github.com/daily-co/daily-js/blob/master/demo/demo-css-grid.css)

Customizing the styling of your API video chats is really rather simple. Whether your a well-versed front-end engineer or a designer with some basic CSS knowledge you should be able to customize the UI of your video calls. That said, basic CSS and HTML knowledge are required.

## About CSS Grid

CSS grid is a very powerful layout property that allows you to layout elements on a 2-dimensional grid. For a detailed overview, check out [CSS Tricks excellent guide](https://css-tricks.com/snippets/css/complete-guide-grid/). Essentially, you create a grid (your container) and then define where elements (i.e. a `div`) are placed on the grid.

# Creating the CSS Grid Demo

The files for this demo live in [our daily-js repo](https://github.com/daily-co/daily-js) under the `/demo` directory. Specifically, you'll want to check out the [demo-css-grid.html](https://github.com/daily-co/daily-js/blob/master/demo/demo-css-grid.html) and [demo-css-grid.css](https://github.com/daily-co/daily-js/blob/master/demo/demo-css-grid.css) files.

## Styling the demo

The demo-css-grid.css file is the file we used to style the video call elements. These elements, or components, are what are embedded in the calls `iframe`.

For example in the CSS file, `.daily-videos-wrapper` is the grid container and `.daily-video-div` is a video feed element.

### Creating the grid

Before we began we designed our UI in [Sketch](https://www.sketch.com/) so that we could plan for our implementation. Learn from us! After creating this demo, among others, we believe that **you'll save time by planning your grid for your largest meeting scenario**. Define a grid for the largest video call requirement and work backwards from there.

It is easier to position 1 participant on a complex grid structure than it is to position 4 participants on a grid that's too small.

For our prototype we had a max call size requirement of 4 participants — 3 remotes and 1 local. We designed our UI/grid in [Sketch](https://www.sketch.com/) for all of the call sizes before jumping into code!

Grid demo designs created in Sketch
Grid demo designs created in Sketch

From here we had a grid we could work off of. Defining the grid container was then as simple as updating the `.daily-videos-wrapper` class with the following:

    -- CODE language-css --
   .daily-videos-wrapper {
     position: relative;
     display: grid;
     grid-template-rows: repeat(2, 1fr);
     grid-template-columns: repeat(4, 0.5fr);
     overflow-x: auto;
     -ms-overflow-style: -ms-autohiding-scrollbar;
    }

If you inspect the live demo you'll see the following grid overlaid by your browser.

CSS Grid overlay when inspecting demo
CSS Grid overlay when inspecting demo

The grid is created using `grid-template-rows` and `grid-template-columns`. The values for each property generate a grid with 2 rows and 4 columns from which we will then place our UI elements in.

For more information on how to use the fr unit check out [this great post](https://alligator.io/css/css-grid-layout-fr-unit/) from [Alligator.io](http://alligator.io/).

### Positioning an element on the grid

As an example, let's look at how we positioned the local video feed.

To begin we target the `.daily-video-div.local` class. We use `grid-area` to define where on the grid this element is placed.

   -- CODE language-css --
   .daily-video-div.local {
       grid-area: 1 / 1 / span 1 / span 2;
   }

This code is shorthand for the following:

    -- CODE language-css --    
   .daily-video-div.local {
     grid-row-start: 1;
     grid-column-start: 1;
     grid-row-end: span 1;
     grid-column-end: span 2;
   }

- **Row (and column) start is set to 1:** This tells the browser to "start" placing the UI on the first row (and column).
- **Row end is set to span 1:** The UI only fills (spans) one row; which in this case, is the first row.
- **Column end is set to span 2:** The UI will fill (span) two columns. Column 1 and 2.

To better visualize this see the illustration below. The cyan rectangle represents the local video feed UI. You can see that it is positioned in our grid to fill the first two columns that intersect the first row.

An illustration of local video feed grid area
An illustration of local video feed grid area

There are many different ways to define where UI may be positioned on the grid. For example, you can name the areas of your grid using the `grid-template-areas` property — [learn more on CSS Tricks](https://css-tricks.com/snippets/css/complete-guide-grid/#prop-grid-template-areas) — or you can [name the lines of your grid](https://css-tricks.com/snippets/css/complete-guide-grid/#prop-grid-template-columns-rows) and then position your UI elements accordingly.

Further, items can be placed over one another or across similar areas.

### Placing more UI

The concepts above are used to place remote participants as well. For example when 3 people are in the call a class of `.remote-cams-N` is dynamically added to the `.daily-videos-wrapper` and `.daily-video-div` elements. These classes represent a call where a local participant, plus N remote participants are in the call.

- `.remote-cams-2` — 2 remote participants, 1 local
- `.remote-cams-2` — 3 remote participants, 1 local
- `.remote-cams-4` — 4 remote participants, 1 local
- Etc.

Throughout this demo we use these classes to reposition the video feeds in our grid based upon the call size.

The `nth-child` selector is used to individually place video feeds. Here's the code from the demo for a 3 person call — 2 remote participants and 1 local participant:

    -- CODE language-css --
   /** 3-person call**/
   .daily-videos-wrapper.remote-cams-2 > .daily-video-div.remote:nth-child(2) {
    grid-area: 1 / 3 / span 1 / span 2;
   }
   
   .daily-videos-wrapper.remote-cams-2 > .daily-video-div.remote:nth-child(3) {
    grid-area: 2 / 3 / span 1 / span 2;
   }

### Responsive design

CSS grid makes responsive implemenation quite a breeze!

We use the same logic as above to reposition components for smaller breakpoints. For the purpose of this demo, we simply target one media query, `@media (max-width: 800px) { … }`, and have added styling as needed to each element.

## Controller and informational overlays

In order to add in-call controls — camera, microphone, leave, etc. — to the video call, we've customized the demo-css-grid.html file.

Think of this file as your the video call experience in your product. This is the bones of the video call controller plus the call elements itself, which are rendered as an iframe.

To add the controller and participant UI shown in the demo, as well as the "Loading your video feed…" overlay, we essentially duplicated the grid layout from the `demo-css-grid.css` file so that we could position our controller elements appropriately.

In the demo-css-grid.html file:

- Line 137: `#ui-container` creates the grid container
- Line 138: `#ui-local` creates the "Loading your video feed…" overlay
- Line 143: `#ui-controller` adds the in-call controls for camera, microphone, screen share and leave/join

Again, you can use media queries to reposition elements in your grid layout, at different breakpoints. As we've done for the `#ui-controller` element.

## Further customization

Going a level deeper, we wrote some functions to update the ID's of elements based upon different states in a meeting. For example, when you are alone we have a function that allows us to display UI specific to that scenario.

You can customize your experience as needed.

---

Customizing your interface with CSS Grid Layouts offers developers a lot of flexibility. You can even utilize Flexbox Layout and/or standard positioning, in conjunction with Grid Layout, for even more control over your UX.

As always, it helps to start building with a design or plan in place. We first designed our UI in Sketch in order to have a solid starting place from which to implement.

If you have any other questions about CSS Grid please do not hesitate to reach out! We are very excited to see what folks will create using the [Daily.co API](http://daily.co/api), and are proud to offer custom layout control.

Recent posts