본문 바로가기

Programming/국비학원

220621 - 반응형 웹(고정/가변 그리드, 미디어 쿼리, flex box)

반응형 웹

: 하나의 웹사이트에서 pc, 스마트폰 등 기기에 따라 화면 크기가 자동으로 변하도록 만드는 웹페이지 접근 기법

(cf. 적응형 웹 : 각각의 기기 디스플레이에 맞춰 독립적 템플릿, 페이지 제작 ex.네이버, 다음)

 

 

  • 고정 그리드 (fixed grid)

: 그리드의 너비를 픽셀(px)로 고정

 

 

  •  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>고정 그리드</title>
    <style>
        #wrapper{
            width: 960px;
            margin: 0 auto;
        }
        header{
            width: 960px;
            height: 120px;
            background-color: rgb(156, 156, 247);
        }
        .head{
            color: #fff;
            text-align: center;
            line-height: 120px;
            font-size: 3em;
        }
        .content{
            float: left;
            width: 600px;
            height: 400px;
            padding: 15px;
            background-color: rgb(255, 225, 168);
        }
        .content img{
            width: 500px;
        }
        .side{
            float: right;
            width: 300px;
            height: 400px;
            padding: 15px;
            background-color: rgb(212, 240, 169);
        }
        footer{
            clear: both;
            height: 120px;
            background-color: pink;
        }
    </style>
</head>
<body>
    <div id="wrapper">
        <header>
            <h1 class="head">고정 그리드 홈페이지</h1>
        </header>
        <section class="content">
            <h2>홈페이지 메인 본문</h2>
            <img src="images/dish4.jpg" alt="">
        </section>
        <aside class="side">
            <h2>광고 영역</h2>
        </aside>
        <footer>
            <h2>푸터 영역</h2>
        </footer>
    </div>
</body>
cs

 

 

 

  • 가변형 그리드 (fluid grid)

: 백분율 이용하여 화면 너비에 대한 각 그리드 너비 비율 지정

 

=> 화면의 크기 변화에 따라 그리드의 크기도 유동적으로 변함

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>가변 그리드</title>
    <style>
        #wrapper{
            width: 100%;
            margin: 0 auto;
        }
        header{
            width: 100%;
            height: 120px;
            background-color: rgb(156, 156, 247);
        }
        .head{
            color: #fff;
            text-align: center;
            line-height: 120px;
            font-size: 5vw; /*1000px 기준 50px*/
        }
        .content{
            float: left;
            width: 62.5%;
            height: 400px;
            padding: 1.5625%;
            background-color: rgb(255, 225, 168);
        }
        .content img {
            max-width: 80%; /*최대 너비*/
            height: auto;
        }
        .side{
            float: right;
            width: 31.25%;
            height: 400px;
            padding: 1.5625%;
            background-color: rgb(212, 240, 169);
        }
        footer{
            clear: both;
            width: 100%;
            height: 120px;
            background-color: pink;
        }
    </style>
</head>
<body>
    <div id="wrapper">
        <header>
            <h1 class="head">가변 그리드 홈페이지</h1>
        </header>
        <section class="content">
            <h2>홈페이지 메인 본문</h2>
            <img src="images/dish4.jpg" alt="">
        </section>
        <aside class="side">
            <h2>광고 영역</h2>
        </aside>
        <footer>
            <h2>푸터 영역</h2>
        </footer>
    </div>
