Search code examples
htmlcssreactjsstyled-components

Why is overflow-x:clip not working on mobile browser


I wanted to crop my background on mobile phone so the user cant scroll horizontally, it works fine when i use responsive design mode on web browser :

enter image description here

But when i open it on my mobile phone , it shows like this :

enter image description here

I know this question have been asked many times, but none of the solutions seems work for me.

this is my code :

import React from "react"
import styled from "styled-components"

const HeroBackground = () => {
  return (
    <Wrapper>
      <Background src="/images/backgrounds/hero-background.svg" />
    </Wrapper>
  )
}

export default HeroBackground

const Wrapper = styled.div`
  position: relative;
  max-width: 1440px;
  margin: auto;
  overflow-x: clip !important;
`

const Background = styled.img`
  position: absolute;
  z-index: -1;
  @media (max-width: 480px) {
    max-width: 600px;
    height: auto;
  }
`

This is the link of my website in case if needed : https://trusting-bohr-a3f5b8.netlify.app/


Solution

  • My guess is you are using Safari browser on an iphone, and according to Can I Use, clip is unfortunately not supported in Safari, hence the discrepancy you are seeing.

    I tried messing around to see if I could achieve the effect you're looking for. One possible solution is to introduce one more wrapping div around the img.

    const HeroBackground = () => {
      return (
        <Wrapper>
          <ImageWrapper>
            <Background src="/images/backgrounds/hero-background.svg" />
          </ImageWrapper>
        </Wrapper>
      )
    }
    
    export default HeroBackground
    
    const Wrapper = styled.div`
      position: relative;
      max-width: 1440px;
      margin: auto;
      /* overflow-x: clip !important; ***cannot use!*** */
    `
    
    const ImageWrapper = styled.div`
      position: absolute;
      top: 0;
      left: 0;
      overflow: hidden;
      max-width: 100vw;
      z-index: -1;
    `
    
    const Background = styled.img`
      /* position: absolute; ***remove*** */
      /* z-index: -1; ***remove*** */
      @media (max-width: 480px) {
        max-width: 600px;
        height: auto;
      }
    `
    

    There are three keys to this working:

    • The additional wrapper div allows you to position the image statically so that it contributes to height. The div is therefore what becomes absolutely positioned.
    • max-width: 100vw means the div will never be longer than the screen.
    • And overflow: hidden means the image won't leak out of its constraining div.
      • Using hidden on Wrapper hides the entire image because it ends up with 0 height. This is why the extra div is introduced.

    I also recommend investigating if there's a way to use your image as a background-image.