모든 프로젝트를 진행하면서 어떤 폰트를 사용할까? 에 대한 고민을 정말 오랜 시간 많이 했다.
느낌으로 결정하는 폰트보다, 상황에 맞는 가독성 좋은 그리고 예쁘기까지 한 폰트를 알아보자.
2. 세리프(Serif)
글자의 끝에 장식선과 곡선이 존제하는 체. 빽빽한 글을 읽을 때 눈의 피로를 줄여줘 가독성에 용의 하다.
3. 산세리프(Sans serif)
세리프와 달리 끝에 장식선이 없다. 깔끔한 디자인과 크기가 작아도 가독성이 좋아서 인터페이스 등에 사용하기 용의 하다.
4. 디스플레이(Display)
폰트 사이즈가 클 때 유리하다. 그래서 제목이나 로고 등의 용도로 사용할 때 용의 하다.
하지만 가독성이 낮아 텍스트가 많거나, 사이즈가 작으면 사용해서는 안된다.
5. 고정폭(Monospace)
글자의 실제 크기와 상관없이, 모든 글자가 동일한 가로길이를 보여준다.
주로, 텍스트를 자세하게 표현할 수 없는 경우 사용한다.
6. 세부적인 조절에 필요한 용어
크기 : 일명 pt. 일반적으로는 css에서 font-size로 조절하는 부분이다. 대부분 10px이하는 가독성이 너무 떨어져서 추천하지 않고, 12px정도가 정석이다.
줄 간격 : css에서 line-height로 조절하는 부분이다. 글자 간의 세로 길이를 뜻하며, 어느 정도 떨어져서 자연스럽게 텍스트가 읽히도록 한다. 너무 많이 띄어놓으면 자연스럽게 읽히지가 않고 강조하는 느낌이나, 아예 다른 섹션의 글처럼 느껴질 수 있다.
자간(tracking)과 커닝(karning) : 자간은 css에서 letter-spacing으로 조절하는 부분이다. 글자 하나하나 간의 사이 간격을 말한다. 커닝은 css에서 font-kerning으로 조절하는 부분이다. 대부분의 브라우저는 auto로 설정되어 있고, 사용하거나(normal), 사용하지 않는(none)을 속성으로 가지고 있다. 글자 내부의 공백(자간보다 좁은 글자 하나에 해당하는 빈 공간)을 조절한다.
폰트 페어링(font pairing) : 한 가지 디자인에서 폰트를 여러 가지 조합한다. 너무 다른 폰트를 같이 사용하면 어색하다.
Tip: 같은 폰트 중에서 굵기나 볼드, 이탤릭체 등을 사용해서 다른 느낌을 주어서 같은 폰트이지만 미묘하게 다른 느낌으로 사용할 수 도 있다.
Tip: 형태가 비슷한 폰트는 같이 사용하는 것을 피하는 것이 좋다. 세리프와 산세리프를 사용하면 비슷하지만 다른 느낌으로 사용할 수 있다.
가독성 : 얼마나 잘 읽히는가에 관한 것이다. UX에서 가장 중요한 요소이다.
Tip: 컴퓨터 화면에서는 작은 폰트로 텍스트를 표시할 경우가 많은데 이때, 산세리프가 유리하다.
Tip: 이탤릭체나 필기체 등을 너무 남발하면 가독성은 최악이다. 적당히 필요한 곳에만 사용한다.
Tip: 가끔 구분이 힘든 글자들이 섞여있는 폰트들이 존재한다. (ex: e, c, d, o 등이 주로 헷갈리게 표현될 수 있다) 이런 부분까지 확인하고 사용하는 것이 옳다.
Tip: 대문자는 제목에서 정도만 사용하자. 읽기가 쉽지 않다.
사실 이부분은 디자인에 가깝다. 하지만 개발자가 알아서 나쁘지 않은 부분이다. 가독성 부분은 UX에서도 매우 중요한 부분이며, 여러 가지 폰트를 다양하게 적용시켜 보면서 최선의 선택을 하는 것은 디자이너와 협업하기 전에도 필요하기 때문이다. 아래에는 참고하거나 폰트를 얻을 수 있는 사이트를 적어 놓는다. 물론, 가장 중요한 '저작권' 문제가 있다. 대부분 폰트를 다운 받을때 확인 할 수 있도록 적혀있다. 꼭 사용이 가능한 것인지 확인하고 사용하자!
포트폴리오를 역시나 만들고 있는 중에, 프로젝트나 설명 부분에 옆으로 넘어가는 디자인을 만들면 가독성도 좋고 디자인도 뛰어 날 것이라고 생각했다. '라이브러리를 사용하자!'라는 생각은 있었다만, 아직 익숙하지 않은 타입 스크립트와 생각보다 css를 적용하는 부분이 헷갈렸다. 그래서 복습하고자 이 글을 작성하고 있다.
2. Carousel VS Slider
구글링을 하다가 알게 된 사실이다. 생각해 보니 슬라이더는 저렇게 음량등을 조절할 때 사용하는 것이었다!
저렇게 사진이나 내용들이 넘어가는 것은 'Carousel'이다. 한국말로는 회전목마.
2. 사전 작업은 어떻게 합니까?
우리가 install 해야 할 것은 총 3개
npm install --save @types/react-slick
npm install --save react-slick
npm install --save slick-carousel
위의 3가지를 모두 install 해야 한다. 그래야 올바르고 쉽고 간편하게 기능하게 만들 수 있다.
그리고 사용할 tsx 파일위에 또 3가지 내용을 import 한다.
import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
css 파일을 따로 불러줘야 한다. 아니면 옆으로 넘길 수 있는 화살표나 지금 어떤 내용을 보고 있는지를 표시하는 점(Dots)이 안 나온다.
3. 일단 코드 쳐 보기
import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
function Carousel() {
const settings = {
dots: true,
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1,
}
// 사용할 Carousel의 기본 세팅을 해준다. props로 받아 와야 하기 때문에 객체에 넣어서 받아온다.
// 더 많은 설정이 있지만, 그것은 직접 코드를 뜯어 보면 쉽게 알 수 있다.
// 위의 설정은 홈페이지에 나와있는 기본 설정을 한번에 보여줄 갯수만 1개로 바꾼 것이다.
<section className="page-carousel">
<Slider {...settings}>
<div>거창한 내용</div>
<div>대단한 내용</div>
<div>멋있는 내용</div>
<div>예쁜 내용</div>
<div>무언가 엄청난 내용</div>
</Slider>
</section>
}
export default Carousel;
이렇게 하면 기본적인 케러솔을 볼 수 있다. 위의 예시 그림과 비슷하게 만들어질 것이다. 기본적인 css는 적용되어 있고, 기능 또한 적용되어 있다.
4. 커스텀하기
이대로 쓰면 모두가 똑같은 디자인과 UI를 가지게 될 수 있으므로, 조금 바꿔본다.
화살표 커스텀
화살표는 이미지 혹은 아이콘 뭐든지 가능하다. 아에 컴포넌트로 만들어 넣을 수 있다.
그러므로 tsx 파일인 NextArrow.tsx 파일을 만들었다.
import React from "react";
interface NextArrowProps {
onClick?: React.MouseEventHandler<HTMLDivElement>;
}
// 타입스크립트를 사용하기 때문에 onClick 이벤트를 props로 받아준다.
// className을 받아줄 수 도 있다. 그리고 부모 컴포넌트에서 설정해 줘도 된다.
export default function NextArrow({ onClick }: NextArrowProps) {
return <div className="next-arrow" onClick={onClick}>누르면 넘어감</div>;
}
html 태그를 img로 바꿔서 이미지를 넣을 수 도 있다. css를 설정하면 마음대로 사용할 수 있다.
하지만 css가 조금 곤란하다. 원래 있던 slick 자체 테마에 있던 위치 설정을 해놓은 css들을 일단 모두 써 놓고, 이후에 조금씩 바꿔 가는 방향으로 작업해야 원하는 위치에 화살표를 위치시킬 수 있다.
매일 포트폴리오를 만들고 있다가 메뉴 토글을 만드려고 오픈 핸들러 함수를 자식 컴포넌트로 내리려고 하는 순간, 영문모를 에러들을 만났다. 여러 번 프로젝트를 만들면서 매번 하던 작업이라 실수한 줄 알았지만 아무리 봐도 틀린 건 없고... 에러 메시지를 보니 타입 스크립트가 뭔가 이상하다고 알려주는 것 같아서 구글링 하고 찾아본 결과 답을 찾을 수 있었다.
2. 무엇이 문제인가요?
가장 중요한 포인트는 'props를 받는 자식 컴포넌트가 부모에게 받을 props의 형태를 결정 할 수 있다'는 것이다!
그래서 더 정확한 데이터 만을 넘겨 줄 수 있다.
3. 어떻게 사용할까요?
일단 원래 하듯이 props를 내려주는 부모부터 살펴본다. 상위에서 Menu 컴포넌트로 헨들러 함수를 내려 줄 것이다.
// 먼저 useState를 이용해 상태를 만들고 블리언 타입으로 설정한 후 초기값을 주었다. react와 조금 다르지만,
// 그리 복잡하지 않고 타입을 생략해도 작동하는 것은 문제없다.
const [isOpenMenu, setIsOpenMenu] = useState<boolean>(false);
const openMenuHandler = () => {
setIsOpenMenu(!isOpenMenu);
};
// react에서 하듯이 이렇게 넘겨준다. 넘겨만 주면 에러가 날 것이다. 받는 쪽을 보자.
return (
<div>
<Menu openMenuHandler={openMenuHandler}/>
</div>
)
이제 진짜 본론인 어떻게 받는가? 이다.
// React 지우면 안된다. 바벨을 만약 쓴다면 필요하다고 한다.
// FC로 function component를 사용 할 수 있게 만든다.
import React, { FC } from "react";
// interface를 이용해 받을 props의 타입을 결정해준다.
interface Props {
openMenuHandler(): void;
}
// 나머지는 같다.
const Menu: FC<Props> = ({ openMenuHandler }) => {
return (
<div>
<div onClick={() => openMenuHandler()}>Open</div>
</div>
)
}
export default Menu;
이렇게 받는 쪽에서 타입을 정해줘야 받을 수 있다. 다른 데이터 타입도 같다.
4. 추가로 알아보는 type
그렇다면, 다른 타입은 어떻게 정해줘야 할까?
일단 any로 설정하고 props를 내려본다. 그러면 마우스를 대보면 정확한 타입이 뜨고, 이후 그 타입으로 바꿔주면 된다.
사용할 수 있는 타입에는 우리가 기본적으로 쓰는 타입들(ex: Number, Boolean 등)이 있고
CSS로도 라이브러리를 쓰지 않더라도 간단하게 애니메이션을 표현할 수 있다. flex-box를 어느 정도 사용하게 되고 나니, 이제 자연스럽게 애니메이션을 이용해 css를 활용해보려는 욕심이 났다. 그래서 움직임과 관련한 속성들을 전부 정리해 보려고 한다.
2. transform
위치 값이나 크기 등을 변환시킬 수 있다.
scale(크기), skew(기울어짐), rotate(회전), translate(위치 이동), perspective(3D), matrix(perspective를 제외하고 앞의 모든 속성을 다 적용시킴)의 속성들을 사용할 수 있다.
각 속성들은 단위와 함께 적어서 변화를 줄 수 있다. 그리고 속성 뒤에 X, Y를 붙이면 축에 따른 변화도 가능하다.
3. transition
얼마나 오랜 시간 동안 애니메이션을 재생시킬 것인가를 정한다.
그래서 뒤에 시간이 온다. (ex: 2s, 2000ms 등 )
ease(기본값, 천천히 시작해서 빨라졌다가 다시 느리게 끝), ease-in(시작이 느림), ease-out(끝이 느림), ease-in-out(느리게 시작해서 느리게 끝), linear(전부 동일한 속도)의 속성들도 사용할 수 있다. 이후 시간 단위도 붙여도 된다. 그 시간 안에서 지정한 방식의 속도를 가진다.