※ 본 포스팅은 개인 기록용으로 반응형 웹에서 이미지나 요소의 비율을 유지하는 방법에 대해 고민하다가 알게된 내용을 정리한 것입니다. 혹시나 저와 비슷한 고민을 하시는 분이 계실까봐 기록으로 남깁니다.
aspect-ratio로 반응형 웹에서 요소의 비율 유지하기
들어가며
최근 캐러셀(슬라이더) 컴포넌트를 만들면서 이미지의 비율을 어떻게 유지할지 고민이 많았습니다. 처음에는 단순히 width와 height를 픽셀로 고정하거나 퍼센트(%)로 지정했는데, 이게 생각보다 쉽지 않더라구요. 고정 픽셀을 사용하면 모바일에서 깨지고, 퍼센트만 사용하면 부모 요소의 크기에 따라 이미지가 찌그러지는 문제가 있었습니다. div를 여러 개 중첩해서 해결할 수도 있겠지만, 성능 이슈가 걱정되었죠. 그러다 발견한 게 바로 `aspect-ratio` CSS 속성입니다.
aspect-ratio란?
`aspect-ratio`는 요소의 가로세로 비율을 설정하는 CSS 속성입니다. 예를 들어 16:9 비율을 유지하고 싶다면 다음과 같이 작성할 수 있습니다:
element { aspect-ratio: 16/9; }
실제 사용 예시 - 기존 제가 했던 캐러셀 구현 방식의 문제점
처음에는 이런 식으로 구현했습니다
.carousel-wrapper {
width: 100%;
position: relative;
}
.carousel-container {
width: 100%;
height: 0;
padding-bottom: 56.25%; /* 16:9 비율을 위한 padding hack */
position: relative;
}
.carousel-item {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.carousel-image-wrapper {
width: 100%;
height: 100%;
position: relative;
}
.carousel-image {
width: 100%;
height: 100%;
object-fit: cover;
}
...
<div class="carousel-wrapper">
<div class="carousel-container">
<div class="carousel-item">
<div class="carousel-image-wrapper">
<img src="image1.jpg" class="carousel-image" alt="" />
</div>
</div>
<!-- 추가 슬라이드 아이템들... -->
</div>
</div>
...
여기에서 저는 처음에는 구현이 일단 됐기 때문에 다른 작업을 하다가
실제로 api 연결을 하고 사진이 많아졌을 때 컴포넌트가 버벅거리는 경험을 하게 되었습니다.
그래서 코드를 점검해보고 고민해보는 시간을 갖게 되었고 제가 내렸던 이 방식의 문제점은
- div가 너무 많이 중첩됩니다 (wrapper -> container -> item -> image-wrapper -> image)
- position: absolute를 사용해야 하는 등 복잡한 position 설정이 필요합니다
- padding hack(padding-bottom: 56.25%)을 사용해야 해서 코드가 직관적이지 않습니다
- DOM 요소가 많아져서 성능에 영향을 줄 수 있습니다
였고 어떤 식으로 최적화 및 html 요소를 줄일 수 있을지 찾아보았습니다.
aspect-ratio를 활용한 개선된 구현
이걸 aspect-ratio를 사용하면 훨씬 단순화할 수 있었습니다:
.carousel {
width: 100%;
overflow: hidden;
}
.carousel-item {
width: 100%;
aspect-ratio: 16/9;
}
.carousel-image {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="carousel">
<div class="carousel-item">
<img src="image1.jpg" class="carousel-image" alt="" />
</div>
<!-- 추가 슬라이드 아이템들... -->
</div>
단순히 계산해도 원래는
캐러셀 랩퍼 > 컨테이너 > 아이템 > 아이템 랩퍼 순으로 4뎁스나 필요했었는데
개선된 코드에서는 랩퍼 없이 캐러셀, 캐러셀 아이템 만으로 엄청 간소화되었습니다.
더 좋은 방법이 있지 않을까 고민하지 않고 아는 지식만으로 구현하려 했었기 때문에
무지에서 발생한 성능저하였고, 지금 구현은 된다고 하더라도 내가 하는게 최선인지 의심해보던 초심을 몇개월동안 잃어버렸던 것 같은데 포스팅할 좋은 경험이 되었습니다.
'코딩이야기 > HTML & CSS' 카테고리의 다른 글
[CSS] 텍스트 블러 효과 구현하기 - text-shadow, filter:blur 알아보기 (1) | 2024.10.24 |
---|---|
[HTML/CSS] hover 이벤트시 다른 클래스, id 에도 효과를 주는 법 (0) | 2023.02.07 |
[HTML & CSS] Hover의 이벤트들 cursor의 속성들. (0) | 2022.10.23 |
[HTML5 & CSS] 속성 선택자 (0) | 2022.08.09 |
입력에 필요한 태그와 속성 (HTML & CSS) 01 (0) | 2022.07.18 |