</body>
cs

 

  • pet_box.html 응용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>애완동물</title>
    <style>
        body{
            font-family: "맑은 고딕", "고딕", "굴림";  /*1,2,3순위 (글꼴 없을 경우 대비)*/
        }
        #wrapper{
            width: 96%;
            margin: 0 auto;
        }
        header{
            margin-left: auto;  /*가운데*/
            margin-right: auto;
            background-color: rgb(121, 121, 231);
            padding: 10px;
            overflow: hidden;
        }
        header h1{
            text-align: center;
            width: 40%;
            float: left;
            color: #fff;
        }
        nav{
            text-align: center;
            width: 60%;
            float: right;
        }
        nav ul{
            list-style: none;
        }
        nav ul li {
            float: left;
            margin: 15px;
        }
        nav ul li a{
            text-decoration: none;
            color: white;
        }
        section{
            border: 5px solid #333;
            overflow: hidden;
        }
        article{
            width: 29.17%;
            height: auto;
            float: left;
            margin-right: 1.5625%;
            margin-top: 20px;
            margin-bottom: 20px;
            padding: 0.5%;
            border: 1px dotted #333;
            border-radius: 10px;
        }
        article:first-child{ 
        /*= section>article:firstchild = 자식인 아티클 중 첫번째*/
            margin-left: 2.083%;
        }
        article h2{
            font-size: 1.2em;
            background-image: url(../images/19s.png);
            background-repeat: no-repeat;
            padding-left: 30px;
            background-position: left center;
        }
        article dt{
            font-weight: bold;
            color: purple;
        }
        aside{
            clear: both;
            width: 93.75%;
            margin: 10px auto;
            background-color: bisque;
            padding: 10px;
        }
        aside h2 {
            font-size: 1.2em;
        }
        footer{
            clear: both;
            margin-left: auto;
            margin-right: auto;        
            padding: 10px;
            background-color: #333;
            color: white;
            text-align: center;
        }
    </style>
</head>
<body>
    <div id="wrapper">
        <header>
            <h1>애완견 종류</h1>
            <nav> <!-- 메뉴 -->
                <ul>
                    <li><a href="#">애완견 종류</a></li>
                    <li><a href="#">입양하기</a></li>
                    <li><a href="#">건강 돌보기</a></li>
                    <li><a href="#">더불어 살기</a></li>
                </ul>
            </nav>
        </header>
        <section>  <!-- 콘텐츠 내용 -->
            <article id="pet1"> <!-- 섹션 상세 설명 -->
                <h2>활달한 강아지</h2>
                <dl> <!-- 설명 목록 -->
                    <dt>요크셔테리어</dt> <!-- description title -->
                    <dd>생기있고 활달한 성질을 가지고 있으며 자신보다 몸집이 큰 개나 집에 들어온 침입자를 겁내는 일이 없어 좋은 번견이고 우리나라 최고의의 가정견으로 자리 잡고 있다.</dd> <!-- d data -->
                    <dt>말티즈</dt>
                    <dd>애정이 많고, 충실하며 활발한 성격을 소유하고있다. 이 종은 1급 가정견으로 요크셔테리어와 함께 우리나라 최고의 가정견으로 자리잡고 있다.</dd> <!-- d data -->
                    <dt>포메라니안</dt>
                    <dd>활기차고 명랑한 개로 유명하고, 걷는 모습이 우아하다.충실하고 우호적인 성격이 가장 먼저 거론된다.</dd> <!-- d data -->
                    <dt>골드 리트리버</dt>
                    <dd>이 견종은 충성심이 강하고 성격이 활달하여 어린아이나 여성이 상대하기에 적합한 견종이다.참을성 또한 강하여 현재는실내에서도 많이 길러지고 있다.</dd>
                </dl>
            </article>
            <article id="pet2">
                <h2>온순한 강아지</h2>
                <dl>
                    <dt>쉬즈</dt>
                    <dd> 얼굴에서 풍기는 모습처럼 온순, 쉽게 친숙해지고 우호적이며,어린아이나 여성들이 기르기에 적합한 견종이다.</dd> 
                    <dt>퍼그</dt>
                    <dd>매우 사려가 깊고 사랑스러운 견종이며 그다지 손질이 필요하지 않고 식사량에 비해 많은 운동량이 필요하지 않다.</dd>
                    <dt>래브라도 리트리버</dt>
                    <dd>침착하고 영리하여 어린이들을 안심하고 맡길 수 있다. 사람을 즐겁게 해주려는 성질이 있다 공을 가지고 노는 것을 가장  좋아한다. 현재 맹인 안내견과 마약견으로 사용중이다. 온순한 강아지를 좋아하는 분에게는 적합한 견종이다.</dd>
                    </dl>
            </article>
            <article id="pet3">
                <h2>복종적인 강아지</h2>
                <dl>
                    <dt>미니어쳐핀셔</dt>
                    <dd>경계심이 강하고 영리하며 작은 몸집에 비해 매우 용감하다. 주인에게 매우 복종적이며 작은 몸집에 보디가드 역할을 충실히 수행한다.</dd>
                    <dt>푸들 </dt>
                    <dd>사납진 않으나, 상당히 복종적이며, 지능지수가 애완견종 중 가장 뛰어나다.</dd>
                    <dt>폭스테리어</dt>
                    <dd>가정에서 키우기에 적합한 품종이다.  보호본능이 강하고 정이 많다. 하지만 사냥을 하던 본능이 조금은 남아있어 사나운 면이 있다. 이종을 좋은 품종으로 기르기 위해서는 어릴 때부터 엄한 훈련이 필요하기도 하다.</dd>
                </dl>
            </article>
        </section>
        <aside> <!-- 사이드 (보조 내용) -->
            <h2>건강한 강아지는</h2>
            <ul>
                <li>코가 젖어있고 눈꼽이 없어야 합니다.</li>
                <li>털에 윤기가 있는 것을 골라야 합니다.</li>
                <li>입에서 고약한 냄새가 나면 병이 있다는 증거입니다.</li>
                <li>가장 활발하게 움직이는 녀석을 고르는게 좋습니다.</li>
                <li>강아지들 중에서 적당한 체구를 유지한 강아지가 좋습니다.</li>
            </ul>    
        </aside>
        <footer>
            <p>Copyright 2022 pet.com</p>
        </footer>
    </div>
