My team has recently been focused on a huge backend migration, and as a result we haven't been doing much frontend lately. Seeing as our sprint tasks were finished, I picked up what I thought would be a tiny little CSS fix from the backlog. I've been eager to get some CSS experience in. I also had just finished a couple great tutorials in this series, HTML & CSS Is Hard, where I learned a little bit more about advanced positioning and Flex.
The task? Make the image in a side panel in our embedded checkout modal fixed at the top of the panel, so that with enough content, the image would stay fixed while the rest of the content scrolled behind it. Essentially, the image should be sticky and not scroll away when scrolling.
Below is the before behavior. As you can see, the entire panel scrolls, the image going with it. There's also a fun unexpected little right border on the image.
When I started investigating a fix, I saw that the side panel used display: table, which I thought was curious as the rest of our app generally used Flexbox. Perhaps the developer who wrote this bit of code didn't know that this could be much easier to work with in Flex!
I switched the div back to display: flex and flex-direction: column, and then after some trial and error with the devtools in the browser, ended up setting the width of the child div to 100%, and overflow: auto on the parent, and voila! It worked! The image stayed put at the top and the content beneath it scrolled perfectly behind it. And, that pesky little right border was gone. Great! I moved on to the last part of the ticket, adding a gradient to the bottom of the image to add a visual effect for the content scrolling underneath the image.
After some struggles with that task, I got it all working with border-shadow, and all was well. Below, the new behavior in Chrome: image fixed, beautiful gradient applied below it. A sigh of relief.
But not for long. In code review it was pointed out that the reason why the div was using display: table was because of a bug with Flexbox in IE 11. Sure enough, after testing the fix in my IE 11 virtual machine, I saw the previous issue. =( =( =(
Internet Explorer 11 has trouble with scaling and calculating sizes as Flex requires. For others' struggles with this bug, check out this link.
I was ready to quit by this point. Moving back to display: table would mean having to start over on this whole bug fix. Arggghhh!!!
I got some help from the hubby from here luckily. His years of frontend experience have made him much more patient than me. He looked at the problem, asked me one question, "What size is the image?" to which I replied "Well as it's all responsive, it changes. But the ratio is always the same, 2:1."
💡💡💡! Of course, he had an immediate solution. If IE is having trouble calculating the size of the image and div around it, let's just set it explicitly instead. Since the page is responsive we can't set a fixed height and width, but we could use another trick -- using padding-bottom and position: absolute save a space for the image so the browser doesn't have to completely figure it out. Since the image ratio is always 2:1, and since padding-bottom is calculated using the width of the parent, we could set it to 50% and we'd have our perfect 2:1 space left for our image to fill. Voila!! With a couple other small adjustments, it all worked perfectly.
Again, not for long. I was determined to make sure the fixes all worked across browsers, and after testing in IE again, Chrome, and Safari, I was pretty relieved. But then -- Firefox. Of course. The padding-bottom fix unfortunately didn't work correctly in Firefox because of an issue with it calculating that value off of the parent's parent instead of the parent, and it was calculating off of the height instead of width, leaving too much space saved which threw off the rest of the panel.
At this point I brought up this issue with my team, and one of my teammates helped out. After we looked into the Firefox bug online, he suggested just trying creating another div underneath the image and adding the padding-bottom there instead, to see if it would work in Firefox and also for Chrome and the other browsers.
VOILA!!! For real this time though. (Until further notice, I suppose...). It all worked perfectly. Again, here's the new behavior:
A beautiful lesson in the trial and errors of CSS. My first struggles with CSS, and definitely not the last time.
I learned through all this that everyone has their own way of approaching CSS and debugging, and getting help from others is sure to increase my chances of finding a passable fix.
I also learned that I need to be more patient when dealing with CSS, and that I shouldn't take "no" for an answer -- as in, no, this attribute cannot be used in this browser. There is always a way around it through some trick or obscure CSS. I have to be patient so that I can give myself a chance to get more experience with CSS to learn about all of its nuances.