Speaking of cool CSS stuff you can buy, Julia Evans’ zine Hell Yes! CSS! is hot off the presses. A “zine” being 28 pages of “short, informative, and fun comics which will quickly teach you something useful.” Some parts of it are like cheat sheets. Some parts of it are like concepts made digestible through the relaxed format. Some parts of it are like mini-tutorials. There is definitely some uhmmmm wow weird moments in there that might stump even CSS smarties, like this inline-block behavior.
Managing freelancers can be twice as hard when compared to managing employees in an office. If you think about it, these are people you haven’t truly met yet, and you can’t even see what they’re doing all the time. What you know about them is only based on what is written on their resume.
So how do you manage people who are from other parts of the world? Below are eight ways you can effectively do this:
Recruit the right freelancers
This first step is very important. This doesn’t mean that you should only hire freelancers with impressive skills, but more important than that is to hire freelancers that you can rely on and are trustworthy.
One of the best ways to find trustworthy freelancers is to ask for recommendations from your team. But, if you want to expand your search, you can opt to go through freelancing platforms.
Post on job boards and once you’ve gotten applications, make sure you check their reviews, social media accounts, and experience and education. You can also ask for some work samples to assess if they’re who you’re looking for.
Set clear goals
Before even creating a team, make sure you have set clear goals. What are you planning to do with your business? Why do you need a team? What tasks are you looking for them to accomplish? What results are you looking for?
Once you know the answers to these questions, it’s the only time you can search for the right people. People that will resonate with your goal and value it as much as you do. It’s also easier to communicate what you expect of them and what results that you’re looking for.
In short, setting clear goals will help ensure that you and your team are all on the same page. This also helps in motivating them to always give their best so you can accomplish the goals.
Avoid communication mishaps
Communicating effectively is one of the biggest challenges when working remotely. This is why it’s very important to have a good communication system. There are four systems most business owners follow:
Daily Check-Ins: So this is just usually a quick chat at the start, middle, or end of the day to see how your team is doing.
Daily Email Summaries: Aside from checking in on your team, you can ask them to send you an email with a detailed report on what they’ve done for the day, how many hours they worked, etc.
Weekly 1-on-1 Meetings: If you only have a small team, it’s also great if you can communicate with them deeply once a week.
Weekly All-Hands Meetings: If you can’t do a 1-on-1 meeting, you can also plan whole group meetings.
Frequent communication helps ensure that you and your team are always on the same page. It also helps in monitoring progress and ensuring your team that you’re always there to help.
Track their work time
You can’t control what’s happening in a business daily. So there will be days where you’ll be too busy to check in with your team. So, let a time tracker do the monitoring for you.
Most business owners utilize time trackers to know exactly what freelancers do at a given time. You can monitor the tasks they did on the day and how many hours they dedicated to it.
Use the right tools and apps
Managing a remote team is not easy, but it’s great that you can use tools and apps to manage teams effectively. Some of the most used apps are:
Trello for easy collaboration
Slack for easy communication
ResourceGuru if your team has a flexible schedules
What freelancer management system to use will highly depend on what you need. Just do a quick search in Google, and you’ll find a list of apps to use.
Refrain from micromanaging
Next, don’t be the manager that micromanages your team. If there’s one thing most freelancers don’t like is that feeling of being controlled.
Trust is very important in remote work, and if you continue to micromanage, you’re showing your team that you’re not satisfied with what they do. It lowers their morale, and might even lose their motivation to keep on doing their best.
So, if you think you’ve hired the right people, trust them. Train new hires, delegate tasks, and trust them with responsibility. You don’t need to go back and forth with them about the deliverable. They know what they’re doing.
Provide feedback
Feedback will always help your team improve. Just make sure that you are providing constructive criticism.
Make sure you focus on the work done and don’t take anything personally. You can be straightforward, but don’t be too condescending. And if you have set some guidelines, stick to them and don’t change instructions right after you’ve seen the work.
Build a relationship with them
Lastly, build a relationship with your team. How? You only need four things:
Proper Communication
Understanding
Providing Resources
Showing Appreciation
This makes your freelancers happy and will continue to be motivated to do their best so you can reach your goals.
Conclusion
Managing freelancers is not easy, but it shouldn’t be as hard as you think, too. You just need to set your goals, find the right people, and have the right attitude to manage them well. Make use of project management tools and apps, and follow the eight tips above to manage your remote team better.
Managing freelancers can be twice as hard when compared to managing employees in an office. If you think about it, these are people you haven’t truly met yet, and you can’t even see what they’re doing all the time. What you know about them is only based on what is written on their resume.
So how do you manage people who are from other parts of the world? Below are eight ways you can effectively do this:
Recruit the right freelancers
This first step is very important. This doesn’t mean that you should only hire freelancers with impressive skills, but more important than that is to hire freelancers that you can rely on and are trustworthy.
One of the best ways to find trustworthy freelancers is to ask for recommendations from your team. But, if you want to expand your search, you can opt to go through freelancing platforms.
Post on job boards and once you’ve gotten applications, make sure you check their reviews, social media accounts, and experience and education. You can also ask for some work samples to assess if they’re who you’re looking for.
Set clear goals
Before even creating a team, make sure you have set clear goals. What are you planning to do with your business? Why do you need a team? What tasks are you looking for them to accomplish? What results are you looking for?
Once you know the answers to these questions, it’s the only time you can search for the right people. People that will resonate with your goal and value it as much as you do. It’s also easier to communicate what you expect of them and what results that you’re looking for.
In short, setting clear goals will help ensure that you and your team are all on the same page. This also helps in motivating them to always give their best so you can accomplish the goals.
Avoid communication mishaps
Communicating effectively is one of the biggest challenges when working remotely. This is why it’s very important to have a good communication system. There are four systems most business owners follow:
Daily Check-Ins: So this is just usually a quick chat at the start, middle, or end of the day to see how your team is doing.
Daily Email Summaries: Aside from checking in on your team, you can ask them to send you an email with a detailed report on what they’ve done for the day, how many hours they worked, etc.
Weekly 1-on-1 Meetings: If you only have a small team, it’s also great if you can communicate with them deeply once a week.
Weekly All-Hands Meetings: If you can’t do a 1-on-1 meeting, you can also plan whole group meetings.
Frequent communication helps ensure that you and your team are always on the same page. It also helps in monitoring progress and ensuring your team that you’re always there to help.
Track their work time
You can’t control what’s happening in a business daily. So there will be days where you’ll be too busy to check in with your team. So, let a time tracker do the monitoring for you.
Most business owners utilize time trackers to know exactly what freelancers do at a given time. You can monitor the tasks they did on the day and how many hours they dedicated to it.
Use the right tools and apps
Managing a remote team is not easy, but it’s great that you can use tools and apps to manage teams effectively. Some of the most used apps are:
Trello for easy collaboration
Slack for easy communication
ResourceGuru if your team has a flexible schedules
What freelancer management system to use will highly depend on what you need. Just do a quick search in Google, and you’ll find a list of apps to use.
Refrain from micromanaging
Next, don’t be the manager that micromanages your team. If there’s one thing most freelancers don’t like is that feeling of being controlled.
Trust is very important in remote work, and if you continue to micromanage, you’re showing your team that you’re not satisfied with what they do. It lowers their morale, and might even lose their motivation to keep on doing their best.
So, if you think you’ve hired the right people, trust them. Train new hires, delegate tasks, and trust them with responsibility. You don’t need to go back and forth with them about the deliverable. They know what they’re doing.
Provide feedback
Feedback will always help your team improve. Just make sure that you are providing constructive criticism.
Make sure you focus on the work done and don’t take anything personally. You can be straightforward, but don’t be too condescending. And if you have set some guidelines, stick to them and don’t change instructions right after you’ve seen the work.
Build a relationship with them
Lastly, build a relationship with your team. How? You only need four things:
Proper Communication
Understanding
Providing Resources
Showing Appreciation
This makes your freelancers happy and will continue to be motivated to do their best so you can reach your goals.
Conclusion
Managing freelancers is not easy, but it shouldn’t be as hard as you think, too. You just need to set your goals, find the right people, and have the right attitude to manage them well. Make use of project management tools and apps, and follow the eight tips above to manage your remote team better.
This year I had the pleasure of re-launching The Accessibility Project. I spend a lot of time researching and writing about accessibility and inclusive design, so this felt like the cumulation of a lot of that effort. The site now uses all sorts of cool web features like CSS Grid, @supports, and media features, aria-current, Service Workers, and Eleventy. But that’s really not the important bit.
The important bit I learned this year is the same thing I learn over and over again: When it comes to disability, representation matters.
In my exploration, the importance of representation is a layered truth I find myself re-internalizing as I learn more about the different communities that make up the accessibility space. I am extraordinarily thankful to be welcomed into these communities, and grateful to be able to participate in them.
We must, however, acknowledge that it is a lot easier for me to enter into these communities than the other way around. Disabled people frequently face many barriers towards representation in many industries, ours included. Considering that, I thought I’d ask disabled people who work on the web what they’ve learned. Here’s what they told me:
Developer Jennilee Rose comments on increased awareness of accessibility in the framework space:
As an advocate for accessibility in web design/development, something I’ve noticed (not exactly learned per-say, but a trend I’ve seen) is that in probably the last 2-3 years there has been a shift in prioritizing accessibility in JavaScript libraries. I think some of it is that there are devs out there like me who care and are holding devs who create these libraries accountable and helping to create change.
Software Engineer Nadhim Orfali comments on their experience working with design systems, accessibility, and documentation:
Using Vue and scoped packages made it easier and quicker for teams to adopt the design system. Bonus: fair amount of accessibility work is done and documenting all this is a lot easier than previous versions. […] This means that if we need to update documentation about a prop, we can make the change in the prop file itself within a component and only that package will get released (thanks to CI/CD).
User experience designer Francis C. Rupert comments on how quarantine has affected everyone:
In 2020 everyone was struck with a shared Situational Disability by everyone wearing a mask. Hearing loss isn’t necessarily always about volume, but speech discrimination. We collectively lost the ability to distinguish between consonants and vowels, and everyone else sounds garbled through their masks.
Speaking of quarantine, web designer Jen Diaz tells us about some benefits that come with remote work becoming mainstream:
Clients are super-keen to work with remote business partners now that they have little or no choice not to. Which is great — it truly levels the playing field. On a Zoom call, nobody knows that my hands are shaped like lobster claws or that I physically cannot participate in the company bowling league — both things that have raised eyebrows for me at in-office jobs.
Anne Berlin, technical SEO and web manager, also comments on some remote work benefits:
I don’t have to worry about someone coming in with strong fragrance, which can send my brain into haywire. I can control the light level of the room and brightness level of my monitors, and a bit more control over the noise level.
It’s not all good vibes, however. Web developer Olu also chimes in about remote work:
Quarantine has also shown how adaptable companies can be when their backs are against the wall. It’s funny how disabled people can ask for accommodations for years and then when they have no choice suddenly these accommodations are becoming permanent for everyone.
Anne also mentions:
Pressure to pass as abled due to ignorance about “invisible” disabilities or lack of proactively inclusive culture for a range of things including cognitive styles, or issues with overstimulation.
Disability is more than physical access. Managing Director Josh Clayton mentions the cognitive fatigue that comes with framework churn:
The continued use of React is concerning. The JavaScript ecosystem is fragmented, with a lot of people doing a lot of work and nobody producing anything new. I don’t mind investing in technology where I feel like I’m getting something. There’s just so much churn, I don’t bother to keep up. I would like to think it’s not sacrificing future employability if I was going to look for a new job, but when it comes to other person’s money, there’s the “newshiny,” or “is this actually the right thing you should be doing right now?”
What I have learned about the industry is that it is unrepentantly ableist.
While I’m happy to see progress being made on some fronts, we need to understand that doing technical work to make websites accessible is only part of the picture. We need to realize that usable products can be created in exclusionary spaces. Only by including disabled people in the product creation process can we truly improve as an industry.
Thank you to Jennilee Rose, Nadhim Orfali, Francis C. Rupert, Jen Diaz, Anne Berlin, Olu, Josh Clayton, EJ Mason, and everyone else who shared their experiences with me.
Cassidy Williams has been doing a Blogvent (blogging every day for a month) over on the Netlify Blog. A lot of the blog posts are about Next.js. There is a lot to like about Next.js. I just pulled one of Cassidy’s starters for fun. It’s very nice that it has React Fast-Refresh built-in. I like how on any given “Page” you can import and use a to control stuff that would be in a . This was my first tiny little play with Next so, excuse my basicness.
But the most compelling thing about Next.js, to me, is how easily it supports the entire rendering spectrum. It encourages you to do static-file rendering by default (smart), then if you need to do server-side rendering (SSR), you just update any given Page component to have this:
export async function getServerSideProps() {
// Fetch data from external API
const res = await fetch(`https://.../data`)
const data = await res.json()
// Pass data to the page via props
return { props: { data } }
}
The assumption is that you’re doing SSR because you need to hit a server for data in order to render the page, but would prefer to do that server-side so that the page can render quickly and without JavaScript if needed (great for SEO). That assumes a Node server is sitting there ready to do that work. On Netlify, that means a function (Node Lambda), but you barely even have to think about it, because you just put this in your netlify.toml file:
[[plugins]]
package = "@netlify/plugin-nextjs"
Now you’ve got static where you need it, server-rendered where you need it, but you aren’t giving up on client-side rendering either, which is nice and fast after the site is all booted up. I think it shoots some JSON around or something, framework magic.
I set up a quick SSR route off my homepage to have a play, and I can clearly see that both my homepage (static) and /cool route (SSR) both return static HTML on load.
I admit I like working in React, and Next.js is a darn nice framework to do it with because of the balance of simplicity and power. It’s great it runs on Netlify so easily.
What’s one thing I learned about building websites this year? Not all that much.
This year, unlike most previous years, I didn’t explore a lot of new technologies. For obvious reasons, it’s been a difficult year to be as engaged in the hot new topics and to spend time playing around with new things. So, for the most part, I’ve tried to keep calm and carry on.
That said, I did try a couple of things that were new to me. I built my first React application (after stubbornly holding out for so long). This was a bit of a struggle for me, coming from using a fully fledged framework, like Angular, to a strictly UI library, like React, and I learned a lot about the difference between libraries and frameworks in the process.
I also trialled Tailwind to see what a radically different way of writing CSS (or in this case, not writing CSS) could be like. This was a really fun trial and although I’ve gone back to my good-ole-SCSS, I have taken with me the idea of utility CSS classes. For example, I now create utility classes for things like aligning text, so the line text-align: center; is only written once in my CSS file.
But ultimately, I’ve found that my way of building websites hasn’t changed all that much this year. And more importantly, it didn’t have to.
High five to Ahmad Shadeed for releasing his new book, Debugging CSS. I think that’s a neat angle for a book on CSS. There are a ton of books on the general subject of CSS already, so not that they can’t be fresh takes on that, but this feels equally important and less trodden territory.
Browser DevTools help us a ton these days in debugging CSS, but there isn’t exactly a step-by-step guide about about it that I know of. This book leans into that, showing off how to debug really practical and understandable CSS issues with the help of DevTools when appropriate.
I bought it because I’m a CSS nerd obviously — not really because I feel like I need to bone up on my CSS debugging. I really wanna support Ahmad because he really got the #1 gold star ?? for CSS blogging this year. Every post of his was an extremely well done deep dive into some important area of CSS.
Looks like all the content of MDN is on GitHub now. That’s pretty rad. That’s been the public plan for a while. Chris Mills:
We will be using GitHub’s contribution tools and features, essentially moving MDN from a Wiki model to a pull request (PR) model. This is so much better for contribution, allowing for intelligent linting, mass edits, and inclusion of MDN docs in whatever workflows you want to add it to (you can edit MDN source files directly in your favorite code editor).
Looks like that transition is happening basically today, and it’s a whole new back-end and front-end architecture.
Say you wanted to update the article for :focus-within. There will be a button on that page that takes you to the file in the repo (rather than the wiki editing page), and you can edit it from the GitHub UI (or however you like to do Git, but that seems like right-on-GitHub will be where the bulk of editing happens). Saving the changed document will automatically become a Pull Request, and presumably, there is a team in place to approve those.
We think that your changes should be live on the site in 48 hours as a worst case scenario.
Big claps from me here, I think this is a smart move. I can’t speak to the tech, but the content model is smart. I’d maybe like to see the content in Markdown with less specialized classes and such, but I suspect that kind of thing can evolve over time and this is already a behemoth of an update to ship all at once.
In August 2020, the entire MDN (writers) team was laid off, so it looks like the play here is to open up the creation and editing of these technical docs to the world of developers. Will it work? It super didn’t work for the “Web Platform Docs” (remember those?). But MDN has way more existing content, mindshare, and momentum. I suspect it will work great for the maintenance of existing docs, decently for new docs on whatever is hot ‘n’ fresh, but less so for anything old and “boring”.
Seems a little risky to fire all the writers before you find out if it works, so that speaks to the product direction. Things are changing and paying a content creation team directly just ain’t a part of whatever the new direction is.
Here’s a scenario. You start a banging Kendrick Lamar track in one of your many open browser tabs. You’re loving it, but someone walks into your space and you need to pause it. Which tab is it? Browsers try to help with that a little bit. You can probably mute the entire system audio. But wouldn’t it be nice to actually have control over the audio playback without necessarily needing to find your way back to that tab?
The Media Session API makes this possible. It gives media playback access to the user outside of the browser tab where it is playing. If implemented, it will be available in various places on the device, including:
the notifications area on many mobile devices,
on other wearables, and
the media hub area of many desktop devices.
In addition, the Media Session API allows us to control media playback with media keys and voice assistants like Siri, Google Assistant, Bixby, or Alexa.
The Media Session API
The Media Session API mainly consists of the two following interfaces:
MediaMetadata
MediaSession
The MediaMetadata interface is what provides data about the playing media. It is responsible for letting us know the media’s title, album, artwork and artist (which is Kendrick Lamar in this example). The MediaSession interface is what is responsible for the media playback functionality.
Before we take a deep dive into the topic, we would have to take note of feature detection. It is good practice to check if a browser supports a feature before implementing it. To check if a browser supports the Media Session API, we would have to include the following in our JavaScript file:
if ('mediaSession' in navigator) {
// Our media session api that lets us seek to the beginning of Kendrick Lamar's "Alright"
}
The MediaMetadata interface
The constructor, MediaMetadata.MediaMetadata() creates a new MediaMetadata object. After creating it, we can add the following properties:
MediaMetadata.title sets or gets the title of the media playing.
MediaMetadata.artist sets or gets the name of the artist or group of the media playing.
MediaMetadata.album sets or gets the name of the album containing the media playing.
MediaMetadata.artwork sets or gets the array of images related with the media playing.
The value of the artwork property of the MediaMetadata object is an array of MediaImage objects. A MediaImage object contains details describing an image associated with the media. The objects have the three following properties:
src: the URL of the image
sizes: indicates the size of the image so one image does not have to be scaled
type: the MIME type of the image
Let’s create a MediaMetadata object for Kendrick Lamar’s “Alright” off his To Pimp a Butterfly album.
if ('mediaSession' in navigator) {
navigator.mediaSession.metadata = new MediaMetadata({
title: 'Alright',
artist: 'Kendrick Lamar',
album: 'To Pimp A Butterfly',
artwork: [
{ src: 'https://mytechnicalarticle/kendrick-lamar/to-pimp-a-butterfly/alright/96x96', sizes: '96x96', type: 'image/png' },
{ src: 'https://mytechnicalarticle/kendrick-lamar/to-pimp-a-butterfly/alright/128x128', sizes: '128x128', type: 'image/png' },
// More sizes, like 192x192, 256x256, 384x384, and 512x512
]
});
}
The MediaSession interface
As stated earlier, this is what lets the user control the playback of the media. We can perform the following actions on the playing media through this interface:
play: play the media
pause: pause the media
previoustrack: switch to the previous track
nexttrack: switch to the next track
seekbackward: seek backward from the current position, by a few seconds
seekforward: seek forward from the current position, by a few seconds
seekto: seek to a specified time from the current position
stop: stop media playback
skipad: skip past the advertisement playing, if any
The MediaSessionAction enumerated type makes these actions available as string types. To support any of these actions, we have to use the MediaSession‘s setActionHandler() method to define a handler for that action. The method takes the action, and a callback that is called when the user invokes the action. Let us take a not-too-deep dive to understand it better.
To set handlers for the play and pause actions, we include the following in our JavaScript file:
let alright = new HTMLAudioElement();
if ('mediaSession' in navigator) {
navigator.mediaSession.setActionHandler('play', () => {
alright.play();
});
navigator.mediaSession.setActionHandler('pause', () => {
alright.pause();
});
}
Here we set the track to play when the user plays it and pause when the user pauses it through the media interface.
For the previoustrack and nexttrack actions, we include the following:
let u = new HTMLAudioElement();
let forSaleInterlude = new HTMLAudioElement();
if ('mediaSession' in navigator) {
navigator.mediaSession.setActionHandler('previoustrack', () => {
u.play();
});
navigator.mediaSession.setActionHandler('nexttrack', () => {
forSaleInterlude.play();
});
}
This might not completely be self-explanatory if you are not much of a Kendrick Lamar fan but hopefully, you get the gist. When the user wants to play the previous track, we set the previous track to play. When it is the next track, it is the next track.
To implement the seekbackward and seekforward actions, we include the following:
Given that I don’t consider any of this self-explanatory, I would like to give a concise explanation about the seekbackward and seekforward actions. The handlers for both actions, seekbackward and seekforward, are fired, as their names imply, when the user wants to seek backward or forward by a few number of seconds. The MediaSessionActionDetails dictionary provides us the “few number of seconds” in a property, seekOffset. However, the seekOffset property is not always present because not all user agents act the same way. When it is not present, we should set the track to seek backward or forward by a “few number of seconds” that makes sense to us. Hence, we use 10 seconds because it is quite a few. In a nutshell, we set the track to seek by seekOffset seconds if it is provided. If it is not provided, we seek by 10 seconds.
To add the seekto functionality to our Media Session API, we include the following snippet:
if ('mediaSession' in navigator) {
navigator.mediaSession.setActionHandler('seekto', (details) => {
if (details.fastSeek && 'fastSeek' in alright) {
alright.fastSeek(details.seekTime);
return;
}
alright.currentTime = details.seekTime;
});
}
Here, the MediaSessionActionDetails dictionary provides the fastSeek and seekTime properties. fastSeek is basically seek performed rapidly (like fast-forwarding or rewinding) while seekTime is the time the track should seek to. While fastSeek is an optional property, the MediaSessionActionDetails dictionary always provides the seekTime property for the seekto action handler. So fundamentally, we set the track to fastSeek to the seekTime when the property is available and the user fast seeks, while we just set it to the seekTime when the user just seeks to a specified time.
Although I wouldn’t know why one would want to stop a Kendrick song, it won’t hurt to describe the stop action handler of the MediaSession interface:
if ('mediaSession' in navigator) {
navigator.mediaSession.setActionHandler('stop', () => {
alright.pause();
alright.currentTime = 0;
});
}
The user invokes the skipad (as in, “skip ad” rather than “ski pad”) action handler when an advertisement is playing and they want to skip it so they can continue listening to Kendrick Lamar’s “Alright” track. If I’m being honest, the complete details of the skipad action handler is out of the scope of my “Media Session API” understanding. Hence, you should probably look that up on your own after reading this article, if you actually want to implement it.
Wrapping up
We should take note of something. Whenever the user plays the track, seeks, or changes the playback rate, we are supposed to update the position state on the interface provided by the Media Session API. What we use to implement this is the setPositionState() method of the mediaSession object, as in the following:
if ('mediaSession' in navigator) {
navigator.mediaSession.setPositionState({
duration: alright.duration,
playbackRate: alright.playbackRate,
position: alright.currentTime
});
}
In addition, I would like to remind you that not all browsers of the users would support all the actions. Therefore, it is recommended to set the action handlers in a try...catch block, as in the following:
Putting everything we have done, we would have the following:
let alright = new HTMLAudioElement();
let u = new HTMLAudioElement();
let forSaleInterlude = new HTMLAudioElement();
const updatePositionState = () => {
navigator.mediaSession.setPositionState({
duration: alright.duration,
playbackRate: alright.playbackRate,
position: alright.currentTime
});
}
const actionsAndHandlers = [
['play', () => {
alright.play();
updatePositionState();
}],
['pause', () => { alright.pause(); }],
['previoustrack', () => { u.play(); }],
['nexttrack', () => { forSaleInterlude.play(); }],
['seekbackward', (details) => {
alright.currentTime = alright.currentTime - (details.seekOffset || 10);
updatePositionState();
}],
['seekforward', (details) => {
alright.currentTime = alright.currentTime + (details.seekOffset || 10);
updatePositionState();
}],
['seekto', (details) => {
if (details.fastSeek && 'fastSeek' in alright) {
alright.fastSeek(details.seekTime);
updatePositionState();
return;
}
alright.currentTime = details.seekTime;
updatePositionState();
}],
['stop', () => {
alright.pause();
alright.currentTime = 0;
}],
]
if ( 'mediaSession' in navigator ) {
navigator.mediaSession.metadata = new MediaMetadata({
title: 'Alright',
artist: 'Kendrick Lamar',
album: 'To Pimp A Butterfly',
artwork: [
{ src: 'https://mytechnicalarticle/kendrick-lamar/to-pimp-a-butterfly/alright/96x96', sizes: '96x96', type: 'image/png' },
{ src: 'https://mytechnicalarticle/kendrick-lamar/to-pimp-a-butterfly/alright/128x128', sizes: '128x128', type: 'image/png' },
// More sizes, like 192x192, 256x256, 384x384, and 512x512
]
});
for (const [action, handler] of actionsAndHandlers) {
try {
navigator.mediaSession.setActionHandler(action, handler);
} catch (error) {
console.log(`The media session action, ${action}, is not supported`);
}
}
}
Here’s a demo of the API:
CodePen Embed Fallback
I implemented six of the actions. Feel free to try the rest during your leisure.
If you view the Pen on your mobile device, notice how it appears on your notification area.
If your smart watch is paired to your device, take a sneak peek at it.
If you view thePen on Chrome on desktop, navigate to the media hub and play with the media buttons there. The demo even has multiple tracks, so you experiment moving forward/back through tracks.
If you made it this far (or not), thanks for reading and please, on the next app you create with media functionality, implement this API.
The HTTP Archive looked at more than 7 million websites and compiled their annual report detailing how the sites were built. And there’s an enormous wealth of information about how the web changed in 2020. In fact, this report is more like an enormous book and it’s entirely fabulous. The data comes from making queries to the HTTP Archive and is broken down into various sections, such as Performance, Security, and the languages themselves, including how folks wrote HTML or CSS.
Here’s what the report has to say about the CSS they scanned:
While JavaScript far surpasses CSS in its share of page weight, CSS has certainly grown in size over the years, with the median desktop page loading 62 KB of CSS code, and 1 in 10 pages loading more than 240 KB of CSS code. Mobile pages do use slightly less CSS code across all percentiles, but only by 4 to 7 KB. While this is definitely greater than previous years, it doesn’t come close to JavaScript’s whopping median of 444 KB and top 10% of 1.2 MB
Gasp! And here’s a shocking bit of info that shortly follows:
[…] only about 7% of pages concentrate all their CSS code in one remote stylesheet, as we are often taught to do. In fact, the median page contains 3 elements and 6 (!) remote stylesheets, with 10% of them carrying over 14 elements and over 20 remote CSS files! While this is suboptimal on desktop, it really kills performance on mobile, where round-trip latency is more important than raw download speed.
I sort of want to quote the whole section about CSS specifically because there’s a lot of interesting facts that show how we, as a community, have a lot of work to do to improve performance and spread the good word about CSS optimization.