[solved] Need workaround to make CSS grid work on IOS Safari

According to https://caniuse.com/#search=grid, Safari IOS has issues with CSS grid, including when dealing with grid properties such as grid-template-columns (which I am using…).

Known issues:

  1. Safari does not yet support intrinsic and extrinsic sizing with grid properties such as grid-template-rows

This is how my styling looks like on IOS safari (you need to use an IOS device to see this. devTools will not show you the bad styling - on devTools it all renders beautifully)

I have been trying all sorts of things to make this look proper to no results. Has anyone been able to find a workaround for this IOS safari issue in the past? Pointers more than welcome.

The CSS code:

 body {
     font-family: 'Helvetica Neue', sans-serif;
     font-weight: 400;
     height: 100%;
     width: 100%;
     margin: 0;
     padding: 0;
     background: #53687e;
     background: linear-gradient(120deg, #53687e, hsl(0, 0%, 18%)) fixed;
 }

 #calculator {
     margin: 0 auto;
     text-align: center;
     padding-top: 100px;
 }

 .container {
     position: relative;
     line-height: 1.5;
     display: flex;
     align-items: center;
     justify-content: center;
     padding-bottom: 50px;
 }

 .key-group {
     display: grid;
     grid-template-columns: 1fr 1fr 1fr 1fr;
     grid-gap: 10px;
     align-items: center;
     justify-content: center;
     background-color: #000;
     padding: 8px;
     border-radius: 8px;
     box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.7);
 }

 .key-pad {
     cursor: pointer;
     background: #33373f;
     color: #ffff;
     border-radius: 8px;
     font-size: 2.5rem;
     border-style: none;
     padding-right: 50px;
     padding-bottom: 50px;
     padding-left: 50px;
     */
 }

 .display {
     grid-column: 1 / span 4;
     grid-row: 1;
     color: #51aaff;
     background: none;
     height: 5rem;
     display: flex;
     align-items: flex-end;
     justify-content: flex-end;
 }

 .seven {
     grid-column: 1 / span 1;
     grid-row: 2;
 }

 .eight {
     grid-column: 2 / span 1;
     grid-row: 2;
 }

 .nine {
     grid-column: 3 / span 1;
     grid-row: 2;
 }

 .divide {
     grid-column: 4 / span 1;
     grid-row: 2;
     color: #51aaff;
     background-color: #1e242c;
 }

 .four {
     grid-column: 1 / span 1;
     grid-row: 3;
 }

 .five {
     grid-column: 2 / span 1;
     grid-row: 3;
 }

 .six {
     grid-column: 3 / span 1;
     grid-row: 3;
 }

 .multiply {
     grid-column: 4 / span 1;
     grid-row: 3;
     color: #51aaff;
     background-color: #1e242c;
 }

 .one {
     grid-column: 1 / span 1;
     grid-row: 4;
 }

 .two {
     grid-column: 2 / span 1;
     grid-row: 4;
 }

 .three {
     grid-column: 3 / span 1;
     grid-row: 4;
 }

 .subtract {
     grid-column: 4 / span 1;
     grid-row: 4;
     color: #51aaff;
     background-color: #1e242c;
 }

 .zero {
     grid-column: 1 / span 1;
     grid-row: 5;
 }

 .decimal {
     grid-column: 2 / span 1;
     grid-row: 5;
 }

 .clear {
     grid-column: 3 / span 1;
     grid-row: 5;
     color: #51aaff;
     background-color: #1e242c;
     font-size: 2rem;
     height: 100%;
     width: 100%;
 }

 .add {
     grid-column: 4 / span 1;
     grid-row: 5;
     color: #51aaff;
     background-color: #1e242c;
 }

 .equals {
     grid-column: 1 / span 4;
     grid-row: 6;
     color: #51aaff;
     background-color: #1e242c;
 }

 footer {
     position: fixed;
     font-size: small;
     color: #fff;
     background-color: #262626;
     display: flex;
     width: 100vw;
     height: 4rem;
     bottom: 0;
 }

 .footer-options {
     width: 50vw;
     display: flex;
     justify-content: flex-start;
     padding-inline-start: 20px;
     align-items: center;
 }

 footer span {
     width: 50vw;
     display: flex;
     justify-content: flex-end;
     padding: 0 20px;
     align-items: center;
 }

 @media (max-width: 900px) {
     footer {
         flex-wrap: wrap;
         height: 5rem;
     }

     .footer-options {
         width: 100vw;
         flex-direction: row;
         justify-content: center;
         padding-inline-start: 0;
         align-items: center;
     }

     footer span {
         width: 100vw;
         flex-direction: column;
         text-align: center;
         align-self: flex-start;
     }
 }

What iPhone are you on? I did a few screenshot tests (using lambdatest) and didn’t see the overflow you have in the picture. Does it overflow in landscape as well?

As far as I can tell, the intrinsic & extrinsic sizing is referring to the use of min-content and max-content. Below is what I’m guessing is the related WebKit bug.

WebKit Bugzilla: Bug 173873 - Support Intrinsic & Extrinsic Sizing with CSS Grid Layout

