1-7. 숙소 리스트 아이템 만들기 -실습-

Shy·2023년 7월 25일

HTML, CSS, JS

목록 보기
7/14

CSS box model

CSS에서는 margin, border, padding, 그리고 gap 속성을 이용해 페이지의 요소들이 어떻게 배치되고 표시되는지를 정의한다. 이들은 페이지 내 요소들 간의 공간과 관련된 속성이다.

  • Margin: Margin은 요소의 바깥쪽 공간을 조절한다. 이는 요소와 그 주변의 다른 요소들 간의 공간을 생성한다. 예를 들어, 두 개의 요소가 서로 붙어 있지 않고 일정한 공간을 두고 떨어져 있어야 한다면, margin을 사용하여 이를 조절할 수 있다. margin은 상하좌우 모두 설정할 수 있으며, 음수의 값을 가질 수도 있다.
  • Border: Border는 요소의 테두리를 정의한다. 테두리의 너비, 스타일(실선, 점선 등), 색상을 조절할 수 있다. 이를 통해 요소의 경계를 시각적으로 명확하게 표현할 수 있다.
  • Padding: Padding은 요소의 테두리와 그 내용(content) 사이의 공간을 조절한다. 이는 내용과 테두리 사이에 일정한 공간을 생성하므로, 요소 내부의 내용이 테두리에 너무 붙지 않게 한다. padding은 상하좌우 모두 설정할 수 있으며, 음수의 값을 가질 수 없다.
  • Gap: Gap은 그리드 또는 플렉스 요소의 행이나 열 사이의 간격을 조절하는 속성이다. grid-gap(그리드 갭), column-gap(열 갭), row-gap(행 갭) 등의 속성이 gap으로 통합되었다. 이 속성을 이용하면 그리드나 플렉스 아이템들 사이에 일정한 간격을 설정할 수 있다.

이 속성들을 이해하고 사용하면 웹 페이지의 레이아웃을 더욱 정교하게 조절할 수 있다.

실습

<main>
    <div class="place-list-item">
        <div class="place-image-wrapper">
            <img src="https://picsum.photos/1000/1000" alt="place image">
        </div>
    </div>
</main>
.place-image-wrapper {
    width: 300px;
    height: 293px;
    overflow: hidden;
} /*<div>요소의 너비와 높이를 설정. 이 크기를 넘으면 보이지 않게 된다.*/

.place-image-wrapper img {
    width: 500px;
    height: 500px;
} /*이미지의 크기를 조절해준다. 그러나 위의 width: 300px;, height: 293px;을 넘어가면 보이지 않는다.*/

place-image-wrapper에 들어간 이미지 원본 사이즈는 1000x1000이지만, '.place-image-wrapper img'를 통해 500x500으로 조절이 되었다. 하지만 '.place-image-wrapper'의 크기인 300x293을 넘음으로서, 이미지가 잘려 나온다.

이제, 이미지를 둥글게 깎는 'border-radius'를 주고, 좋아요를 누를 수 있는 하트 표시를 만들어보자.

<main>
    <div class="place-list-item">
        <div class="place-image-wrapper">
            <img src="https://picsum.photos/1000/1000" alt="place image">
          	<img class="heart-icon" src="./imgs/heart.png" alt="'heart icon">
        </div>
    </div>
</main>
.place-image-wrapper {
    position: relative;
    width: 300px;
    height: 293px;
    border-radius: 23px;
    overflow: hidden;
} /*<div>요소의 너비와 높이를 설정. 이 크기를 넘으면 보이지 않게 된다.*/

.place-image-wrapper img {
    width: 500px;
    height: 500px;
} /*이미지의 크기를 조절해준다*/

