1. 모달 생성하기
모달이란 웹이나 앱에서 일시적으로 화면에 나타나는 팝업 형태의 UI 컴포넌트다.
주로 사용자의 입력이나 알림, 추가 정보를 표시하는 데에 사용된다.
모달이 나타나면 배경은 일시적으로 가려져 다른 부분에 대한 상호작용이 차단되는데, 모달을 닫거나 작업을 완료하면 모달은 사라진다.
모달은 사용자 경험을 개선하고 정보를 전달하는 역할을 하는데, 일반적으로 흐릿한 배경과 모달 내 내용을 포함하는 컨테이너로 구성된다.
이 이미지와 같이 여러 영화가 있는 배경은 흐릿해지고, 등장한 모달이 클릭한 영화의 상세 정보를 제공하고 있다.
우측 상단의 ❌를 누르면 사라진다. (추후에 저 버튼이 아니라 바깥 화면을 눌러도 모달이 꺼지게끔 기능을 디벨롭할 예정이다.)
먼저 모달의 열림과 닫힘을 표현하기 위해 const [modalOpen, setModalOpen] = useState(false)를 선언해주고,
클릭한 영화의 정보가 보여지게 const [movieSelected, setMovieSelected] = useState({})를 선언해준다.
영화 이미지를 클릭하면 모달이 오픈되는 함수 handleClick를 호출한다. 이 때 어떤 영화를 눌렀는지 알기 위해 파라미터를 전해준다.
<div id={id} className="row__posters">
{movies.map((movie) => (
<img
key={movie.id}
className={`row__poster ${isLargeRow && "row__posterLarge"}`}
src={`https://image.tmdb.org/t/p/original/${
isLargeRow ? movie.poster_path : movie.backdrop_path
}`}
alt={movie.name}
onClick={() => handleClick(movie)}
// 함수 호출 시 어떤 영화를 눌렀는지 알아야 하기 때문
/>
))}
</div>
함수 handleClick은 아래와 같다.
const handleClick = (movie) => {
setModalOpen(true);
setMovieSelected(movie); //객체 안에 영화 정보를 넣어줬음
};
클릭하면 모달이 열리는 부분이 true가 되고, 선택한 영화에 대한 정보를 가져와야 한다.
이제 [Row 컴포넌트] 왼쪽 화살표 - 영화 나열 - 오른쪽 화살표 의 맨 밑에 모달이 작동할 때를 구현한다.
modelOpen이 true여야 하고, MovieModal이라는 컴포넌트에 movieSelected의 정보를 props로 전달해줘야 한다.
모달이 열리면 setOpenModal도 true로 작동되어야 한다.
{modalOpen && (
<MovieModal {...movieSelected} setModalOpen={setModalOpen} />
)}
{/* modalOpen이 true면 MovieModal이 보여지는데 이 안에는 movieSelected의 정보가 들어 있음 */}
이런 식으로 들어 있고, ...movieSelected에는 아까 말한 것처럼 빈 객체 안에 영화 정보가 들어 있다.
MovieModal 컴포넌트에서는 이미지 경로, 제목(title=name), 줄거리(개요), 릴리즈 데이트(=처음 방영 날짜), 평점, setModalOpen을 props로 내려준다. 위에 슈퍼 마리오를 보면 이 부분이 똑같이 들어가 있다.
2. 모달 UI 만들기
위에서 MovieModal 컴포넌트에 backdrop_path, title, overview, name, release_date, first_air_date, vote_average, setModalOpen를 줬다. 이 부분을 가지고 UI를 구성해보자.
크게 presentation이라는 div 안에 wrapper-modal, modal을 감싸 만들어주자.
모달을 닫는 ❌ 버튼은 이벤트 onClick을 부여해 setModalOpen이 false가 되게 한다.
위에서 모달이 열릴 때 이 부분이 true여야 열렸기 때문에 닫을 때는 이 부분을 false로 만들어 열리지 않게 하는 것이다.
그래서 위에 props로 받을 때 영화 정보와 같이 이 부분을 받아왔다.
이미지, 평점, 줄거리 등은 동일하게 받아오고, 방영 날짜나 제목의 경우 없는 경우를 고려해 삼항연산자로 대체할 것을 넣어주었다.
return (
<div className="presentation">
<div className="wrapper-modal">
<div className="modal">
<span className="modal-close" onClick={() => setModalOpen(false)}>
{/* row.js 에 있는 State */} ❌
</span>
<img
className="modal__poster-img"
src={`https://image.tmdb.org/t/p/original/${backdrop_path}`}
alt="modal__poster-img"
/>
<div className="modal__content">
<p className="modal__details">
<span className="modal__user-perc">100% for you</span>
{release_date ? release_date : first_air_date}
</p>
<h2 className="modal__title"> {title ? title : name}</h2>
<p className="modal__overview"> 평점: {vote_average}</p>
<p className="modal__overview"> {overview} </p>
</div>
</div>
</div>
</div>
);
📌 !important ⭐️
CSS에서 속성의 우선 순위를 최상으로 선택하는 특수한 키워드다.
일반적으로 CSS는 아래, 가장 최근에 쓴 것이나 국소 부위에 해당하는 스타일 규칙을 우선으로 쓴다고 알고 있는데
이 속성을 적용하면 그런 규칙들을 다 무시하고 해당 부분이 최고 우선 순위를 갖게 된다.
📌 -webkit-tap-highlight-color: transparent;
모바일 기기에서 터치 이벤트로 요소를 탭 할때 발생하는 하이라이트를 비활성화한다.
모바일 기기에서 어떤 요소를 탭하면 가끔 파란색으로 박스가 생기는 걸 볼 수 있다. 그 부분을 투명하게 바꿔주었다.
-webkit-tap-highlight-color - CSS: Cascading Style Sheets | MDN
-webkit-tap-highlight-color is a non-standard CSS property that sets the color of the highlight that appears over a link while it's being tapped. The highlighting indicates to the user that their tap is being successfully recognized, and indicates which el
developer.mozilla.org
📌 스크롤 바 숨기기
/* Hide scrollbar for IE, Edge and Firefox */
.modal {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
-ms-overflow-style 는 IE, Edge 브라우저에서 오버 플로우 시 스크롤바 스타일을 지정하는데, 현재 스크롤바를 none으로 해두었다.
scrollbar-width 는 Firefox 브라우저에서 스크롤바의 너비를 지정하는데 동일하게 너비를 없애서 보이지 않게 해두었다.
이렇게 각 브라우저에 맞게 동일한 기능을 적용한 것은 크로스 브라우징을 위한 것이다.
(*크로스 브라우징: 웹, 앱이 여러 웹 브라우저에서 일관되게 동작하고 호환되는 것)
📌 Break Point ⭐️⭐️⭐️
반응형 웹 디자인에서 화면 크기, 장치 유형에 따라 디자인 레이아웃이 변하는 지점
예를 들어 휴대전화는 데스크탑 모니터보다 보이는 화면이 작기 때문에 화면에 상품이 3개씩 보이게 해두었다면, 데스크탑 모니터에서는 화면에 상품이 7개씩 보일 수 있게 레이아웃을 조절하는 지점을 말한다.
일반적으로 768px, 992px, 1200px을 사용하는데 이 값들은 스마트폰, 태블릿, 데스크탑을 고려해 선택되는 값이라고 한다.
어쩐지 왜 자꾸 강사님이 768px을 정확하게 쓰시는지 궁금했는데 이것 때문이었다!
[HTML] 반응형 웹 (Responsive) 처리
head태그 안에, 미디어쿼리(media query) @media screen and (max-width : 1200px) { .box { font-size : 40px; } } @media screen and (max-width : 768px) { .box { font-size : 30px; } } media query를 작성할 때는 CSS파일 최하단에 작성한다
hellowwworld.tistory.com
이런 식으로 기대 점수와 릴리즈되는 날짜, 제목, 평점, 줄거리를 가져와 모달을 만들었다.