기존의 웹사이트는 position: absolute
를 사용하여 대부분의 요소의 위치를 고정시키는 방식으로 구성되어 있었다. 이 방식은 레이아웃의 유연성을 크게 제한하고, 다양한 디바이스 및 화면 크기에서 호환성 문제를 일으킬 수 있다. 이를 개선하기 위해 display: grid
와 display: flex
를 사용하여 레이아웃 전체를 재구성하였다.
.sc-main {
position: relative;
width: 100%;
height: 1152px;
max-width: 100%;
min-height: 720px;
color: #fdf8f1;
}
.sc-main .award-list li a {
position: absolute;
width: 73px;
height: 73px;
zoom: var(--zoom);
top: 103px;
z-index: 2;
}
.sc-main .text-wrapper p {
position: absolute;
zoom: var(--zoom);
width: 288px;
font-weight: 300;
text-transform: uppercase;
}
.sc-main .text-wrapper p:first-child {
top: 430px;
left: 38px;
font-size: 16px;
line-height: 20px;
}
.sc-main .text-wrapper p:last-child {
top: 458px;
left: 38px;
font-size: 10px;
}
.sc-main .anchor-link {
position: absolute;
width: 203px;
height: 50px;
top: 497px;
left: 39px;
zoom: var(--zoom);
text-transform: uppercase;
background: url("../imgs/start1.png") no-repeat center / cover;
transition: all 0.3s ease-in-out;
z-index: 2;
}
.
.
.
생략
(이외에도 거의 대부분의 요소가 position: absolute
로 잡혀있었다. 모든 요소의 레이아웃을 변경하느라 애를 좀 먹은 프로젝트였다...🥲)
메인페이지가 꽤나 복잡한 구조였는데, display: grid
를 사용하여 좀 더 유연하게 재구성하였다.
💡 display: grid란?
grid는 웹페이지를 격자 형태로 나누어 각 요소를 배치할 수 있게 해준다. 이는 레이아웃을 보다 유연하고 효율적으로 제어할 수 있게 해준다.display: grid
를 사용하면, 해당 요소가 grid 컨테이너가 되고, 그 자식 요소들은 자동으로 grid 아이템이 된다.
.sc-main .top-section .left-section {
display: grid;
grid-template-columns: repeat(6, 1fr); // 6개의 열
grid-template-rows: repeat(6, 1fr); // 6개의 행
width: 50%;
height: 100%;
padding-left: 3.5rem;
}
.sc-main .left-section .award-list {
grid-row: 2 / 3;
grid-column: 1 / span 4;
align-self: self-end;
display: flex;
justify-content: space-between;
width: 27vw;
gap: 10px;
}
.sc-main .left-section .award-list li {
flex: 1;
min-width: 73px;
}
.sc-main .left-section .text-wrapper {
grid-row: 5 / 6;
grid-column: 1 / span 3;
align-self: self-end;
}
.sc-main .left-section .text-wrapper p:first-child {
font-size: 1.3vw;
padding-bottom: 0.4rem;
}
.sc-main .left-section .text-wrapper p:last-child {
font-size: 0.84vw;
padding-bottom: 2rem;
}
.sc-main .left-section .anchor-link {
grid-row: 6 / 7;
grid-column: 1 / span 3;
display: flex;
justify-content: center;
align-items: center;
width: 325px;
height: 80px;
background: url("../imgs/start1.png") no-repeat center / cover;
transition: all 0.3s ease-in-out;
}
grid-template-columns: repeat(6, 1fr);
👉 6개의 열을 만들고 각각의 크기를 컨테이너 크기에 맞게 유연하게 조정한다. 1fr
은 사용 가능한 공간의 동등한 비율을 의미한다.
grid-template-rows: repeat(6, 1fr);
👉 6개의 행을 만든다. 1fr
은 위에서 설명한 것과 동일한 의미이다.
grid-row: 2 / 3;
👉 grid 아이템이 차지할 위치와 범위를 정의한다. 2번째 행에서 시작하여 3번째 행 바로 전까지 차지한다는 의미이다.
grid-column: 1 / span 4;
👉 1번째 열에서 시작해서 4개의 열을 차지한다.
(참고로 끝에서부터 위치를 지정하려면 grid-column: span 4 / -1
이렇게 해주면 된다.)
align-self: self-end;
👉 아이템의 세로 정렬 방식을 설정한다. self-end
는 아이템을 그리드 영역의 아래쪽 끝에 정렬한다.
또한, 기존의 웹사이트는 zoom
이라는 속성을 사용하여 반응형 디자인을 구현하고 있었는데, 이는 현대의 웹사이트에서는 잘 사용되지 않는 속성으로 브라우저 간 호환성에 문제를 일으킬 수 있다. zoom
대신 SCSS를 도입하여 다양한 화면 크기와 디바이스에 맞춰 스타일을 쉽게 조정할 수 있도록 하였다.
.sc-classic-space .bottom-section strong {
position: absolute;
zoom: var(--zoom);
top: 115px;
left: 27px;
width: 558px;
color: #ffca20;
font-size: 106px;
line-height: 106px;
font-weight: 300;
letter-spacing: -0.4px;
text-transform: uppercase;
}
.sc-classic-space .bottom-section .sub-title {
position: absolute;
zoom: var(--zoom);
top: 241px;
left: 239px;
width: 603px;
color: #fdf8f1;
font-size: 30px;
line-height: 1.26;
font-weight: 300;
letter-spacing: -0.4px;
text-transform: uppercase;
}
.sc-classic-space .bottom-section .description {
position: absolute;
zoom: var(--zoom);
top: 396px;
left: 496px;
width: 159px;
color: #fdf8f1;
font-size: 12px;
line-height: 15px;
font-weight: 400;
text-transform: uppercase;
}
.sc-classic-space .bottom-section .big-blue-lego {
display: block;
position: absolute;
zoom: var(--zoom);
left: 81px;
top: 374px;
width: 238px;
}
.sc-classic-space .bottom-section .cruiser {
position: absolute;
zoom: var(--zoom);
left: 610px;
top: 127px;
width: 858px;
}
.sc-classic-space .bottom-section .yellow-block {
position: absolute;
zoom: var(--zoom);
left: -90px;
top: 509px;
width: 1380px;
max-width: inherit;
}
우선 데스크탑에서 많이 사용되는 해상도를 기준으로 브레이크 포인트를 설정하여 프로젝트 전체에서 재사용할 수 있게 하였다. 그리고 :root
에 화면 사이즈에 따른 폰트를 적용하여 padding
, margin
등에 rem
단위를 사용하여 구현하였다.
/* 미디어 쿼리 믹스인 설정 */
@mixin desktop() {
@media (min-width: 1537px) {
@content;
}
}
@mixin laptop() {
@media (max-width: 1536px) {
@content;
}
}
@mixin laptop-small() {
@media (max-width: 1366px) {
@content;
}
}
/* 반응형 폰트 사이즈 설정 */
@mixin responsive-font-size($condition, $size) {
@media (#{$condition}) {
:root {
font-size: $size;
}
}
}
@include responsive-font-size("(min-width: 1537px)", 16px);
@include responsive-font-size("(max-width: 1536px)", 14px);
@include responsive-font-size("(max-width: 1366px)", 13px);
💡 SCSS의 장점
- 변수 사용: 색상, 폰트 크기, 간격 등을 변수로 저장하여 전체 프로젝트에서 일관되게 사용할 수 있다.
- 믹스인과 함수: 반복적으로 사용되는 CSS 스타일 패턴을 믹스인으로 정의하여 필요할 때마다 재사용할 수 있다. 미디어쿼리와 같은 반응형 디자인의 구현을 위한 코드를 믹스인으로 만들어 코드의 중복을 줄이고 가독성을 높일 수 있다.
- 중첩 규칙: SCSS에서는 선택자를 중첩하여 사용할 수 있어, HTML 구조와 유사한 방식으로 스타일을 구성할 수 있다. 이는 코드의 구조를 더 명확하게 하고, CSS 선택자의 복잡성을 줄여준다.
.sc-classic-space .bottom-section {
display: grid;
grid-template-columns: repeat(10, 1fr);
grid-template-rows: repeat(5, 1fr);
position: relative;
height: 140vh;
padding-top: 15rem;
text-transform: uppercase;
}
.sc-classic-space .bottom-section #year-1987 {
grid-row: 1/3;
grid-column: 1 / span 3;
padding-left: 3.5rem;
color: #ffca20;
font-size: 8.8vw;
font-weight: 300;
letter-spacing: -0.4px;
}
.sc-classic-space .bottom-section .sub-title {
grid-row: 2/3;
grid-column: 3 / span 5;
align-self: center;
padding-left: 1rem;
padding-top: 1.5rem;
}
.sc-classic-space .bottom-section .description {
grid-row: 3/4;
grid-column: 5 / span 2;
align-self: center;
color: #fdf8f1;
font-size: 1vw;
line-height: 1.2;
font-weight: 400;
padding-left: 2.5rem;
}
.sc-classic-space {
.img-wrapper img {
position: absolute;
}
.bottom-section {
.big-blue-lego {
left: 130px;
bottom: 80px;
width: 381px;
@include laptop {
left: 104px;
bottom: 60px;
width: 305px;
}
@include laptop-small {
left: 92px;
bottom: 53px;
width: 271px;
}
}
.cruiser {
width: 1373px;
bottom: 60px;
right: -430px;
@include laptop {
width: 1098px;
bottom: 50px;
right: -342px;
}
@include laptop-small {
width: 976px;
bottom: 44px;
right: -304px;
}
}
.yellow-block {
width: 115%;
bottom: 0;
left: 50%;
transform: translateX(-50%);
max-width: none;
z-index: 2;
}
}
}
비록 완전한 반응형 디자인을 구현한 것은 아니지만, SCSS 도입 및 rem
, vw
, vh
등 상대적 단위를 사용하여 데스크탑 환경에서 사용자에게 더 나은 시각적 경험을 제공할 수 있게 되었다.