.place-image-wrapper .heart-icon {
    position: absolute;
    top: 16px;
    left: 16px;
    width: 24px;
    height: 24px;
}
  • '.place-image-wrapper': 이 클래스는 이미지를 감싸는 div 요소에 적용된다.
    • position: relative는 이 div 요소 내의 절대 위치 지정된 자식 요소들이 위치를 결정할 기준점을 제공한다.
    • width: 300px;와 height: 293px;은 div 요소의 너비와 높이를 지정한다.
    • border-radius: 23px;는 div의 모서리를 둥글게 만든다.
    • overflow: hidden는 이 div 요소의 범위를 넘어가는 내용을 숨긴다. 따라서 이 요소 안에 있는 이미지의 크기가 div의 크기를 초과하더라도, 초과하는 부분은 보이지 않게 된다.
  • .place-image-wrapper img: 이 클래스는 div 요소 내의 이미지에 적용된다.
    • width: 500px와 height: 500px은 이미지의 크기를 지정한다. 이 값들은 div 요소의 크기를 초과하므로, 이미지의 일부만 보이게 된다.
  • .place-image-wrapper .heart-icon: 이 클래스는 하트 아이콘에 적용된다.
    • position: absolute;는 이 요소의 위치를 'position: relative'인 부모 요소인 .place-image-wrapper에 상대적으로 결정한다.
    • top: 16px;와 left: 16px;는 아이콘이 부모 요소의 위쪽에서 16픽셀, 왼쪽에서 16픽셀 떨어진 위치에 있도록 한다.
    • width: 24px;와 height: 24px;은 아이콘의 크기를 지정한다.

.place-image-wrapper .heart-icon 으로 지정한 이유는, .heart-icon으로만 지정하여

.heart-icon {
    position: absolute;
    top: 16px;
    left: 16px;
    width: 24px;
    height: 24px;
    cursor: pointer;
}/*위치가, 부모의 상대위치를 사용한다.*/

이렇게 사용할 경우, 보다 상위 선택자인

.place-image-wrapper img {
    width: 500px;
    height: 500px;
} /*이미지의 크기를 조절해준다*/

코드가 적용되기 때문에, width와 height가 24px이 적용되는 것이 아니라 500px이 된다.
따라서 .place-image-wrapper .heart-icon 으로 지정해 줘야 24px이 되는 것이다.

<main>
  <div class="place-list-item">
    <div class="place-image-wrapper">
      <img src="https://picsum.photos/1000/1000" alt="place image">
      <img class="heart-icon" src="./imgs/heart.png" alt="'heart icon">
    </div>
    <div class="description-section">
      <div class="description-section_title">addddd</div>
      <div class="description-section_">bddddd</div>
      <div class="description-section_">cddddd</div>
    </div>
  </div>
</main>
.description-section {
    margin-top: 13px;
    display: flex;
    flex-direction: column; /*세로 방향 flex*/
    font-size: 15px;
    color: rgb(34, 34, 34);
    gap: 3px; /*flex의 간격을 3px로 둔다.*/
}

.description-section_title {
    font-weight: 600;
}

위 그림을 보면, 글자 사이의 간격이 3px로 떨어진 것을 볼 수 있다. 또한, image와 description-section_title 사이의 간격이 13px 떨어져 있는 것을 볼 수 있다.

