[React] Movie app clone coding : Giving some CSS to
7-2. Giving some CSS to
-
To install it run:
1yarn add react-lines-ellipsis
CSS 꾸미기
App.css
1.App {
2 padding: 50px;
3 display: flex;
4 justify-content: space-around;
5 flex-wrap: wrap;
6 font-size: 14px;
7}
8
9.App--loading{
10 display: flex;
11 justify-content: center;
12 align-items: center;
13 height: 100%;
14}
App.js
1 render() {
2 const {movie} = this.state;
3 return (
4 <div className={movie ? "App" : "App--loading"}>
5 {movies ? this._renderMovies() : 'Loading'}
6 </div>
7 );
8 }
9}
-
<div className={movie ? "App" : "App--loading"}>
movies가 있으면 div의 이름은 app이 되고, movies가 없으면 app-loading이 된다.
-
그리고 각각의 css를
App.css
에 정했다.
index.css
1body {
2 margin: 0;
3 padding: 0;
4 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
5 background-color:#EFF3F7;
6 height: 100%;
7}
8
9html, #root{
10 height:100%;
11}
Movie.css
1.Movie{
2 background-color:white;
3 width:40%;
4 display: flex;
5 justify-content: space-between;
6 align-items:flex-start;
7 flex-wrap:wrap;
8 margin-bottom:50px;
9 text-overflow: ellipsis;
10 padding:0 20px;
11 box-shadow: 0 8px 38px rgba(133, 133, 133, 0.3), 0 5px 12px rgba(133, 133, 133,0.22);
12}
13
14.Movie__Column{
15 width:30%;
16 box-sizing:border-box;
17 text-overflow: ellipsis;
18}
19
20.Movie__Column:last-child{
21 padding:20px 0;
22 width:60%;
23}
24
25.Movie h1{
26 font-size:20px;
27 font-weight: 600;
28}
29
30.Movie .Movie__Genres{
31 display: flex;
32 flex-wrap:wrap;
33 margin-bottom:20px;
34}
35
36.Movie__Genres .Movie__Genre{
37 margin-right:10px;
38 color:#B4B5BD;
39}
40
41.Movie .Movie__Synopsis {
42 text-overflow: ellipsis;
43 color:#B4B5BD;
44 overflow: hidden;
45}
46
47.Movie .Movie__Poster{
48 max-width: 100%;
49 position: relative;
50 top:-20px;
51 box-shadow: -10px 19px 38px rgba(83, 83, 83, 0.3), 10px 15px 12px rgba(80,80,80,0.22);
52}
53
54/* Mobile Phone */
55@media screen and (min-width:320px) and (max-width:667px){
56 .Movie{
57 width:100%;
58 }
59}
60
61/* Mobile-portrait */
62@media screen and (min-width:320px) and (max-width:667px) and (orientation: portrait){
63 .Movie{
64 width:100%;
65 flex-direction: column;
66 }
67 .Movie__Poster{
68 top:0;
69 left:0;
70 width:100%;
71 }
72 .Movie__Column{
73 width:100%!important;
74 }
75}
Movie.js
1import LinesEllipsis from 'react-lines-ellipsis'
2import './Movie.css';
3
4function Movie({title, poster, genres, synopsis}){
5 return(
6 ...
7 <p className="Movie__Synopsis">
8
9 /* Synopsis를 줄여주는 역할 :
10 * npm install --save react-lines-ellipsis
11 */
12 <LinesEllipsis
13 text={synopsis}
14 maxLine='3'
15 ellipsis='...'
16 trimRight
17 basedOn='letters'
18 />
19 </p>
20 ...
21 )
22}
전체코드
App.js
1import React, { Component } from 'react';
2import './App.css';
3import Movie from './Movie';
4
5class App extends Component {
6
7 state = {}
8
9 componentDidMount(){
10 this._getMovies(); // 큰 사이즈의 componentDidMount를 갖고 싶지 않으므로
11 }
12
13 _renderMovies = () => {
14 const movies = this.state.movies.map((movie, index) => {
15 return <Movie
16 title={movie.title_english}
17 poster={movie.medium_cover_image}
18 key={movie.id}
19 genres={movie.genres}
20 synopsis={movie.synopsis}
21 />
22 })
23 return movies
24 }
25
26 _getMovies = async() => {
27 const movies = await this._callApi()
28 this.setState({
29 movies
30 })
31 }
32
33
34 _callApi = () => {
35 return fetch('https://yts.am/api/v2/list_movies.json?sort_by=rating')
36 .then(response => response.json())
37 .then(json => json.data.movies)
38 .catch(err => console.log('error'))
39 }
40
41
42 render() {
43 const {movies} = this.state;
44 return (
45 <div className={movies ? "App" : "App--loading"}>
46 {movies ? this._renderMovies() : 'Loading'}
47 </div>
48 );
49 }
50}
51
52export default App;
App.css
1.App {
2 padding: 50px;
3 display: flex;
4 justify-content: space-around;
5 flex-wrap: wrap;
6 font-size: 14px;
7}
8
9.App--loading{
10 display: flex;
11 justify-content: center;
12 align-items: center;
13 height: 100%;
14}
Movie.js
1import React from 'react';
2import propTypes from 'prop-types';
3import LinesEllipsis from 'react-lines-ellipsis'
4import './Movie.css';
5
6function Movie({title, poster, genres, synopsis}){
7 return(
8 <div className="Movie">
9 <div className="Movie__Columns">
10 <MoviePoster poster={poster} alt={title} />
11 </div>
12 <div className="Movie__Columns">
13 <h1>{title}</h1>
14 <div className="Movie__Genres">
15 {genres.map((genre, index) => <MovieGenre genre={genre} key={index} />)}
16 </div>
17 <p className="Movie__Synopsis">
18 <LinesEllipsis
19 text={synopsis}
20 maxLine='3'
21 ellipsis='...'
22 trimRight
23 basedOn='letters'
24 />
25 </p>
26
27 </div>
28 </div>
29 )
30}
31
32function MoviePoster({poster, alt}) {
33 return(
34 <img src={poster} alt={alt} title={alt} className="Movie__Poster" />
35 )
36}
37
38
39function MovieGenre({genre}){
40 return(
41 <span className="Movie__Genre">{genre}</span>
42 )
43}
44
45
46Movie.propTypes = {
47 title: propTypes.string.isRequired,
48 poster: propTypes.string.isRequired,
49 genres: propTypes.array.isRequired,
50 synopsis: propTypes.string.isRequired
51}
52
53MoviePoster.propTypes = {
54 poster: propTypes.string.isRequired,
55 alt: propTypes.string.isRequired
56}
57
58MovieGenre.prototype ={
59 genre: propTypes.string.isRequired
60}
61
62
63export default Movie;
Movie.css
1.Movie{
2 background-color:white;
3 width:40%;
4 display: flex;
5 justify-content: space-between;
6 align-items:flex-start;
7 flex-wrap:wrap;
8 margin-bottom:50px;
9 text-overflow: ellipsis;
10 padding:0 20px;
11 box-shadow: 0 8px 38px rgba(133, 133, 133, 0.3), 0 5px 12px rgba(133, 133, 133,0.22);
12}
13
14.Movie__Column{
15 width:30%;
16 box-sizing:border-box;
17 text-overflow: ellipsis;
18}
19
20.Movie__Column:last-child{
21 padding:20px 0;
22 width:60%;
23}
24
25.Movie h1{
26 font-size:20px;
27 font-weight: 600;
28}
29
30.Movie .Movie__Genres{
31 display: flex;
32 flex-wrap:wrap;
33 margin-bottom:20px;
34}
35
36.Movie__Genres .Movie__Genre{
37 margin-right:10px;
38 color:#B4B5BD;
39}
40
41.Movie .Movie__Synopsis {
42 text-overflow: ellipsis;
43 color:#B4B5BD;
44 overflow: hidden;
45}
46
47.Movie .Movie__Poster{
48 max-width: 100%;
49 position: relative;
50 top:-20px;
51 box-shadow: -10px 19px 38px rgba(83, 83, 83, 0.3), 10px 15px 12px rgba(80,80,80,0.22);
52}
53
54/* Mobile Phone */
55@media screen and (min-width:320px) and (max-width:667px){
56 .Movie{
57 width:100%;
58 }
59}
60
61/* Mobile-portrait */
62@media screen and (min-width:320px) and (max-width:667px) and (orientation: portrait){
63 .Movie{
64 width:100%;
65 flex-direction: column;
66 }
67 .Movie__Poster{
68 top:0;
69 left:0;
70 width:100%;
71 }
72 .Movie__Column{
73 width:100%!important;
74 }
75}
index.css
1body {
2 margin: 0;
3 padding: 0;
4 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
5 background-color:#EFF3F7;
6 height: 100%;
7}
8
9html, #root{
10 height:100%;
11}