문제
Next.js
에서 display
를 비롯한 스타일링이 제대로 작동하지 않았다. 그 이유는 무엇일까?
해결 방법
이 역시 고질적인
next/image
에 대한 이슈였다.기본적으로 next/image에서는 제대로 된 스타일링 기능을 보장해주지 않았다.
따라서 이를 해결하는 방법은, 상위 컴포넌트를 컨테이너처럼 씌워, 해당 이미지를 스타일링하는 방법이었다.
따라서, 다음과 같이
ImageContainer
을 만든 후, display
등 이미지를 스타일링하였다.import * as React from 'react'; import NextImage from 'next/image'; import styled from '@emotion/styled'; import { css, Interpolation, Theme } from '@emotion/react'; export interface ImageContainerProps { loader?: string; src: string; alt: string; width?: string | number; height?: string | number; margin?: string | number; padding?: string | number; position?: | undefined | 'static' | 'relative' | 'absolute' | 'fixed' | 'sticky'; placeholder?: 'blur' | 'empty'; blurDataUrl?: string; sizes?: string; objectFit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down'; layout?: 'intrinsic' | 'fixed' | 'fill' | 'responsive'; isCircle?: boolean; css?: Interpolation<Theme>; } const StyledImageContainer = styled.div` overflow: hidden; ${({ width, height, margin, padding, position, isCircle, }: Partial<ImageContainerProps>) => css` ${position ? `position: ${position};` : ''} width: ${typeof width === 'string' ? width : `${width}px`}; height: ${typeof height === 'string' ? height : `${height}px`}; padding: ${typeof padding === 'string' ? padding : `${padding}px`}; margin: ${typeof margin === 'string' ? margin : `${margin}px`}; border-radius: ${isCircle ? '50%' : 0}; `} `; const ImageContainer: React.FC<ImageContainerProps> = ({ src, alt, width = 40, height = 40, margin = 0, padding = 0, position = undefined, placeholder = 'empty', isCircle = false, objectFit = 'cover', layout = 'intrinsic', sizes = '100vw', ...props }) => { return ( <StyledImageContainer {...props} width={width} height={height} margin={margin} padding={padding} isCircle={isCircle} position={position} > <NextImage src={src} alt={alt} width="100%" height="100%" placeholder={placeholder} layout={layout} sizes={layout === 'fill' || layout === 'responsive' ? sizes : undefined} objectFit={objectFit} /> </StyledImageContainer> ); }; export default ImageContainer;
즉,
css
적인 요소는 위의 요소에 위임하고, 나머지 요소들은 NextImage
에 위임하는 꼴이다.결과적으로 어떻게 동작할까?
<div> {Array.from(new Array(20), (_, k) => k).map((i) => ( <ImageContainer key={i} isCircle src={`https://picsum.photos/${i + 1}00`} alt="사진 테스트" css={{ display: 'inline-block' }} /> ))} </div>
결과
호출할 때 전달한
css
Prop
이 옵션 값에 따라 잘 동작한다!