개발공부 3개월 차... html, css, javascript를 배우면서 이제 슬슬 뭐 좀 만들어보고 싶은 생각이 개발공부 3개월차에 들기 시작했다. 페이지 레이아웃 짜는 것을 계속 연습해보고 싶었고(flexbox, grid 등), css의 다양한 속성들에 대해서는 일단 뭘 만들어봐야 익숙해지겠구나 싶었다.
유튜브에서 오픈 소스 하나를 찾아 다시 내가 복기해서 만들어보고, 그 중에서 웹페이지가 더 예쁘게 보이도록 여러 속성들을 수정하고 더해보았다.
페이지를 만들면서 기억하고 싶었던 중요한 부분을 짚고 넘어가고자 이 포스팅을 적게 되었다.
자주 쓰이는 폰트, 컬러, 간격, overlay 속성 등을 전역에 변수처리 해두었다. 전체적으로 페이지가 안정감있고(간격들이 들쭉날쭉 하지 않기 때문) 톤온톤 색상들로 균형감 있게 보여지기 위함이다.
:root {
--header-height: 3rem;
/*========== Colors ==========*/
/* Change favorite color to match images */
/*Green dark 190 - Green 171 - Grren Blue 200*/
--hue-color: 190;
/* HSL color mode */
--first-color: hsl(var(--hue-color), 64%, 22%);
--first-color-second: hsl(var(--hue-color), 64%, 22%);
--first-color-alt: hsl(var(--hue-color), 64%, 15%);
--title-color: hsl(var(--hue-color), 64%, 18%);
--text-color: hsl(var(--hue-color), 24%, 35%);
--text-color-light: hsl(var(--hue-color), 8%, 60%);
--input-color: hsl(var(--hue-color), 24%, 97%);
--body-color: hsl(var(--hue-color), 100%, 99%);
--white-color: #fff;
--scroll-bar-color: hsl(var(--hue-color), 12%, 90%);
--scroll-thumb-color: hsl(var(--hue-color), 12%, 75%);
/*========== Font and typography ==========*/
--body-font: "Open Sans", sans-serif;
--title-font: "Raleway", sans-serif;
--biggest-font-size: 2.5rem;
--h1-font-size: 1.5rem;
--h2-font-size: 1.25rem;
--h3-font-size: 1rem;
--normal-font-size: 0.938rem;
--small-font-size: 0.813rem;
--smaller-font-size: 0.75rem;
/*========== Font weight ==========*/
--font-medium: 500;
--font-semi-bold: 600;
/*========== Margenes Bottom ==========*/
--mb-0-25: 0.25rem;
--mb-0-5: 0.5rem;
--mb-0-75: 0.75rem;
--mb-1: 1rem;
--mb-1-25: 1.25rem;
--mb-1-5: 1.5rem;
--mb-2: 2rem;
--mb-2-5: 2.5rem;
/*========== z index ==========*/
--z-tooltip: 10;
--z-fixed: 100;
/*========== Hover overlay ==========*/
--img-transition: 0.3s;
--img-hidden: hidden;
--img-scale: scale(1.1);
}
@media screen and (min-width: 968px) {
:root {
--biggest-font-size: 4rem;
--h1-font-size: 2.25rem;
--h2-font-size: 1.75rem;
--h3-font-size: 1.25rem;
--normal-font-size: 1rem;
--small-font-size: 0.875rem;
--smaller-font-size: 0.813rem;
}
}
/*========== Variables Dark theme ==========*/
body.dark-theme {
--first-color-second: hsl(var(--hue-color), 54%, 12%);
--title-color: hsl(var(--hue-color), 24%, 95%);
--text-color: hsl(var(--hue-color), 8%, 75%);
--input-color: hsl(var(--hue-color), 29%, 16%);
--body-color: hsl(var(--hue-color), 29%, 12%);
--scroll-bar-color: hsl(var(--hue-color), 12%, 48%);
--scroll-thumb-color: hsl(var(--hue-color), 12%, 36%);
}
섹션별로 바로 디자인이 들어가기 전, 바탕으로 깔리게 되는 속성들을 먼저 설정해주었다.
margin, padding, 폰트사이즈, 폰트컬러, 폰트종류, 이미지 크기, 버튼이나 인풋박스 겉 테두리 없애기 등 기본적으로 디폴트로 지켜져야 하는 것들을 정리하였다.
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html {
scroll-behavior: smooth;
}
body {
margin: var(--header-height) 0 0 0;
font-family: var(--body-font);
font-size: var(--normal-font-size);
background-color: var(--body-color);
color: var(--text-color);
}
h1,
h2,
h3 {
color: var(--title-color);
font-weight: var(--font-semi-bold);
font-family: var(--title-font);
}
ul {
list-style: none;
}
a {
text-decoration: none;
}
img,
video {
max-width: 100%;
height: auto;
}
button,
input {
border: none;
font-family: var(--body-font);
font-size: var(--normal-font-size);
}
button {
cursor: pointer;
}
input {
outline: none;
}
.main {
overflow-x: hidden;
/* 부모요소의 범위를 넘어가는 자식 요소의 부분은 보이지 않도록 처리한다. */
}
기본적으로 레이아웃은 내용별로 section이 가장 바깥에 있는 박스이고, 그 안에 container 박스로 감싸주면서 아래와 같은 재사용되는 css 속성들을 적용시켜주었다.
section과 container로 감싸는 내부 컨텐츠들은 공통적으로 아래 속성들이 적용된다. padding, margin, text컬러나 정렬 등이 이에 해당된다.
.section {
padding: 4.5rem 0 2.5rem;
}
.section__title {
font-size: var(--h2-font-size);
color: var(--title-color);
text-align: center;
text-transform: capitalize;
margin-bottom: var(--mb-2);
}
.container {
max-width: 968px;
margin-left: var(--mb-1);
margin-right: var(--mb-1);
}
.grid {
display: grid;
gap: 1.5rem;
}
이번 웹페이지를 만들면서 가장 많이 연습해보았던 속성이다. 아래와 같은 상황에 사용하였다.
해당 요소에는 position: absolute;
를 부여하고 그 요소의 부모요소에는 position: relative;
를 부여하면 된다.
position: absolute;
가 부여된 속성에 top, right, bottom, left
등의 속성을 추가로 주어 독립적으로 위치가 조정되도록 하면 된다.
예시를 들어서 하나를 설명해보자면...
.place__card
라는 부모요소(사진과 텍스트를 모두 담고 있는 박스)에 relative
속성을 부여하고, .place__content
라는 자식 요소(텍스트)에 absolute
속성을 부여하여, 사진 위로 overwrite을 시켰다. 이 때 top, left
속성을 0으로 주었더니 사진 상단에서부터 텍스트가 채워졌다.
.place__card {
position: relative;
overflow: var(--img-hidden);
}
.place__content {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 0.75rem 0.75rem 1rem;
}
이 웹페이지에서는 이미지가 굉장히 여러개가 쓰였다. 조금 더 동적인 페이지를 만들기 위해 마우스를 사진위로 올렸을 시 순간적으로 조금 확대되는 에니메이션을 구현해보았다. 이를 위해서 부모속성 div요소를 꼭 만들어 사진을 한 번 감싸주고, overflow, transition, transform
속성을 적절히 사용해주었다. 이미지가 조금 더 생동감 있게 보여질 수 있다.
예시를 들면 아래와 같다.
.home__info-overlay {
overflow: var(--img-hidden);
}
.home__info-img {
width: 145px;
transition: var(--img-transition);
}
.home__info-img:hover {
transform: var(--img-scale);
}
추가로 스폰서의 로고들은 아래와 같이 filter: invert()
속성으로 로고 위에 hover시 에니메이션을 구현하였다.
.sponsor__img {
width: 90px;
filter: invert(0.7);
transition: var(--img-transition);
}
.sponsor__img:hover {
filter: invert(0.5);
}
가장 처음에 보여지는 홈 section
에서 이미지를 배경으로 두고 텍스트 요소가 그 위로 overwrite됨을 표현하였다.
일단 배경이 되는 이미지의 position
속성은 absolute
로 두고 텍스트 div박스(이미지의 자식속성 아님!)는 position
속성을 relative
로 두었다.
이미지에 object-fit, object-position
등의 속성을 부여하여 이미지가 웹 페이지 크기에 맞춰서 반응하게끔 하였다.
그리고 첫 화면은 홈 section
으로 꽉 차면 좋겠어서 height
속성을 100vh
로 설정하였다.
.home__img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100vh;
object-fit: cover;
object-position: 83%;
}
.home__container {
position: relative;
height: calc(100vh - var(--header-height));
align-content: center;
row-gap: 3rem;
}
이 사이트에서는 버튼이 상당히 여러개가 쓰였다. 기본적으로 재사용되는 버튼의 속성들을 아래와 같이 정하였다. hover시 속성도 정해주었다.
.button {
display: inline-block;
background-color: var(--first-color);
color: var(--white-color);
padding: 1rem 2rem;
font-weight: var(--font-semi-bold);
transition: 0.3s;
border-radius: 5px;
}
.button:hover {
background-color: var(--first-color-alt);
}
조그만 text data는 span태그를 사용하였다. span은 기본적으로 display: inline 속성을 내포하고 있다. 이 때 width와 height 속성을 지정해도 무시된다. 왜냐하면 해당 태그가 마크업하고 있는 컨텐트의 크기 만큼만 공간을 차지하도록 되어 있기 때문이다. 또한, margin과 padding 속성은 좌우 간격만 반영이 되고, 상하 간격은 반영이 되지 않는다.
따라서 안전하게 사용하기 위하여, inline 엘리먼트와 달리 width, height, margin, padding 속성이 모두 반영이 되게끔 display: block
속성을 부여해주었다.
부모요소의 display
의 속성이 grid
인 요소에서 알아둬야 할 자식 속성들의 위치 정렬 속성이 있다.
justify-items
속성은 수직축을 중심으로 좌우로 위치를 조정한다.
justify-contents
속성은 수평축을 기준으로 상하위치를 조정한다.
두 속성의 가장 중요한 차이는... justify-items
는 grid의 위치가 변하지 않은 상태에서 내부 요소의 위치 조정이며, justify-content
는 grid의 위치 자체가 변한다는 것이다!
따라서 (모든 경우에 그렇진 않았지만) 쉽게 이해하자면
justify-contents: center
속성을 사용하였고, justify-items: center
속성을 사용하였다.grid 방향 정렬 관련 설명이 매우 자세한 사이트: https://happygunja.tistory.com/107
유튜브 컨텐츠: https://youtu.be/YzRDHxbw1RU