Safari의 flex height 상속 버그

Safari의 flex height 상속 버그

Dom의 크기가 상황에 따라 동적으로 변할 때 크기를 조절 하려고 display 속성 중 하나인 flex를 자주 쓴다.
flex라는 이름처럼 크기조절에 관해서는 안되는게 거의 없다.
비교적 최신스펙이긴 하지만 지금 modern브라우저는 거의다 지원 할 뿐만 아니라 성능저하의 큰 원인인 자바스크립트에서 돔을 접근하는 코드들을 많이 줄일 수 있다. (경험으로는 대부분 없앨 수 있다.)

flex를 많이 써오면서 flex의 사용 가이드와 팁들에 관한 블로그를 먼저 쓰려고 했으나 차일피일 미루다
부모 element가 flex일 때 자식 element의 height 값이 상속받지 못하고 0이 되어버리는 증상이 발생했다.
날 몇시간 동안 괴롭힌 버그라서 간단한 설명 겸 이와 관련해서 써보고자 한다.

flex

먼저 상위 Dom에 display:flex를 지정하면 그 하위 Dom들은 flex라는 속성으로 부모돔의 넓이 (혹은 높이)를 얼마큼 차지할 지 결정할 수 있다.

예를 들어

<div id="parent">
  <div>static</div>
  <div id="dynamic">dynamic......</div>
  <div>static</div>   
</div>
#parent {
  display: flex;
  width: 500px;
  background-color: yellow;
}

#dynamic {
  flex: 1;
  background-color: green;
}

위와 같이 쓰면 부모돔의 500px를 static한 엘리먼트가 차지하는 넓이를 빼고 dynamic이란 id를 가지고 있는 Dom이 차지할 것이다.

이와 같이 flex는 렌더링 되기전엔 크기를 모르는 dom들을 컨트롤 할 때 매우 편하다~

flex-direction

기본적으로 flex가 동작하는 방향은 가로방향이다. 세로로 동작하게 하려면 flex-direction이라는 속성을 column 으로주면 된다.

in safari

safari에서 flex를 쓰려면 완전한 내장 스팩이 아니라 속성에 -webkit을 붙여줘야 한다.

safari버그

이번에는 세로방향으로 flex하게 만들고 #dynamic 에 하위 dom을 하나 더 둬보자 하위 dom은 height이 100%로 부모의 값을 상속한다.

<div id="parent">
  <div>static</div>
  <div id="dynamic">
    <div id="child">dynamic......</div>     
  </div>
  <div>static</div>   
</div>
#parent {
  width: 100px;
  height: 300px;
  background-color: yellow;
  display: flex;
  display: -webkit-flex;
  flex-direction: column;
  -webkit-flex-direction: column;
}

#dynamic {
  flex: 1;
  -webkit-flex: 1;
  background-color: green;
}

#child {
   height: 100%;
   background-color: skyblue;
}

부모 element의 height값을 상속 받는다면 #child의 색깔인 하늘색이 나와야 한다.

실제로 타브라우저에서는 잘 나온다.
하지만 safari는 다르다. Dom이 차지하는 영역만 빼고는 height값을 상속받지 못한다.

ex) chrome/safari

위 예제는 http://codepen.io/Vnthf/pen/ALywZx 에서 살펴 볼 수 있다.

해결 방법

여러가지 방법이 있을 수 있겠지만 먼저

height 값을 명시해준다.

height값을 상속받지 않고 구체적으로 지정해주면 된다. 그러나 이런경우는 많이 없을 것이다.

자식 값 까지 flex를 상속받는다.

자식 값 까지 flex속성을 상속 받도록 한다. 위의 예제에서는 #dynamic에 display: flex속성을 추가하고 #child에 flex:1속성을 추가하면서 가는 방법이다.

하지만 이 방법은 Dom구조가 깊어질수록 번거로워질 뿐만 아니라 굳이 flex속성이 필요없는 dom일 경우에 성능에 불필요한 작업이 될 수 있다.

script로 parent의 dom을 계산

부모돔의 height값이 변할 때 계산해주고 자식의 height 값에 할당해 주는 방식이다. 스크립트가 들어간다는 단점이 있지만 flex 속성을 유지하면서 복잡하지 않게 처리 할 수 있다. 물론 safari와 관련된 예외처리 코드가 들어간다는게 단점이다.

위의 버그는 height속성에만 적용 될 뿐 width값은 safari도 잘되니 참고하기 바란다.

Comments

comments powered by Disqus
comments powered by Disqus