Emotion(Styled), Props 전달하기(Typescript)

Typescript와 함께 동적 CSS 스타일 사용하기
import styled from "@emotion/styled";

const StyledPropsTest = styled.div`
  width: 120px;
  height: 40px;
  font-size: 25px;
  background: ${(props) => (props.testProps ? "blue" : "red")};
  color: white;
`;

const StyledTest = ({testprops}) => {
  return(
    <StyledPropsTest testProps={testprops}>Prop Test</StyledPropsTest>
  )
}

export default StyledTest;

컴포넌트 내부에서 사용하는 변수를 CSS에 전달하여 동적 스타일을 적용하기 위해서는 위와 같이 props를 전달하는 방법이 있습니다.

하지만 Typescipt를 사용하여 custom props를 사용하면 다음과 같은 에러를 만나게 됩니다.

(property) testProps: boolean
Type ‘{ children: string; testProps: boolean; }’ is not assignable to type ‘IntrinsicAttributes & { theme?: Theme | undefined; as?: ElementType<any> | undefined; } & ClassAttributes<HTMLDivElement> & HTMLAttributes<…>’.
Property ‘testProps’ does not exist on type ‘IntrinsicAttributes & { theme?: Theme | undefined; as?: ElementType<any> | undefined; } & ClassAttributes<HTMLDivElement> & HTMLAttributes<…>’.ts(2322)

이는 타입스크립트에서 props의 타입을 체크하기 때문인데요.

다음과 같이 간단하게 <{data:type}>의 타입 단언(Type Assertion)으로 해결할 수 있습니다.

const StyledPropsTest = styled.div<{testProps:boolean}>`
  width: 120px;
  height: 40px;
  font-size: 25px;
  background: ${(props) => (props.testProps ? "blue" : "red")};
  color: white;
`;

다음과 같이 에러가 사라진 것을 확인할 수 있습니다.

CSS, calc()를 사용해 main(body) 높이 자동 설정하기

CSS에서 calc 메서드 사용하기

CSS에서 calc() 메서드를 사용하면 window 창의 사이즈 변경에 따라 자동으로 길이를 계산할 수 있습니다.

header, main, footer의 레이아웃을 나눌 때 main에서 calc()를 사용하게 되면 윈도우 창의 크기가 줄어들어도 main의 내용이 잘릴 염려 없이 가변적으로 창의 크기에 맞게 표현할 수 있습니다.

1. 필요성

예를 들면 다음과 같은 상황에서 유용합니다.

위와 같은 화면이 있을 때 윈도우 창의 사이즈를 줄이면(resizing) 가운데 main의 스크롤을 끝까지 내려도 데이터가 모두 표시되지 않을 때가 있습니다.

스크롤을 끝까지 내렸지만 이렇게 r 까지만 표시되고 아랫부분은 짤려서 표시되지 않습니다.

이런 상황에서 main의 div 높이를 계산하여 자동으로 조절해주면 다음과 같이 윈도우가 리사이징 되더라도 화면이 짤리지 않고 유지되는 것을 볼 수 있습니다.

2. 적용하기

main div의 높이(height)에 calc() 메서드를 사용하여 ‘뷰 높이(vh) – 나머지 공간’을 해주면 됩니다.

다만 전달값의 +, – 앞 뒤에는 반드시 공백을 삽입해야 합니다.

// OK
height: calc(100vh - 300px);

// 에러(공백 없음)
height: calc(100vh-300px);

결과는 다음과 같습니다.