Apple’s latest Mobile Safari (iOS 10.3.1) has broken resize behaviour.
Up until recently Mobile Safari has correctly posted the resize event after the viewport was resized and after page layout. However, that’s no longer the case. Instead it’s posted before the page has been completely laid out. Any JavaScript relying on clientWidth, clientHeight, getBoundingClientRect etc. in an onresize callback is now broken.
Upon observing this new behaviour, my first thought was “How did the Mobile Safari team not notice this? Surely it impacted Apple’s own website!”
So I set out to check Apple’s homepage.
Now, anything sized using pure CSS is going to be unaffected by the change, it’s only DOM elements sized by JavaScript resize callbacks that are going to affected. Lucky for me, right at the top of Apple’s homepage is an image carousel currently advertising the Red iPhone 7, Apple Watch Series 2 and iPad. Carousels are generally pretty heavily reliant on JavaScript for sizing, in fact, it’s my own carousel not working that led me on this wild goose chase!
Alright, let’s watch this carousel as I rotate from portrait to landscape. Sure enough, just as the rotation completes…
“Ah, Yuck!”
Curiously though, this glitchy layout, whilst 100% reproducible, is only visible very briefly, then the webpage layout recovers somehow.
I wonder how they’re working around the problem. Let’s take a squiz at their carousel code…
Oh come on, seriously!? A 500ms timeout… “debounced”… what is this nonsense? Why 500ms? Why not 400ms, or 600ms?
Okay, so at this point I feel a bit better about my carousel breaking. After all, Apple are themselves reliant on terrible hacks to work around their browser’s cruddy behaviour. However, the relief is short-lived as I realise that if I’m going to “fix” my carousel, I’m going to have to implement something equally awful.
Sigh!
Well, Apple, looks like you’ve won another round of Apple vs. Developer. Please, I don’t want to see the scoreboard.