많은 프론트엔드 개발자 지망생이 공통으로 얘기하는 건, css가 생각보다 어렵다는 것이다.
css 프로퍼티가 서로 의존하고 css 프로퍼티가 DOM 구조에 의존하기에, 스타일링 코드의 결과를 예측하기 어렵다. css 프로퍼티가 서로 의존하는 예시로, z-index가 있다. z-index의 값이 미치는 영향은, 해당 요소가 어느 stacking context에 존재하냐에 따라 달라진다. 그리고 stacking context는, 정말 다양한 css 프로퍼티의 영향을 받는데, MDN의 'The Stacking Context'문서에 나와 있는 것만 해도 15가지가 넘는다.... 그렇기에 z-index 프로퍼티는, 최소한 이 15가지 css 프로퍼티와 의존관계에 놓여져있는 것이다.
css 프로퍼티가, DOM 구조에 의존하는 예시로는, width,height의 퍼센티지 값이 있다. 특정 요소의 width와 height를 퍼센티지 단위로 정할 때, 기준이 되는 블록을 'containing block'이라 부른다. 많은 경우에는, 부모 요소가 containg block을 결정짓는다 봐도 무방하지만, 꼭 그런 건 아니다. MDN의 'Layout and the containing block' 문서에는, containing block이 결정되는 알고리즘이 설명돼있는데, 이론적으로는 '부모' 요소가 아니라, '조부모, 증조부모 심지어는 고조부모' 요소가 containing block이 될 수 있고, 스타일링에 영향을 미칠 수 있다.
이번 프로젝트를 진행하면서, 스타일링 코드가 미치는 영향을 정확히 예측하는 것이 힘들다는 것을, 다시 느낄 수 있었는데, 구체적인 사례 하나를 살펴보자.
위 사진과 같은, 검색 옵션 ui를 구현해야 했다. 처음에는 스타일링을 신경 쓰지 않고, semantic하게 html 코드를 작성하겠다는 마음으로, 아래와 같이 3개의 fieldset으로 나누기로 했다.
그리고 '작성자', '검색기간', '대상'이 각 fieldset의 legend가 되도록 작성했다. 각 fieldset 내부의 레이아웃은, flex를 사용하여 설정하고자 했다. 하지만, 희한하게도 생각한 것과 전혀 다르게 레이아웃이 결정돼서, 자세히 찾아보니, 'fieldset의 display 프로퍼티 값을 변경해도, 어떠한 영향을 줄 수 없다'는 버그 리포트를, 크로미움 버그 포럼에서 찾을 수 있었다. 이 버그를 수정했었으나, 너무 많은 웹 사이트가 망가져 버려서, 다시 되돌렸다고 한다...
하지만 이것이 문제의 원인은 아닌 것처럼 보였던 게, fieldset 내부의 legend 요소를, div요소로 바꾸니, 위의 버그 리포트 내용과는 다르게, fieldset이 flexbox container로 잘 작동했다. 이건 도대체 왜 그러는 건지 도무지 설명할 수 없었고, 설명하는 내용을 찾을 수도 없었다.
이처럼, 다양한 요인들이 복잡하게 의존하고 상호 작용하며 스타일링이 결정되기 때문에, css 코드를 작성했을 때, 결과를 정확하게 예측하는 건 쉽지 않은 일이다. 이런 예측과 다른 결과는, 생산성의 저하로 이어질 수밖에 없다. 또한, 예측이 맞아 떨어지지 않았다 하더라도, 예측과 다른 결과가 발생한 원인을 파악하는 건, 버그를 수정하는데 도움이 되지만, 위의 예시처럼 이것이 항상 가능한 건 아니다. 물론, 이로 인해 생기는 생산성의 저하가 아주 크다고 생각하지는 않는다. 그렇기에 이를 웹 개발의 어쩔 수 없는 한 부분으로 받아들이고, 개발하는 것이, 우리가 할 수 있는 최선일 것이다.