</body>
cs

 

 

 

  • 미디어 쿼리

화면 크기마다 각각 다르게 CSS를 적용하여 반응형 웹 제어

 

 

  •  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>미디어 쿼리 테스트</title>
    <style>
        body{
            background: url(images/bg0.jpg) no-repeat fixed;
            background-size: cover;
        }
        @media screen and (max-width:1024px) {  /*너비 ~1024px이면 배경 표시*/
            body{
                background: url(images/bg0.jpg) no-repeat fixed;
                background-size: cover;
            }
        }
        @media screen and (max-width:768px) { /*너비 ~768px*/
            body{
                background: url(images/bg2.jpg) no-repeat fixed;
                background-size: cover;
            }
        }
        @media screen and (max-width:320px) {  /*너비 ~320px*/
            body{
                background: url(images/bg3.jpg) no-repeat fixed;
                background-size: cover;
            }
        }
    </style>
</head>
<body>
    <!-- pc, 태블릿, 모바일에 따라 적용할 CSS를 다르게 정의  -->
    <!-- 조건 어떻게 체크할 것인지가 중요 -->
</body>
cs

 

 

  •  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>반응형 웹 샘플</title>
    <style>
        *{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        header{
            width: 100%;
            background: #000;
        }
        nav ul{
            height: 50px;
            margin: 0;
            list-style: none;
            background-color: #000;
            color: #fff;
        }
        nav li {
            float: left;
            margin: 5px 15px;
            padding: 10px;
            font-size: 0.8em;
        }
        #container, nav {
            width: 310px;
            margin-bottom: 20px;
        }
        #intro {
            text-align: center;
            margin-bottom: 20px;
        }
        #intro img {
            max-width: 100%;
        }
        #desc {
            width: 100%;
            padding: 10px;
        }
        footer{
            width: 100%;
            padding: 20px;
            height: 60px;
            color: #fff;
            background-color: #37001c;
        }
        footer p {
            text-align: center;
        }
        @media screen and (min-width:768px) {  /*all: 점자, 프린터 등 기타 장치 포함*/
        /*768px~*/
            #container, nav {
                width: 750px;
                margin: 0 auto;
            }
            #intro {
                width: 100%;
            }
            #intro img{
                float: left; /*부모 영역 높이 0으로 만들어 밖으로 나감*/
                width: 200px;
                margin: 20px;
            }
            #desc{
                clear: both;
                width: 100%;
                padding: 0;
                margin: 10px auto;
            }
            footer{
                height: 150px;
                background: url(images/footer.jpg) no-repeat center;
                background-size: cover;
            }
            footer p {
                line-height: 150px;
            }
        }
        @media screen and (min-width:1024px) {  /*1025px~*/
            #container, nav {
                width: 1000px;
                margin: 0 auto;
            }
            #intro img {
                float: left;
            }
            #desc{
                display: inline-block;
                width: 250px;
                height: 200px;
                padding: 5px;
                border: 1px solid #ccc;
            }
            footer{
                clear: both;
                height: 200px;
                background: url(images/footer.jpg) no-repeat center;
                background-size: cover;
            }
            footer p {
                line-height: 200px;
            }
        }
    </style>
