The thing I like most about web development is that you never stop learning new properties and tricks. These past few months have been weird; working from home, having the company I've worked at for three years stop, and starting as a freelancer. It's been a while since writing my last post, for all those reasons and more, but today I decided to pick it up again and write about all the small triumphs I've had this year learning new things!
Fill available
In the Safari iOS browser 100vh is calculated on the viewport height regardless of the visibility of the bottom navigation bar. While this is fine most of the time, and is probably preferable to the other option, in which element heights are recalculated when you scroll slightly up, it can be a very weird bug on fixed scrollable containers (like the popups in the following example).
This is a bug many developers have been pulling their hair out to fix for many many years.
Then in April Matt Smith tweeted this and it almost made up for being socially isolated for a month by that point.
The best way to implement this in my opinion is like Matt does, with a backup for browsers that don't yet understand this property, for example;
.container {
height: 100vh;
height: -webkit-fill-available;
height: fill-available;
}
Interaction based media queries
I think I'm a bit late to the party, but this might be my favourite CSS discovery this year. It's supported by all modern browsers and allows you to style based on a user's primary input mechanism. The great thing about media queries like these is that you don't have to rely on using screen size media queries which don't always correspond with modern devices (looking at you iPad Pro).
Possible options are pointer
, any-pointer
, hover
, and any-hover
, the beautiful thing about pointer
is that it accepts coarse
, fine
or none
taking in account the specificity of the pointer device's input. This would allow you to create slightly larger CTA's, inputs or checkboxes for devices that have a coarse pointer input to create a more accessible experience β¨. I believe the fine pointer value is implemented when a user is using a stylus, but I'm not sure.
I have used the hover
property a handful of times, mostly to create custom cursors, which obviously do not have to show on touch devices.
Example:
@media (pointer: coarse) {
input[type="checkbox"] {
width: 1.5rem;
height: 1.5rem;
}
}
Intersection Observer API
This is one of the best ways to create scroll position based animations and I could write an article solely on this. I've learned a lot about it from reading this Mozilla article.
It's supported in all modern browsers and allows you to call functions when elements come in to view (or are intersecting) in your viewport.
const header = document.querySelector('.header');
const inView = (entries) => {
for (const entry of entries) {
// try logging entry to view all the possible values
if (entry.boundingClientRect.y < -32) {
header.classList.add('background--dark'); // for example change the background of the header when the page has scrolled 32 px.
} else {
header.classList.remove('background--dark');
}
}
};
// threshold is just one of the options you can pass in the InteractionObserver
// It determines the amount of triggers while scrolling, it allows an array of numbers between 0 and 1
let threshold = [];
for (let i = 0; i <= 100; i++) {
threshold.push(i / 100);
}
const observePageHeader = new IntersectionObserver(inView, { threshold });
// observing the element that has .header as a class
observePageHeader.observe(header);
It can be used to create lazy loading images or play videos only when they're in view. Or add styles and animations to elements at certain scroll positions.
I was also pleasantly surprised it still worked while using the Locomotive scroll library!
Perspective
Apparently, when you set the css perspective
property and create a horizontally scrollable container it creates a sort of out of the box scroll animation? Weird stuff!
Found this unexpected feature while working on a way to create a sort of scrollable timeline:
Bonus: learn from my mistakes
I've spent waaaay too many hours trying to fix a 'bug' where a container wouldn't scroll on mobile iOS but would on desktop. It appears using pointer-events: none
on a parent element can really screw up the ability to scroll inside a scrollable container on iOS.
Top comments (8)
Whoa, the
perspective
property looks soooo dope! π₯Very nice portfolio - great work!
Hi CYD
Your articles are awesome, it alawys help me to discove new things.
Thanks for everything you wrote.
Great π
Sometimes it takes a lot of time for me to find what's actually messing up with my site. Some experiments lead to some another bugs. π
Ah yes, the bugs related to fixing a bug! π€―
Very cool I learned some stuff I did not know thanks.
This Intersection Observer API thing seems to be such a nice tool to work with, I'll have a look !
Thank you for sharing your experience it is really helpful.
Yessss itβs the best!