포트폴리오 카드를 한 줄에 3개씩 배치하기 위해 CSS Grid를 사용했다.
section .portfolio-me {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 3rem 5%;
}
section .portfolio-inner {
background-color: #fff;
padding: 1rem 1rem 1.5rem;
border: 1px solid #ccc;
}
.portfolio-inner img {
display: block;
width: 100%;
}
display: grid.portfolio-me {
display: grid;
}
display: grid는 요소를 Grid 컨테이너로 만드는 속성이다.
.portfolio-me가 Grid 컨테이너가 되고, 그 안에 들어 있는 .portfolio-inner 요소들이 Grid 아이템이 된다.
<div class="portfolio-me">
<div class="portfolio-inner">첫 번째 카드</div>
<div class="portfolio-inner">두 번째 카드</div>
<div class="portfolio-inner">세 번째 카드</div>
</div>
Grid를 사용하면 자식 요소들을 행과 열 형태로 쉽게 배치할 수 있다.
과거에는 float와 margin을 이용해 카드 레이아웃을 만들기도 했지만, 현재는 Flexbox나 Grid를 사용하는 것이 더 간단하고 관리하기 좋다.
grid-template-columnsgrid-template-columns: repeat(3, 1fr);
grid-template-columns는 Grid 컨테이너의 열 구조를 설정하는 속성이다.
repeat(3, 1fr)
각 부분의 의미는 다음과 같다.
repeat(3, ...): 같은 크기의 열을 3번 반복한다.1fr: 사용할 수 있는 공간을 1비율만큼 차지한다.fr: fraction의 약자로, Grid 컨테이너 내부의 남은 공간을 나누는 단위다.따라서 다음 두 코드는 같은 의미다.
grid-template-columns: repeat(3, 1fr);
grid-template-columns: 1fr 1fr 1fr;
결과적으로 한 줄에 동일한 너비의 카드 3개가 배치된다. 카드가 6개라면 첫 번째 줄에 3개, 두 번째 줄에 3개가 자동으로 배치된다.

gapgap: 3rem 5%;
gap은 Grid 아이템 사이의 간격을 설정한다.
값을 두 개 작성하면 다음 순서로 적용된다.
gap: 행의 간격 열의 간격;
따라서 현재 코드는 다음과 같다.
gap: 3rem 5%;
3rem: 카드 위아래 사이의 간격5%: 카드 좌우 사이의 간격다음처럼 나눠 작성해도 같은 의미다.
row-gap: 3rem;
column-gap: 5%;
gap을 사용하면 각 카드에 margin-right를 줄 필요가 없다. 또한 마지막 카드의 오른쪽 여백을 없애기 위해 :nth-child(3n)을 따로 작성할 필요도 없다.
section .portfolio-inner {
background-color: #fff;
padding: 1rem 1rem 1.5rem;
border: 1px solid #ccc;
}
각 포트폴리오 카드에 흰색 배경, 안쪽 여백, 테두리를 적용했다.
background-color: #fff;
카드의 배경색을 흰색으로 설정한다.
border: 1px solid #ccc;
카드 테두리를 두께 1px의 회색 실선으로 설정한다.
padding: 1rem 1rem 1.5rem의 의미padding: 1rem 1rem 1.5rem;
padding은 요소의 테두리와 내부 콘텐츠 사이에 생기는 안쪽 여백이다.
값을 3개 작성할 때는 다음 순서로 적용된다.
padding: 위 좌우 아래;
따라서 현재 코드는 다음과 같은 의미다.
padding-top: 1rem;
padding-right: 1rem;
padding-bottom: 1.5rem;
padding-left: 1rem;
즉, 위쪽과 좌우에는 1rem, 아래쪽에는 조금 더 넓은 1.5rem의 여백을 적용한 것이다.
카드 아래쪽에는 프로젝트의 종류와 제목 같은 텍스트가 들어가므로, 아래쪽 여백을 조금 더 크게 주면 카드가 답답하지 않고 안정적으로 보인다.
padding 축약형은 값의 개수에 따라 적용되는 방향이 달라진다.
/* 상하좌우 모두 1rem */
padding: 1rem;
/* 상하 1rem, 좌우 2rem */
padding: 1rem 2rem;
/* 위 1rem, 좌우 2rem, 아래 3rem */
padding: 1rem 2rem 3rem;
/* 위, 오른쪽, 아래, 왼쪽 */
padding: 1rem 2rem 3rem 4rem;
값이 4개일 때는 시계 방향으로 적용된다고 기억하면 편하다.
width: 100%를 사용하는 이유.portfolio-inner img {
width: 100%;
}
width: 100%는 이미지의 너비를 부모 요소의 콘텐츠 영역만큼 채우게 한다.
이미지 원본의 크기가 카드보다 크더라도 카드 너비에 맞게 줄어들기 때문에, 이미지가 카드 밖으로 넘치는 것을 방지할 수 있다.
각 카드의 너비가 달라지더라도 이미지가 카드 크기에 맞춰 함께 조절된다는 장점도 있다.
display: block을 사용하는 이유.portfolio-inner img {
display: block;
}
img 요소는 기본적으로 inline 요소처럼 배치된다.
인라인 요소는 글자와 같은 줄에 배치되며, 브라우저는 영문자의 g, p, y처럼 기준선 아래로 내려가는 부분을 고려해 이미지 아래에 작은 여백을 남긴다.
따라서 이미지 아래에 의도하지 않은 공백이 나타날 수 있다.
img {
display: block;
}
이미지를 블록 요소로 바꾸면 텍스트 기준선의 영향을 받지 않기 때문에 이미지 아래쪽의 불필요한 공백이 사라진다.
또한 이미지가 독립적인 하나의 영역으로 배치되어 크기와 간격을 더 예측하기 쉽게 관리할 수 있다.
width: 100%만 적용해도 이미지의 너비는 맞출 수 있지만, 이미지 아래의 미세한 공백까지 제거하려면 display: block을 함께 사용하는 것이 좋다.
.portfolio-me {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 3rem 5%;
}
위 코드를 사용하면 포트폴리오 카드를 동일한 크기의 3열로 배치할 수 있다.
.portfolio-inner {
padding: 1rem 1rem 1.5rem;
}
카드 내부에는 위와 좌우에 1rem, 아래에 1.5rem의 여백이 적용된다.
.portfolio-inner img {
display: block;
width: 100%;
}
이미지는 카드 너비에 맞게 조절되며, display: block을 통해 이미지 아래에 생길 수 있는 불필요한 공백도 제거된다.