</head>
<body>
    <header>
        <nav>
            <ul>
                <li>메뉴1</li>
                <li>메뉴2</li>
                <li>메뉴3</li>
            </ul>
        </nav>
    </header>
    <div id="container">
        <section id="intro">
            <img src="images/pic1.jpg" alt="">
            <img src="images/pic2.jpg" alt="">
            <img src="images/pic3.jpg" alt="">
        </section>
        <section id="desc" class="text">
            <p>있는 이것을 능히 보이는 투명하되 이상의 낙원을 칼이다. 위하여 같이 힘차게 오직 듣는다. 뭇 창공에 천지는 말이다. 같이, 있는 되는 열매를 말이다. 있는 이것을 능히 보이는 투명하되 이상의 낙원을 칼이다.</p>
        </section>
        <footer>
            <p>뭇 창공에 천지는 말이다. 같이, 있는 되는 열매를 말이다.</p>
        </footer>
    </div>
</body>
cs

 

 

 

 

  • flex box (cf. 레이아웃 방법 : float, display, position, ..)

=> 유동적 레이아웃 구성

 

참고: https://sunshine7e7.tistory.com/3

https://studiomeal.com/archives/197

 

 

  • flex 영역

flex-direction : 플렉스 요소(flex item)가 위치할 방향 설정

   1. row: 텍스트의 방향과 동일하게 정렬 (=> 행 방향, 세로 줄무늬)

   2. row-reverse: 텍스트의 반대 방향으로 정렬  

   3. column: 위에서 아래로 정렬

   4. column-reverse: 아래에서 위로 정렬한다

 

flex-wrap 플렉스 라인에 여유 공간이 없을 때, 플렉스 요소 줄바꿈

   1. nowrap: 모든 요소들을 한 줄에 정렬

   2. wrap: 여러 줄에 걸쳐 정렬 => 기본값보다 너비 넓어지면 아래 영역으로 확장해 항목 배치 => 기본값 필수

   3. wrap-reverse: 여러 줄에 반대로 정렬

 

flex-flow : flex-direction, flex-wrap 2가지 속성을 한번에 설정

 

flex-grow : 다른 플렉스 요소(flex item)들의 공간 흡수하여 성장(확장) (default: 0)

flex-shrink : 자신을 희생하여 공간를 줄이며 그 너비 고정 가능(수축) (default: 1 => 기본적으로 수축)

flex-basis : 기본값

=> grow, shrink 값 0 -> 확장, 축소 없으므로 기본값 필수

=> grow/shrink 값 2 -> 2배 증/감

 

flex : flex-grow, flex-shrink, flex basis 3가지 속성을 한번에 설정 (grow 생략 불가)

 

order : 우선순위 부여

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>flex 속성</title>
    <style>
        .flexbox {
            background: #ccc;
            height: 200px;
            display: -ms-flexbox;
            display: -webkit-flex;
            display: -moz-box;
            display: flex; /*flex 정렬할 항목의 부모 영역에 적용*/
        }
        .flexbox>div {
            background: green;
            margin: 10px;
        }
        .box1{
            /* order: 2; */
            flex: 1 1 0;
        }       
        .box2{
            /* order: 3; */
            flex: 2 2 0;
        }        
        .box3{
            /* order: 1; */
            flex: 1 1 0;
        }
    </style>