<main>
  <div id="place-items-wrapper">
    <div class="place-list-item">
      <div class="place-image-wrapper">
        <img src="https://picsum.photos/1000/1000" alt="place image">
        <img class="heart-icon" src="./imgs/heart.png" alt="'heart icon">
      </div>
      <div class="description-section">
        <div class="description-section_title">addddd</div>
        <div class="description-section_">bddddd</div>
        <div class="description-section_">cddddd</div>
      </div>
    </div>
    <div class="place-list-item">
      <div class="place-image-wrapper">
        <img src="https://picsum.photos/1000/1000" alt="place image">
        <img class="heart-icon" src="./imgs/heart.png" alt="'heart icon">
      </div>
      <div class="description-section">
        <div class="description-section_title">addddd</div>
        <div class="description-section_">bddddd</div>
        <div class="description-section_">cddddd</div>
      </div>
    </div>
    <div class="place-list-item">
      <div class="place-image-wrapper">
        <img src="https://picsum.photos/1000/1000" alt="place image">
        <img class="heart-icon" src="./imgs/heart.png" alt="'heart icon">
      </div>
      <div class="description-section">
        <div class="description-section_title">addddd</div>
        <div class="description-section_">bddddd</div>
        <div class="description-section_">cddddd</div>
      </div>
    </div>
    <div class="place-list-item">
      <div class="place-image-wrapper">
        <img src="https://picsum.photos/1000/1000" alt="place image">
        <img class="heart-icon" src="./imgs/heart.png" alt="'heart icon">
      </div>
      <div class="description-section">
        <div class="description-section_title">addddd</div>
        <div class="description-section_">bddddd</div>
        <div class="description-section_">cddddd</div>
      </div>
    </div>
    <div class="place-list-item">
      <div class="place-image-wrapper">
        <img src="https://picsum.photos/1000/1000" alt="place image">
        <img class="heart-icon" src="./imgs/heart.png" alt="'heart icon">
      </div>
      <div class="description-section">
        <div class="description-section_title">addddd</div>
        <div class="description-section_">bddddd</div>
        <div class="description-section_">cddddd</div>
      </div>
    </div>
  </div>
</main>
main {
    display: flex;
    justify-content: center;
    padding: 24px 80px;
}

#place-items-wrapper {
    display: grid;
    grid-template-columns: repeat(4, 308px);
    justify-items: center;
    align-items: center;
    box-sizing: border-box;
    gap: 40px 24px;
}

.heart-icon:active {
    transform: scale(0.5); /*하트 클릭시 0.5배로 작아짐*/
    transition: transform 0.25s ease;
}

main 선택자에 대한 스타일:

  • display: flex;: main 요소를 flex 컨테이너로 설정한다. 이로 인해 main 요소의 자식 요소들은 flex 아이템이 된다.
  • justify-content: center;: flex 아이템들을 main 컨테이너의 가로축(주 축) 중앙에 정렬한다. 이 속성은 display: flex;로 설정된 컨테이너에 적용된다.
  • padding: 0 80px;: main 요소의 상하 패딩을 0으로, 좌우 패딩을 80px로 설정한다. 이로 인해 main 요소의 내부 내용은 좌우로 80px 떨어진 위치에서 시작한다.

#place-items-wrapper 선택자에 대한 스타일:

  • display: grid;: 이 요소를 grid 컨테이너로 설정한다. 그리드 레이아웃 관련 속성들을 사용할 수 있게 된다.
  • grid-template-columns: repeat(4, 308px);: 4개의 열을 만들고, 각 열의 너비를 308px로 설정한다.
  • justify-items: center;: 각 그리드 셀 내의 아이템들을 가로 방향으로 가운데 정렬한다.
  • align-items: center;: 각 그리드 셀 내의 아이템들을 세로 방향으로 가운데 정렬한다.
  • box-sizing: border-box;: 요소의 너비와 높이 계산을 테두리와 패딩을 포함하는 방식으로 설정한다.
    gap: 40px 24px;: 그리드 셀 간의 간격을 설정. 행 간격을 40px, 열 간격을 24px로 설정한다.

.heart-icon 클래스를 가진 요소에 :active 상태가 적용될 때(즉, 사용자가 해당 요소를 클릭하는 동안) 특정 스타일을 적용하는 것을 정의하고 있다.
.heart-icon 요소의 크기를 기존 크기의 50%로 축소시킨다. 즉, 요소가 클릭될 때 0.5배로 작아진다.
transition: transform 0.25s ease;: transform 속성의 변화를 0.25초 동안 부드럽게 전환하도록 지정한다. ease는 속도 곡선을 의미하며, 애니메이션은 천천히 시작되어, 그다음에는 빠르게 진행되고, 마지막에는 다시 천천히 끝난다.
따라서, 사용자가 .heart-icon 요소를 클릭하는 동안 요소는 원래 크기의 절반으로 빠르게 축소되었다가 다시 천천히 원래 크기로 돌아온다. 이 때 모든 변화는 0.25초 동안 일어난다.

profile
신입사원...

0개의 댓글