2가지 border style 전환 시의 layout shift와 해결 방법 (box-shadow)

2가지 border style 전환 시의 layout shift와 해결 방법 (box-shadow)

Tags
Web Dev
CSS
Published
May 4, 2025
Author
Seongbin Kim
작성 중
 
 

문제 상황

 

‘배경’용 border, ‘강조’용 border의 스타일 차이

 

기존 방법

  • 아래와 같이 ‘축구장’ 형태의 레이아웃을 구성하면서, 기본 격자를 border로 처리했습니다.
    • 격자를 border로 처리하는 것까지는 좋은 선택이었는데요…
    • notion image
  • 이후 ‘선택됨’ 상태도 동일하게 border로 구현하려고 하니 문제가 발생했습니다.
    • 강조 표시(선택됨 상태)로 전환 시 layout shift가 발생했습니다.
 

layout shift의 원인 분석

  • border가 right, bottom에서 all로 변하고,
  • width가 1px -> 3px 로 border-width가 변하기 떄문입니다.
 

해결 방법

 

1. transform으로 ‘카운터’치기(보정하기) ❌

  • 기본 상태와 선택됨 상태의 차이는 눈 대중으로 보았을 때 (x,y) 좌표 차이로 보여서, translate(x,y)를 시도했습니다.
    • CSS: transform: 'translate(-0.5px, -0.2px)'
  • translate로도 layout shift가 거의 없게 근사할 수 있지만 미묘하게 움직이는 느낌은 계속해서 남아 있었고, CSS에 매직 넘버도 추가되어서 좋은 방법은 아니었습니다.
  • 코드
    • // Vanilla Extract / CSS 일부만 발췌 export const commonCellContainer = recipe({ base: { borderRight: `1px solid ${lightThemeVars.color.field.lineLight}`, borderBottom: `1px solid ${lightThemeVars.color.field.lineLight}`, }, variants: { isSelected: { true: { transform: 'translate(-0.5px, -0.2px)', border: `3px dashed ${lightThemeVars.color.white.main}`, }, }, },
  • 화면
 

2. border-width를 일치시키기 ⚠️

  • layout shift는 결국 border의 면적을 항상 일치시키는 것이었습니다.
  • 기본 상태의 레이아웃도 선택됨 상태와 마찬가지로 3px 을 유지하니 layout shfit가 사라졌습니다.
    • border: 3px solid transparent
  • 단, 이렇게 하면 실제 디자인과 많이 달라지기 때문에 사용할 수는 없었습니다.
  • 화면
 

3. box-shadow로 기본 border 대체하기 ✅

 

발상

  • 예전에 CSSBattle 등에서 여러 개의 border를 동시에 사용하던 것이 생각났습니다.
  • 당시 outline, box-shadow를 활용했던 것이 기억났고, box-shadow로 border처럼 렌더링할 수 있는지 확인해보았습니다.
 

적용

  • 다행히도 box-shadow로 쉽게 가능했어서, 결과적으로는 border: 3px,로 배치해서 layout shift를 방지하고, 대신 기본 선택됨 색상은 transparent로 설정했습니다.
    • CSS: border: '3px solid transparent'
  • 이후 box-shadow로 기본 border 표시를 대체할 수 있었습니다.
    • // Vanilla Extract / CSS 일부만 발췌 export const commonCellContainer = recipe({ base: { border: '3px solid transparent', boxShadow: `0 0 0 1px ${lightThemeVars.color.field.lineLight}`, }, variants: { isSelected: { true: { border: `3px dashed ${lightThemeVars.color.white.main}`, }, }, }, });
  • 화면
 

결론

 

box-shadow는 그림자도 되지만 border도 된다.

 

여러 스타일의 border가 필요할 때는 border만으로는 layout shift가 발생할 수 있다.