</head>
<body>
    <div class="flexbox">
        <div class="box1">
            <h1>1</h1>
        </div>
        <div class="box2">
            <h1>2</h1>
        </div>
        <div class="box3">
            <h1>3</h1>
        </div>
    </div>
</body>
 
cs

 

 

 

  • flex 항목 배치

justify-content : 플렉스 요소의 수평 정렬 방식 설정

    1. flex-start : (기본 설정) 플렉스 컨테이너의 앞쪽에서부터 배치

    2. flex-end : 플렉스 컨테이너의 뒤쪽에서부터 배치

    3. center : 플렉스 컨테이너의 가운데에서부터 배치

    4. space-between : 요소들 사이에만 여유 공간을 두고 배치

    5. space-around : 앞, 뒤, 그리고 요소들 사이에도 모두 여유 공간을 두고 배치

 

align-items : 플렉스 요소의 수직 정렬 방식 설정

   1. stretch : (기본 설정) 플렉스 요소의 높이가 플렉스 컨테이너의 높이와 같게 변경된 뒤 연이어 배치

   2. flex-start : 플렉스 컨테이너의 위쪽에 배치

   3. flex-end : 플렉스 컨테이너의 아래쪽에 배치

   4. center : 플렉스 컨테이너의 가운데에 배치

   5. baseline : 플렉스 컨테이너의 기준선(baseline)에 배치

 

align-content : 플렉스 요소의 여러 줄 사이의 간격을 조정 => 두 줄 이상인 플렉스 박스에서만 효과 O

  1. flex-start: 여러 줄들을 컨테이너의 꼭대기에 정렬

  2. flex-end: 여러 줄들을 컨테이너의 바닥에 정렬

  3. center: 여러 줄들을 세로선상에 가운데 정렬

  4. space-between: 여러 줄들 사이에 동일한 간격

  5. space-around: 여러 줄들 주위에 동일한 간격

  6. stretch: (기본값) 여러 줄들을 컨테이너에 맞도록 늘림

 

 

※ align-items & align-content 의 차이

align-items : 수직축 라인을 기준으로 아이템들이 정렬됨 (.box div 내부 기준)
align-content : 수직축 라인을 기준으로 라인 자체가 정렬됨 (.box 내부 기준)

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>flex 배치 방법</title>
    <style>
        .box{
            width: 200px;
            height: 500px;
            margin: 0 auto 20px;
            display: flex;
            flex-wrap: wrap;
            border: 2px solid;
        }
        .box1{
            /* justify-content: flex-start;  한줄용*/
            align-content: flex-start; /*여러 줄로 내려올 때*/
        }
        .box2{
            /* justify-content: flex-end; */
            align-content: flex-end;
        }
        .box3{
            /* justify-content: center; */
            align-content: center;
        }
        .box4{
            /* justify-content: space-between; */
            align-content: space-between;
        }
        .box5{
            /* justify-content: space-around; */
            align-content: space-around;
        }
        h1, p{
            text-align: center;
        }
        .box div {
            width: 200px;
            border: 1px solid;
            background-color: rgb(196, 247, 238);
            margin: 1px;
        }
    </style>
</head>
<body>
    <h1>주축을 기준으로 배치 (flex-start)</h1>
    <div class="box box1">
        <div><p>1</p></div>
        <div><p>2</p></div>
        <div><p>3</p></div>
    </div>
    <h1>주축의 끝점으로 배치 (flex-end)</h1>
    <div class="box box2">
        <div><p>1</p></div>
        <div><p>2</p></div>
        <div><p>3</p></div>
    </div>
    <h1>주축의 중앙으로 배치 (center)</h1>
    <div class="box box3">
        <div><p>1</p></div>
        <div><p>2</p></div>
        <div><p>3</p></div>
    </div>
    <h1>주축의 시작점에서 같은 간격 배치 (space-between)</h1>
    <div class="box box4">
        <div><p>1</p></div>
        <div><p>2</p></div>
        <div><p>3</p></div>
    </div>
    <h1>같은 간격 배치 (space-around)</h1>
    <div class="box box5">
        <div><p>1</p></div>
        <div><p>2</p></div>
        <div><p>3</p></div>
    </div>
</body>
cs