일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 코딩부트캠프후기
- MomentumParameters
- 개발자스터디
- 항해플러스
- 항해
- 파이썬 클래스
- fatal:not a git repository
- print("""
- 주니어개발자멘토링
- 99일지
- print sep
- 10430번
- 파이썬 int()
- Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
- cp949
- 파이썬 map 함수
- 백준
- 파이썬 sep
- EnvCommandError
- 파이썬 |
- 개발자사이드프로젝트
- not a git repository
- 파이썬
- 항해99
- Til
- 99클럽 #99일지 #코딩테스트 #개발자스터디 #항해 #til
- vscode cp949
- 코딩테스트
- 99클럽
- 주니어개발자역량강화
- Today
- Total
선발대
[스파르타] 웹 프로젝트2: 인스타그램 모바일 화면 만들기 본문
소개
- CSS에서 width, height 지정할 때는 %, vw 등 상대적 수치만을 사용할 것. (px 사용금지)
- html에서 id/class 지정할 때, 동일한 스타일을 여러 요소에 사용할 경우에만 class 사용. 나머지는 id로.
- 예시 영상처럼 화면 크기를 조정해도 요소들의 상대적인 위치가 유지되도록 최대 가로 길이를 제한할 것.
- 만약 최대 가로 길이를 넘어설 경우, 좌우에 공백이 생기도록 할 것.
- 화면의 스크롤을 움직여도, 상단의 헤더와 하단의 푸터는 위치가 절대 달라지지 않도록 할 것.
- (심화옵션) 스토리 테두리 2가지 구현: 회색 / 주황색~보라색 그라데이션
- 요소들의 상대적인 위치만 동일하다면, 요소의 %, vw 등 상대적 크기는 자유롭게 정해도 괜찮음.
- 자신이 원하는 사진을 자유롭게 넣도록 함.
내가 작성한 코드, 모범답안
<!--내가 작성한 코드: HTML-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>Title</title>
<link rel="stylesheet" href="css/insta.css"/>
</head>
<body>
<div class="container">
<div class="header">
<img class="icon" src="img/camera@3x.png" alt="camera-icon">
<img class="logo" src="img/insta-logo.png" alt="logo-icon">
<img class="icon" src="img/dm@3x.png" alt="dm-icon">
</div>
<hr>
<div class="storys">
<div class="story">
<img class="story-img" src="img/xmas.jpg" alt="story-img">
<h5>내 스토리</h5>
</div>
<div class="story">
<img class="story-img" src="img/xmas.jpg" alt="story-img">
<h5>내 스토리</h5>
</div>
<div class="story">
<img class="story-img" src="img/xmas.jpg" alt="story-img">
<h5>내 스토리</h5>
</div>
<div class="story">
<img class="story-img" src="img/xmas.jpg" alt="story-img">
<h5>내 스토리</h5>
</div>
<div class="story">
<img class="story-img" src="img/xmas.jpg" alt="story-img">
<h5>내 스토리</h5>
</div>
</div>
<hr>
<div class="user-name">
<div class="user1">
<img id="profile-img1" src="img/xmas.jpg" alt="profile-icon">
<h4>이용자5</h4>
</div>
<div class="user2">
<img id="more-icon" src="img/more@3x.png" alt="more-icon">
</div>
</div>
<img class="photo1" src="img/xmas.jpg" alt="main-photo">
<div class="functions">
<div class="function1">
<img class="icon" src="img/like@3x.png" alt="like-icon">
<img class="icon" src="img/comment@3x.png" alt="comment-icon">
<img class="icon" src="img/dm@3x.png" alt="dm-icon">
</div>
<div class="function2">
<img class="icon" src="img/favorite@3x.png" alt="save-icon">
</div>
</div>
<div class="likes">
<div class="like1">
<img id="profile-img2" src="img/xmas.jpg" alt="profile-icon">
<h4>이용자님 외 6,671명이 좋아합니다.</h4>
</div>
<h4>이용자 안녕하세요</h4>
<h5>8시간 전</h5>
</div>
<hr>
<div class="footer">
<img class="icon" src="img/home@3x.png" alt="home-icon">
<img class="icon" src="img/search@3x.png" alt="search-icon">
<img class="icon" src="img/trending@3x.png" alt="trend-icon">
<img class="icon" src="img/like@3x.png" alt="like-icon">
<img class="icon" src="img/home@3x.png" alt="home-icon">
</div>
</div>
</body>
</html>
/* 내가 작성한 코드: CSS */
.container {
width: 600px;
height: 940px;
border: 1px solid darkgray;
font-size: 0px;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 20px 0px 20px;
}
.icon {
width: 30px;
height: 30px;
}
.functions {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20px 20px 5px 20px;
}
.function1 {
display: flex;
justify-content: space-around;
flex-basis: 150px;
}
.logo {
width: 120px;
height: 50px
}
.footer {
display: flex;
align-items: center;
justify-content: space-around;
padding-top: 10px;
}
.storys {
width: 600px;
height: 130px;
background-color: #f3f3f3;
font-size: 15px;
display: flex;
justify-content: space-evenly;
align-items: center;
padding-top: 20px;
}
.story {
display: inline-flex;
flex-direction: column;
align-items: center;
font-size: 16px;
}
.story-img {
width: 80px;
height: 80px;
border-radius: 50%;
}
.user-name {
height: 70px;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 16px;
padding: 0 20px;
}
.user1 {
display: flex;
flex-basis: 110px;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.likes {
padding: 0px 20px 0px 20px;
font-size: 14px;
}
.like1 {
display: flex;
width: 270px;
align-items: center;
justify-content: space-between;
}
.photo1 {
width: 600px;
height: 400px;
}
#more-icon {
width: 40px;
height: 10px;
}
#profile-img1 {
width: 40px;
height: 40px;
border-radius: 50%;
}
#profile-img2 {
width: 35px;
height: 35px;
border-radius: 50%;
}
<!--모범답안-->
<!DOCTYPE html>
<html lang="en">
<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">
<link rel="stylesheet" href="style.css">
<title>Instagram</title>
</head>
<body>
<div id="main">
<div id="header">
<img class="header-icon" src="img/camera@3x.png" />
<img id="logo" src="img/insta-logo.png" />
<img class="header-icon" src="img/dm@3x.png" />
</div>
<div id="container">
<div id="story-container">
<div class="story-wrapper">
<div class="story-off">
<img src="img/xmas.jpg"/>
</div>
<p>내 스토리</p>
</div>
<div class="story-wrapper">
<div class="story-on">
<img src="img/xmas.jpg"/>
</div>
<p>내 스토리</p>
</div>
<div class="story-wrapper">
<div class="story-on">
<img src="img/xmas.jpg"/>
</div>
<p>내 스토리</p>
</div>
<div class="story-wrapper">
<div class="story-off">
<img src="img/xmas.jpg"/>
</div>
<p>내 스토리</p>
</div>
<div class="story-wrapper">
<div class="story-off">
<img src="img/xmas.jpg"/>
</div>
<p>내 스토리</p>
</div>
<div class="story-wrapper">
<div class="story-off">
<img src="img/xmas.jpg"/>
</div>
<p>내 스토리</p>
</div>
</div>
<div id="post-container">
<div class="post-wrapper">
<div class="post-header">
<div class="left-wrapper">
<img src="img/xmas.jpg"/>
<p>이용자5</p>
</div>
<div class="right-wrapper">
<img src="img/more@3x.png">
</div>
</div>
<div class="post-body">
<img src="img/xmas.jpg">
<div class="post-icons-wrapper">
<div class="left-wrapper">
<!-- 아이콘 크기가 달라서 부득이 하게 이렇게 만들었으나, 클래스 없이 img로 처리하는게 맞습니다! -->
<img class="post-icon" src="img/like@3x.png">
<img class="post-icon-2" src="img/comment@3x.png">
<img class="post-icon" src="img/dm@3x.png">
</div>
<div class="right-wrapper">
<img src="img/favorite@3x.png">
</div>
</div>
</div>
<div class="post-footer">
<div class="post-like-wrapper">
<img src="img/xmas.jpg">
<p><strong>이용자</strong>님 <strong>외 6,671명</strong>이 좋아합니다</p>
</div>
<div class="post-content-wrapper">
<p class="post-author">이용자</p>
<p class="post-content">안녕하세요</p>
</div>
<p class="post-time">
8시간 전
</p>
</div>
</div>
<div class="post-wrapper">
<div class="post-header">
<div class="left-wrapper">
<img src="img/xmas.jpg"/>
<p>이용자5</p>
</div>
<div class="right-wrapper">
<img src="img/more@3x.png">
</div>
</div>
<div class="post-body">
<img src="img/xmas.jpg">
<div class="post-icons-wrapper">
<div class="left-wrapper">
<!-- 아이콘 크기가 달라서 부득이 하게 이렇게 만들었으나, 클래스 없이 img로 처리하는게 맞습니다! -->
<img class="post-icon" src="img/like@3x.png">
<img class="post-icon-2" src="img/comment@3x.png">
<img class="post-icon" src="img/dm@3x.png">
</div>
<div class="right-wrapper">
<img src="img/favorite@3x.png">
</div>
</div>
</div>
<div class="post-footer">
<div class="post-like-wrapper">
<img src="img/xmas.jpg">
<p><strong>이용자</strong>님 <strong>외 6,671명</strong>이 좋아합니다</p>
</div>
<div class="post-content-wrapper">
<p class="post-author">이용자</p>
<p class="post-content">안녕하세요</p>
</div>
<p class="post-time">
8시간 전
</p>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="icon-wrapper">
<img src="img/home@3x.png">
<img src="img/search@3x.png">
<img src="img/trending@3x.png">
<img src="img/like@3x.png">
<img src="img/home@3x.png">
</div>
</div>
</div>
</body>
</html>
/* 모범답안 */
body {
max-width: 720px;
margin: 0 auto;
}
/* 헤더 */
#header {
display: flex;
justify-content: space-between;
background-color: white;
align-items: center;
width: 100%;
position: fixed;
max-width: 720px;
border-bottom: 1px solid lightgray;
}
#header .header-icon {
margin: 3% 5%;
width: 6%;
}
#header #logo {
width: 27%;
}
/* 컨테이너 */
#container {
padding-top: 12%;
padding-bottom: 12%;
}
/* 스토리 */
#story-container {
padding-left: 1%;
background-color: #f6f6f6;
display: flex;
justify-content: flex-start;
align-items: center;
overflow: hidden;
border-bottom: 1px solid lightgray;
}
.story-wrapper {
width: auto;
margin: 2.5% 3.2%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.story-wrapper .story-on {
width: 13vw;
max-width: 80px;
max-height: 80px;
height: 13vw;
border: 2px solid transparent;
border-radius: 50%;
background-image: linear-gradient(#f6f6f6, #f6f6f6),
linear-gradient(to right, #ff7700, #ff3636aa, #ff00c3);
background-origin: border-box;
background-clip: content-box, border-box;
}
.story-wrapper .story-off {
width: 13vw;
max-width: 80px;
max-height: 80px;
height: 13vw;
border: 2px solid transparent;
border-radius: 50%;
background-image: linear-gradient(#f6f6f6, #f6f6f6),
linear-gradient(#c4c4c4, #c4c4c4);
background-origin: border-box;
background-clip: content-box, border-box;
}
.story-wrapper img {
width: 100%;
height: 100%;
border-radius: 50%;
}
.story-wrapper p {
margin-top: 10%;
margin-bottom: 0%;
font-size: 12px;
}
/* 포스트 - 공통 */
.left-wrapper {
margin-left: 3%;
display: flex;
align-items: center;
width: 100%;
}
.right-wrapper {
width: 100%;
display: flex;
justify-content: right;
margin-right: 3%;
}
/* 포스트 - 헤더 */
.post-header {
margin: 1% 0;
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
}
.post-header .left-wrapper img {
width: 15%;
height: 15%;
border-radius: 50%;
border: 1px solid lightgray;
margin: 0 2%;
}
.post-header .left-wrapper p {
margin-left: 2%;
font-weight: bold;
font-size: 14px;
}
/* 포스트 - 바디 */
.post-body img {
width: 100%;
}
.post-body .post-icons-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
margin-top: 1%;
}
/* 아이콘 크기가 달라서 부득이 하게 이렇게 만들었으나, 그냥 img 로 처리하는게 맞습니다! */
.post-body .post-icons-wrapper .left-wrapper .post-icon {
margin: 2% 4%;
width: 14%;
}
.post-body .post-icons-wrapper .left-wrapper .post-icon-2 {
margin: 2% 4%;
width: 13%;
}
.post-body .post-icons-wrapper .right-wrapper img {
margin: 2% 4%;
width: 11%;
}
/* 포스트 - 푸터 */
.post-footer {
padding-left: 2%;
border-bottom: 1px solid lightgray;
}
.post-footer .post-like-wrapper {
display: flex;
align-items: center;
margin-left: 1%;
margin-top: 1%;
margin-bottom: 1%;
}
.post-footer .post-like-wrapper img {
width: 6%;
height: 6%;
border-radius: 50%;
border: 1px solid lightgray;
margin: 0 1%;
}
.post-footer .post-like-wrapper p {
margin-bottom: 2%;
margin-top: 2%;
font-size: 14px;
}
.post-footer .post-content-wrapper {
display: flex;
}
.post-footer .post-content-wrapper .post-author {
margin: 0% 2% 0% 2%;
font-weight: bold;
font-size: 14px;
}
.post-footer .post-content-wrapper .post-content {
margin: 0%;
font-size: 14px;
}
.post-footer .post-time {
color: gray;
font-size: 10px;
margin-left: 2%;
margin-top: 5%;
}
/* 푸터 */
#footer {
position: fixed;
bottom: 0;
width: 100%;
max-width: 720px;
border-top: 1px solid lightgray;
background-color: white;
}
#footer #icon-wrapper {
margin: 4% 6%;
display: flex;
justify-content: space-between;
align-items: center;
}
#footer #icon-wrapper img {
width: 6%;
}
후기
- 복습용 파일로 보면 더 간단한 코드를 볼 수 있다. (여기에는 포함 안 시켰다.)
- 제일 먼저 구현해야 할 것은 header, footer임. position: fixed; width: 100% 로 설정.
- header는 top: 0; footer는 bottom: 0;으로 설정.
- 아이템은 wrapper로 감싸는 형태가 좋음.
- 한 줄에서 margin으로 여백을 두는 것은 굉장히 비효율적인 방법임.
- CSS는 클론코딩으로 직접 수치를 손으로 쳐보고 체감하는 방법이 좋다.
- overflow: hidden; 가로 길이에서 넘치는 부분은 옆으로 사라진다.
- max-width 주고 margin: 0 auto; 하면 가운데로 정렬된다.
- CSS 작성할 때 부모 div나 기능을 알려주는 div를 함께 앞에 써주면 팀 프로젝트 할 때 좋다.
이번주 월요일부터 이렇게 미니프로젝트를 진행했는데 매일 갈수록 새로운 것을 배우고 있다. 그래서 한 번 놓치면 다음 과제 진행이 안되므로 매일 복습을 해야된다. 어제 카카오톡 프로필 화면을 만들었고, 어제 저녁부터 오늘 12시까지 CSS 벼락치기 공부를 했다. 12시부터 부랴부랴 만들어서 겨우 비슷한 화면은 만들었다. 그렇지만 주어진 조건은 많이 충족하지 못했다. 월요일 ~ 목요일까지는 제출이 16시까지였는데, 오늘은 14시까지라서 시간이 더 부족했다. (오늘은 크리스마스 이브니까)
어쨌거나 이제 주어진 화면을 보고 맨 위의 완성작처럼 만들 수 있게 되었다. 그렇지만 위에 언급했듯이 이번 문제의 조건은 px이 아닌 상대적인 수치를 사용해야했고, 헤더와 푸터도 고정시켜야 했다. class 와 id도 일관적으로 사용해야겠다. 화면 구현은 할 수 있지만 아직 px이 아닌, 상대적 수치에 대해서도 잘 몰라서 공부가 더 필요하다. vw, vh도 처음 듣는다. overflow: hidden; 기능도 찾아봐야겠다. 안 그래도 티스토리 블로그 html, css를 조금씩 건드려보고 있는데 마침 overflow: hidden; 이 내가 찾던 기능 같다. 인스타 스토리들이 옆으로 이어지거나, 인스타 게시글이 위아래로 움직이는 것도 어떻게 구현하는지 다시 공부해야겠다.
- 해결: css파일에서 body를 .body로 표현해서 적용되지 않았었다.
- 아예 body에서 max-width: 720px; margin: 0 auto; 으로 최대 크기랑 화면에서의 위치 설정함.
- 헤더와 푸터는 position: fixed;로 아예 고정시켜버리기
- hr을 썼는데 그러면 font-size: 0px;로 해야하므로, border-bottom: 1px solid lightgray; 이용
- background-image: linear-gradient(...)
- background-origin: border-box;
- background-clip: content-box, border-box;
- 한 줄에 이미지가 여러 개 있으면, left / right-wrapper로 css 각각 적용함.
- font-weight: bold; 굵은 글씨체
HTML 요소는 박스로 이루어져 있고 크게 4개의 영역으로 구분된다.
- 바깥 여백 영역(Margin Area)
- 테두리 영역(Border Area)
- 안쪽 여백 영역(Padding Area)
- 내용 영역(Content Area)
background-origin: [시작점] 배경 이미지를 위의 4가지 영역 중에 어느 영역부터 채워나갈지 정한다. 배경 이미지를 반복시키면 시작점 바깥의 영역도 채운다.
- 문법: background-origin: (원하는 값 입력)
- border-box: 테두리 영역 왼쪽 위부터
- padding-box: 안쪽 여백 영역 왼쪽 위부터
- content-box: 내용 영역 왼쪽 위부터
- initial: 기본값으로 설정
- inherit: 부모 요소의 속성값을 상속 받음.
background-clip: [채울 영역] 요소의 배경이 테두리 안쪽여백, 콘텐츠 상자 중 어디까지 차지할지 지정함.
- 문법: background-clip: (원하는 값 입력)
- border-box: 배경이 테두리 바깥 경계까지 차지함. (Z축 순서상 테두리 아래에 위치함)
- padding-box: 안쪽 여백 바깥 경계까지 차지함. (테두리 밑에는 배경 그리지 않음)
- content-box: 콘텐츠 상자에 맞춰서 그림.
- text: 전경 텍스트 위에만 그림.
참조
'스파르타코딩클럽 > 활동 내용' 카테고리의 다른 글
[스파르타] 99클럽 코테스터디 1일차 TIL / 백준 15700 (0) | 2024.05.03 |
---|---|
[스파르타] 항해 플러스 후기 (0) | 2023.08.22 |
[스파르타] 웹프로젝트1: 카카오톡 프로필 화면 만들기 (0) | 2021.12.23 |
[스파르타] 파이썬 프로젝트3: 턴제 RPG 게임 만들기 (심화) (0) | 2021.12.22 |
[스파르타] 파이썬 프로젝트3: class 연습문제 (기초) (0) | 2021.12.21 |