Styling
Arguably the primary purpose—the raison d’etre—of Media Chrome is creating custom media player user interfaces and experiences. It should come as no surprise that we provide a whole lot of ways to easily change its look and feel. In this guide, we’ll go over some of the central ways to style your Media Chrome UI. From CSS variables and parts, to custom slottable icons, to built in styles in Media Chrome’s container components, to out of the box breakpoints support for responsive design, Media Chrome makes it easy to customize the look and feel of a player UI that works best for your use case.
The Basics
Section titled The BasicsJust to have a baseline, let’s start with a simple player UI built with Media Chrome that uses <media-play-button>
.
Media Chrome + CSS Variables
Section titled Media Chrome + CSS VariablesWhile the component looks pretty good out of the box, maybe you want a slightly different color palette. To help make these styling cases easier, Media Chrome provides a set of well defined CSS Custom Properties (also known as “CSS Variables”). Here’s an example where we’ve changed the default color of the <media-play-button>
’s icon, background, and hover background.
You may have noticed that the names of these variables make no specific mention of play buttons or even buttons at all. That’s intentional. Many of our CSS variables are shared across many of our components, and we’ve intentionally named them to account for the scope of where they apply. If you only want them to apply to a particular component, you can use standard CSS selectors to scope them, like the the example above.
Each Media Chrome component has a pretty wide set of useful variables, including the color-related styles you see, font related styles, padding and sizing styles, and several others, which you can find in the reference section of each component’s documentation. For example, you can find a full list of <media-play-button>
CSS Variables here.
Media Chrome + Custom Icons
Section titled Media Chrome + Custom IconsBeing able to easily customize a variety of CSS properties is great, but that’s not where custom styling stops with Media Chrome. For example, for any of our components with icons, you can override the defaults by passing in your version as a child element with the expected slot
attribute, which identifies which state the icon is for. In our case, the <media-play-button>
has both a play
and a pause
slot to customize what’s shown when pressing the button will play or pause the media, respectively. Slots are actually a well defined part of Web Components, but for most use cases you don’t need to worry about that. All you need to know is that adding the slot
attribute with the expected name will ensure the element’s use. Here’s an example of adding custom play and pause SVG icons to our previous example. Notice that these SVGs still inherit our custom icon color.
There are a few things that we typically recommend when using custom icon images. First, while you can slot anything, we recommend SVGs, since they tend to be an efficient and scalable (hence the name) image format that is also easier to do things like tweak the dimensions of. Second, note that there is no height
, width
, or fill
color defined on the SVGs. While not required, this is the best way to ensure that the sizing and coloring styles will be inherited by Media Chrome components. Additionally, note that these icons have both been constructed with a viewBox="0 0 24 24"
. You can always use CSS to tweak these details, but this will help ensure that you won’t have things like unintended whitespace or have to muck around with the padding of things like your button components.
Earlier, I mentioned that you can use whatever you want for your “icons”. This includes other images, a <span>
with some text, or whatever makes sense for your use case. Here’s an example of using Font Awesome Web Font icons. If you take a look at the custom-styles.css
file, you’ll notice that I’m using slightly different CSS variables here (since the “icons” are actually font glyphs) and I also needed to apply some additional styles to the <i>
element to make sure the sizes and layouts are consistent when toggling between “play” and “pause”.
Styling Multiple Components
Section titled Styling Multiple ComponentsIn the previous example, I ended up using different CSS variables for my font-based icons vs. the SVG-based ones. This also applies for other color styles used in Media Chrome components. Since folks will typically want a consistent palette for their media player, Media Chrome has a couple of “color palette” CSS variables that work as defaults for some of the CSS variables used above: --media-primary-color
, which you can think of as a “foreground” color, and --media-secondary-color
, which you can think of as a “background” color. This makes styling multiple Media Chrome components easier with just a few CSS variables.
To demonstrate this, here’s an example with several more components, including a range component (<media-time-range>
), a text-based button component (<media-playback-rate-button>
), and a text-based display component (<media-time-display>
). All of these are styled using just 3 CSS variables. If you look at the custom-styles.css
, you’ll also see some of the related CSS variables commented out so you can experiment with their relationships.
Conditional styling with media attributes
Section titled Conditional styling with media attributesIn the previous example, we added several components, including a captions button and an airplay button. But what if your video doesn’t have any closed captions or subtitles? What if you’re in a browser that doesn’t support AirPlay? As you may already know, Media Chrome works by passing around different media state to its components, including the Media Controller component itself. Because this state will show up as attributes on the relevant components, we can use standard CSS attribute selectors to change styles based on those attributes.
Though not the only use of this strategy, one of the most common use cases is hiding or disabling components. In the example below, I’ve added some attribute selectors to hide the captions and airplay button based on the relevant state. Additionally, I’ve added a toy “banner” that uses <media-text-display>
(to automatically get our Media Chrome CSS variable styles!) that should hide once the video has started playing (even if it’s subsequently paused). For details on these attributes, check out the components in question. Just like our CSS variables, you can find out what media attributes will be passed to a particular component by checking the reference section of the component’s docs. For example, the list of the airplay button’s media attributes can be found here.
Built in container styling
Section titled Built in container stylingAs the custom icon examples above show, updating the look and feel of player UIs with Media Chrome is more than just convenient CSS. We also mentioned at the beginning that you can get a lot of solid styling just by taking advantage of our built in components and functionality. Yet another way we try to bring this easy customization together is through some built in styling and layout you get from Media Chrome’s container components. This next example will show you how to take advantage of these, even moreso when used together with what’s possible with CSS in Media Chrome.
When it comes to our container components, you’ve actually been working with one of them from the beginning, albeit a special one: <media-controller>
. Just like our button icon slots, the Media Controller container component has some well defined slots that will position components in different “regions” above the video. In this example, we’re using the slot="top-chrome"
and slot="centered-chrome"
to add a title and “big play button”, respectively. Note that our slot="top-chrome"
component is positioned at the top left (similar to the other components we’ve been using, which were positioned at the bottom left), whereas our slot="centered-chrome"
component is (shockingly) centered over the video. If you take a look at the custom-styles.css
, you can also see how we’re using some attribute selectors and CSS variables to apply some general styles and then tweak or override them for the components in each slotted region.
In the example, we’ve also replaced the <div>
we were using to lay out our Media Chrome components with a second container component, <media-control-bar>
. This gives us a few things automatically. First, if you either resize the “page” or remove some of the components, you’ll see that the <media-time-range>
will automatically grow to take up as much real estate is available to make seeking easier. Second, you can see how the components will automatically scale based on the available real estate. Finally, by using it with the <media-controller>
, it will automatically grow to fill the entire width of the controller UI.
Responsive CSS design with Media Controller breakpoints
Section titled Responsive CSS design with Media Controller breakpointsSo far, we’ve seen a couple of ways to easily “react” to the environment where the player UI is being viewed. Earlier, we showed how we can use particular media UI attributes to hide components when AirPlay or captions are unavailable. And in the previous example, we’ve seen how we can take advantage of Media Chrome’s container components to automatically scale based on the available real estate. For folks familiar with “responsive design,” you’ll know that you can do a good amount of “app-"" or page-level styling using CSS @media
queries. Unfortunately, for complex components like a media player UI, it’s much more common to want to change the look and feel based on the player’s size, not the page. And we’re still anxiously await more robust support for CSS @container
queries, which would be a great fit for this kind of responsive UI.
Since we know this is typically how most folks would want to build a responsive player UI, we’ve made sure it’s easy for folks to do by building in a concept of “breakpoints” for <media-controller>
. In the example below, you can see a basic implementation of a “mobile first” responsive design, where we apply the most generic styles for the smallest, “mobile” UI and then override them as the player UI gets larger. Like earlier examples, we can take advantage of attribute selectors, this time using breakpointmd
for our standard “desktop” UI cutoff. I’ve also included a simple “extra large” (breakpointxl
) example that makes all of the controls larger (NOTE: For this XL example, you’ll probably need to open the example in Code Sandbox). And, like many features in Media Chrome, while we have some reasonable default values, you may define your own breakpoint cutoffs for more advanced customization.
More complex component CSS
Section titled More complex component CSSMost of our components are simple enough to style in the fairly simple ways we’ve covered thus far. However, a few of our components are made up of some more complex parts. For these, you can directly style these “sub-components” or “sub-sections” by using CSS ::part()
pseudo-element selectors. Like slots above, ::part()
is actually a well defined part of Web Components. For most cases, though, all you need to know is that they are similar to other pseudo-element selectors. Below is an example where we’ve customized some styles on the <media-time-range>
’s thumbnail and time preview box part (visible when hovering over the component). We’ve also added a transluscent overlay using one of the <media-controller>
parts that fades in/fades out just like the control components.