[코드 리뷰] Lego Classic Space 클론 코딩

Carrie·2024년 1월 23일
0
post-thumbnail

1. position: absolute에서 Grid와 Flex 레이아웃으로 개선

기존의 웹사이트는 position: absolute를 사용하여 대부분의 요소의 위치를 고정시키는 방식으로 구성되어 있었다. 이 방식은 레이아웃의 유연성을 크게 제한하고, 다양한 디바이스 및 화면 크기에서 호환성 문제를 일으킬 수 있다. 이를 개선하기 위해 display: griddisplay: 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는 아이템을 그리드 영역의 아래쪽 끝에 정렬한다.

2. zoom에서 SCSS 도입

또한, 기존의 웹사이트는 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등 상대적 단위를 사용하여 데스크탑 환경에서 사용자에게 더 나은 시각적 경험을 제공할 수 있게 되었다.

profile
Markup Developer🧑‍💻

0개의 댓글