The value min-content is not supported for this grid-template-rows

CSS Grid Layout properties such as grid-template-rows do not support min-content, max-content. These properties are needed for certain flexible grid layouts, and are apparently part of the formal syntax.

I’m not so sure if the overflow is grid related. What happens if you remove flex from the container and just use max-width and margin auto. You will have to move the footer out of the container, so it doesn’t get affected.

.container {
  /* removed other css for brevity */
  max-width: 320px;
  margin: 0 auto;
}

Unfortunately, I can’t really do much testing.

Edit: Just for reference, here is the CSS Grid implementation meta bug for webkit Bug 60731 - [meta] Implement CSS3 Grid Layout.

Thanks a lot for writing @lasjorg

I’m following up in order:

  1. I’ve tested on Iphone7 and IphoneX (both on latest OS), the overflow happened on both.

  2. I’ve just tried lambdatest and the overflow does not happen there (just like it does not happen when I test in browsers’ devTools on my laptop). The styling breaks only when testing on the actual device (guess lambdatest’s tests might not be very native)

  3. tried your suggestion but with 300px instead as 320px was too large

.container {
  /* removed other css for brevity */
  max-width: 300px;
  margin: 0 auto;
}

This is what I get:

So, kind of better for the “equals” button but the rendering is still lost when sizing the other keys.

I’m welcoming other suggestions :slight_smile:

Ok, first of all, I have to say you’ve got me puzzled! I’ve spent a good hour trying to find a bug in your code, which is a mess btw - you really need to practice in pretty writing.

So, explanation of what’s going on:
You trying to control grid cell height with font-size and somehow is scales both width and height on iOS devices (line-height: 1.5; making things worse). I’ve fixed it assigning fixed height to rows and removing font-size, height and width properties away from grid cells

And the screenshot:

For others in the future: a set of things “seemed” to have created the overflow in IOS (once again, this inconsistency only happened on IOS devices when you test natively on the device, do not trust rendering from commercial testing software, they seem to be all using browser’s DevTools - where the overflow does not happen - ).

So, when anyone in the future goes through the same, this is what I’d suggest (bear in mind this is simply a suggestion and the result of tinkering, I cannot find clear cut rationale for the below):

Do not use grid-column property every child element where parent is set to grid-template-columns: repeat(4, 1fr); Stick to defining children that deviates from a standard parent design, i.e. grid-column: 1 / span 4;

body {
  background: #53687e;
  background: linear-gradient(120deg, #53687e, hsl(0, 0%, 18%)) fixed;
  font-family: 'Helvetica Neue', sans-serif;
  font-weight: 400;
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 0;
}

#calculator {
  margin: 0 auto;
  text-align: center;
  padding-top: 10%;
}  
    
.container {
  align-items: center;
  display: flex;
  justify-content: center;
  line-height: 1.5;
  padding-bottom: 50px;
  position: relative;
}

.key-group {
  background-color: black;
  border-radius: 8px;
  box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.7);
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(4, 1fr);
  overflow: hidden;
  padding: 8px;
}

button {
  cursor: pointer;
}

.key-pad {
  background-color: #33373f;
  border-radius: 5px;
  color: #ffff;
  cursor: pointer;
  font-size: 2rem;
  border: none;
  margin: 0;
  padding: 8px;
} 

.display{
   align-items: flex-end;
   cursor: default;
   background-color: transparent;
   display: flex;
   font-size: 2.5rem;
   grid-column: 1 / span 4;
   height: 5rem;
   justify-content: flex-end;
   text-align: right;
   color: #51aaff;
}


.divide, .multiply, .subtract, .clear, .add, .equals{
  background-color: #1e242c;
  color: #51aaff;
}

.equals{
  grid-column: 1 / span 4;
}

footer {
  position: fixed;
  font-size: small;
  color: #fff;
  background-color: #262626;
  display: flex;
  width: 100vw;
  height: 4rem;
  bottom: 0;
}

.footer-options {
   width: 50vw;
   display: flex;
   justify-content: flex-start;
   padding-inline-start: 20px;
   align-items: center;
}

.footer-link {
  padding: 0 20px;
  list-style: none;
}

.footer-linktext {
  color: #fff;
  text-decoration: none;
}
	

footer span {
  width: 50vw;
  display: flex;
  justify-content: flex-end;
  padding: 0 20px;
  align-items: center;
}

.key-pad:active {
  background: #51aaff;
	color: #51aaff;
}

button:hover {
  background-color: #51565d;
}
	

@media (max-width: 900px)  {
  
	footer {
	  flex-wrap: wrap;
        height: 5rem;  
	}
	
	.footer-options {
	  width: 100vw;
	  flex-direction: row;
	  justify-content: center;
          padding-inline-start: 0;
          align-items: center;
	}
	
	footer span {
	  width: 100vw;
          flex-direction: column;
   	  text-align: center;
          align-self: flex-start;
	}
}

a {
    text-decoration: none;  
}

a:visited,
a:hover,
a:active,
a:focus {
   text-decoration: underline;  
}

End result: proper rendering (as per my intended design, with adequately sized fonts) in both Android and IOS devices.

1 Like