본문 바로가기
오즈코딩스쿨/[HTML,CSS]

[HTML,CSS] 5일차 ❻

by Sowon Kim 2025. 8. 27.

Chapter6.
CSS 중급 속성 다루기


1️⃣

변형과 전환

33.html


 
 
 
 

더보기
<!DOCTYPE html>
<html lang="ko">
<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>
    .parent{
      display: inline-block;
      margin: 0 0px;
    }
    .child{
      width: 100px;
      height: 100px;
      background-color: teal;
    }
    
    /* (1)번째 .부모의 > 자식을 변형한다 (X, Y)쪽으로
    .parent:nth-child(1) > .child{ transform: translate(30px, 50px); } 이동
    .parent:nth-child(2) > .child{ transform: scale(1.2, 0.8); } 크기조절
    .parent:nth-child(3) > .child{ transform: skew(45deg); } 기울기
    .parent:nth-child(4) > .child{ transform: rotate(45deg); } 회전
    */

      /* (4)번째 .부모의 > 자식에게 마우스를 올리면, */
    .parent:nth-child(4) > .child:hover{
      width: 100px;
      height: 200px;
      background-color: orange;
      /* 전환된다: 배경색이 2초동안 망설임없이 일정하게, */
      transition: background-color 2s 0s linear,
      height 2s 0s linear; /* 높이가 2초동안 일정하게 */
      
      /* transition-property: width; 무엇을
      transition-duration: 5s; 언제동안
      transition-delay: 2s; 언제부터
      transition-timing-function: linear; 어떤속도로 */
    }
  </style>
</head>
<body>
  <div class="parent">
    <div class="child"></div>
  </div>
  <div class="parent">
    <div class="child"></div>
  </div>
  <div class="parent">
    <div class="child"></div>
  </div>
  <div class="parent">
    <div class="child"></div>
  </div>
</body>
</html>

transform
= 순간이동 (훅 바뀜)

transition
= 이동 애니메이션 (서서히 바뀜)


2️⃣

애니메이션 효과

34.html


 
 

더보기
<!DOCTYPE html>
<html lang="ko">
<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>
    .eyes{
      width: 220px;
      margin: auto;
    }
    .eye{
      width: 100px;
      height: 100px;
      border: 5px solid black;
      border-radius: 55px;
      position: relative;
    }
      /* (1)=첫번째, (2)=두번째 */
      /* 왼쪽에 띄운다 */
    .eye:nth-child(1){ float: left ;} 
      /* 오른쪽에 띄운다 */
    .eye:nth-child(2){ float: right ;}

    .ball{
      width: 30px;
      height: 30px;
      background-color: black;
      border-radius: 15px;
      position: absolute;

      /* 초기 위치 (세로) */
      top: 35px; 
      /* 초기 위치 (가로) */
     left: 10px; 
      /*애니메이션 실행 설정*/
      /* 사용할 움직임 이름 (@keyframes 연결) */
      animation-name: moving;
      /* 실행 시간 */
      animation-duration: 2s;
      /* 지연 없음 */ 
      animation-delay: 0s;
      /* 일정한 속도 */
      animation-timing-function
      : linear; /* ease; ease-in; ease-out; cubic-bezier()
      : 일정한; ㅇㅇㅇ; ㅇㅇㅇ; ㅇㅇㅇ; ㅇㅇㅇ(); */
      /* 무한 반복 */
      animation-iteration-count
      : infinite; /* normal; reverse; alternate; alternate-reverse;
      : 무한; ㅇㅇㅇ; ㅇㅇㅇ; ㅇㅇㅇ; ㅇㅇㅇ(); */
      /* 왕복 */ 
      animation-direction: alternate; 
    }
      /* 마우스 올리면 멈춤 */
    .ball:hover{
      animation-play-state
      : paused; /* running;
      : 멈춤; 움직임; */
    }

/* 애니메이션이 끝난 뒤 상태 ( 참고 )
animation-fill-mode:
: none; forwards; backwards; both;
: ㅇㅇ; ㅇㅇ; ㅇㅇ; ㅇㅇ; */


      /* 움직임 정의 (좌 → 우) */
    @keyframes moving {
      /* 시작 위치 ( 초기 위치와 동일 ) */
      from{ left: 10px; } 
      /* 끝 위치 */
      to{ left: 60px; } 
    }
  </style>
</head>
<body>
  <div class="eyes">
    <div class="eye">
      <div class="ball"></div>
    </div>
    <div class="eye">
      <div class="ball"></div>
    </div>
  </div>
</body>
</html>

.ball의 top/left 
: 정지 상태의 초기 위치
@keyframes ( 네비게이션역할 )
: moving { from { 초기 위치에서 } to { 어디로 } }
          ↘︎ animation-name
animation-* ( 어떻게 )
: 시간, 속도, 횟수 등

즉, 위치keyframes에서 정의,
재생 방식animation에서 제어

 


3️⃣

상속과 공용키워드

35.html


마라톤 대회 참가 기록

  • 새해맞이 대전 마라톤 대회
  • 서울 국제 마라톤 대회
  • 대전 대청호 벚꽃길 마라톤 대회
  • 대전 3대하천 마라톤 대회

더보기
<!DOCTYPE html>
<html lang="ko">
<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>
    .list{

      /* 상속 되는 애 ( 주로 글자 관련 ) */
      color: brown;
      font-style: italic;
      font-weight: 900;

      /* 상속 안 되는 애 ( 주로 박스 관련 ) */
      border: 3px dashed green;
      padding: 0;

    }

    ul{
      border: inherit; /* 강제 상속 */
    }
    li:nth-child(3){
      color: unset; /* 상속받을 게 있으면 받고, 없으면 기본값 */
      font-style: initial; /* 브라우저 기본값으로 되돌림 */
      font-weight: initial;
    }
  </style>
</head>
<body>
  <h2>마라톤 대회 참가 기록</h2>
  <div class="list">
    <ul>
      <li>새해맞이 대전 마라톤 대회</li>
      <li>서울 국제 마라톤 대회</li>
      <li>대전 대청호 벚꽃길 마라톤 대회</li>
      <li>대전 3대하천 마라톤 대회</li>
    </ul>
  </div>
</body>
</html>

🔹 CSS 상속 개념

  • 상속되는 속성
    → 글자 관련 속성
    (color, font-size, font-style, line-height …)
  • 상속되지 않는 속성
    → 박스 관련 속성
    (margin, padding, border, width, height …)

🔹 공용 키워드

  • inherit : 부모의 값을 강제로 상속받음
  • initial : 브라우저 기본값으로 되돌림
  • unset : 상속 가능한 속성이면 상속, 아니면 기본값(initial)

✨ 핵심 정리

  1. 글자 관련 속성은 자동 상속, 박스 관련 속성은 상속되지 않는다.
  2. inherit → 무조건 부모 따라감
  3. initial → 기본값으로 초기화
  4. unset → 상황에 따라 상속 or 기본값 선택

4️⃣

반응형 웹과 뷰포트 단위

36.html


발견하는 즐거움 - 리처드 파인만


더보기
<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <!-- viewport: 컨텐츠 너비를 기기 화면 너비에 맞추고, 확대 배율을 1로 설정 -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>반응형 웹과 뷰포트</title>
  <style>
    p{
      margin: 0;
      /* 글자 크기를 뷰포트 단위로 설정 */
      font-size: 10vw; /* 화면 너비(width)의 10% */
      /* font-size: 10vh;   화면 높이(height)의 10% */
      /* font-size: 10vmin; 뷰포트 너비·높이 중 더 작은 값의 10% */
      /* font-size: 10vmax; 뷰포트 너비·높이 중 더 큰 값의 10% */
    }
  </style>
</head>
<body>
  <p>발견하는 즐거움 - 리처드 파인만</p>
</body>
</html>

🔹 viewport 메타태그

<meta name="viewport" content="width=device-width, initial-scale=1.0">
  • width=device-width
    → 화면 크기에 맞춰 컨텐츠 크기 설정
  • initial-scale=1.0
    → 처음 로드될 때 배율 100%

🔹 뷰포트 단위 (Responsive 단위)

  • vw (viewport width)
    → 뷰포트 가로(width)의 1%
    • 10vw = 화면 가로의 10%
  • vh (viewport height)
    → 뷰포트 세로(height)의 1%
    • 10vh = 화면 세로의 10%
  • vmin (viewport minimum)
    → 뷰포트 너비·높이 중 더 작은 값의 1%
    • 작은 쪽 기준이라서 긴 화면(세로형 모바일)에 유용
  • vmax (viewport maximum)
    → 뷰포트 너비·높이 중 더 큰 값의 1%
    • 큰 쪽 기준이라서 가로가 넓은 PC 화면에 유용

5️⃣

미디어 쿼리

37.html


 

더보기
<!DOCTYPE html>
<html lang="ko">
<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>
    div.box{
      width: 150px;
      height: 150px;
      background-color: teal;
    }
    /* 화면 크기가 800px 이상일 때 적용 */
    @media screen and (min-width: 800px){
      div.box{
        background-color: orange;
      }
    }
    /* 화면 크기가 1000px 이상일 때 적용 */
    @media screen and (min-width: 1000px){
      div.box{
        background-color: red;
      }
    }
  </style>
</head>
<body>
  <div class="box"></div>
</body>
</html>

🔹 media query란?

CSS에서 조건에 따라 다른 스타일을 적용하는 방법
주로 반응형 웹(화면 크기별 스타일 적용)에 사용

🔹 구문 구조

@media [미디어타입] and (조건) { /* 조건을 만족할 때 실행할 CSS */ }
  • 미디어타입
    → screen, print, all 등
  • 조건
    → (min-width: 800px)
    : 화면 너비가 800px 이상일 때

🔹 주요 조건

min-width
: ~px 이상일 때
max-width
: ~px 이하일 때
orientation: portrait
: 세로 방향일 때
orientation: landscape
: 가로 방향일 때

6️⃣

모듈화 디자인

none.html


📝 컴포넌트(Component) 개념 정리

1. 페이지 → 컴포넌트

  • 예전 웹 개발: 하나의 HTML 파일 = 하나의 페이지
  • 최근 웹 개발(React, Vue, Svelte 등):
    • 페이지 전체를 잘게 쪼갠 "컴포넌트" 단위로 개발
    • 페이지 만들기 = 컴포넌트 조립하기 라고 봐도 과언이 아님

2. 컴포넌트란?

  • 독립적이고 재사용 가능한 UI 모듈
  • 버튼, 카드, 네비게이션 바, 게시글 등 화면의 한 부분을 담당
  • 각 컴포넌트는 **자신의 구조(HTML), 스타일(CSS), 동작(JS)**을 가짐

3. 특징

  • 독립성 : 다른 곳에 영향을 주지 않고 동작
  • 재사용성 : 같은 UI를 여러 곳에서 불러와 사용 가능
  • 조립성 : 작은 컴포넌트 → 큰 컴포넌트 → 페이지로 합쳐짐

4. 예시 (React 스타일)

더보기
// 독립된 컴포넌트 정의
function Button({ label }) {
  return <button className="btn">{label}</button>;
}

// 컴포넌트 재사용
function App() {
  return (
    <div>
      <Button label="로그인" />
      <Button label="회원가입" />
    </div>
  );
}
👉 Button이라는 컴포넌트는 한 번 만들면,
로그인 버튼/회원가입 버튼 등 여러 곳에서 재사용 가능

7️⃣

실습 - 채팅방에 말풍선 추가하기

5회차 > chat.html


 

친구

2

  • 친구야 반가워
  • 우리 언제 밥이나 한번 먹자

 

더보기
<!DOCTYPE html>
<html lang="ko">
<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>
    /* 전체적인 세팅부터 */
    *{
      box-sizing: border-box;
    }
    html {
      height: 100%;
    }
    body{
      height: 100%;
      margin: 0;
    }
    .container{
      height: 100%;
      background-color: #74e4da;
    }

    /* 스크린 크기 조정 */
    .chat-screen{
      height: calc(100% - 120px);
    }

    /* 유저 정보 표시되는 부분 */
    .user{
      background-color: #ffffff;
      padding: 16px;
      height: 80px;
    }
    .user_column{
      float: left;
    }
    .user_pic{
      width: 50px;
      height: 50px;
      margin-right: 10px;
      border-radius: 10px;
      background-color: #74e4da;
    }
    .user_nick, .user_count{
      margin: 5px;
    }
    .user_count{
      font-size: 12px;
      color: gray;
    }

    /* 채팅 입력 창 */
    .chat-form{
      height: 120px;
      background-color: #FFFFFF;
    }
    .chat-form_field{
      height: 120px;
    }
    .chat-form_msg{
      width: calc(100% - 120px);
      height: 120px;
      border: none;
      resize: none;
      font-size: 24px;
      padding: 10px;
    }
    .chat-form_bt{
      float: right;
      width: 120px;
      height: 120px;
      border-radius: 10px;
      background-color: #74e4da;
      font-size: 18px;
    }
    .chat-form_msg:focus{
      outline: none;
    }
    .chat-form_bt:active{
      background-color: #42817c;
    }

    .chat-screen__texts{
      padding: 0;
      list-style: none; /* 리스트 앞 동그라미 도형이 사라짐 */
    }
    .chat-screen__texts > .text{
      background-color: #cdfffb;
      width: 280px;
      height: 50px;
      margin: 0 0 10px 0; /* 도형의 밖쪽 여백 */
      padding: 10px;
      border-radius: 8px;
      line-height: 30px; /* 높이 총 50px 중, 패딩 10px씩 위아래를 제외하면, 30px이 남음 */
      position: relative;
      left: 20px;
    }

    .chat-screen__texts > .text::after{
      content: "";                           /* 가상 요소 생성 */
      border-right: 16px solid #cdfffb;    /* 오른쪽으로 색 채운 삼각형 */
      border-bottom: 16px solid transparent; /* 아래쪽은 투명 처리 */
      position: absolute;
      top: 10px; /* 말풍선 상단에서 10px 아래 */
      left: -10px; /* 말풍선 왼쪽 밖으로 10px */
    }

    .chat-screen__texts > .text:hover{
      background-color: #6d8886;
      transition: background-color 1500ms 200ms ease-in;
    }
    .chat-screen__texts > .text:hover::after{
      border-right: 16px solid #6d8886;
      transition: border-right 1500ms 200ms ease-in;
    }

  </style>
</head>
<body>
  <div class="container">
    <main class="chat-screen">
      <section class="chat-screen_bar">
        <div class="user">
          <div class="user_column">
            <div class="user_pic"></div>
          </div>
          <div class="user_column">
            <p class="user_nick">친구</p>
            <p class="user_count">2</p>
          </div>
        </div>
      </section>
      <ul class="chat-screen__texts">
        <li class="text">친구야 반가워</li>
        <li class="text">우리 언제 밥이나 한번 먹자</li>
      </ul>
    </main>

    <form class="chat-form">
      <section class="chat-form_field">
        <textarea class="chat-form_msg"></textarea>
        <input type="submit" value="전송" class="chat-form_bt">
      </section>
    </form>
  </div>
</body>
</html>

1. ::after

  • 선택자 뒤에 붙어서 가상 요소를 추가
  • 원래 HTML에 없지만 CSS에서 의도적으로 만든 “추가 박스”
👉 말풍선 꼬리(삼각형)를 따로 div 넣지 않고 CSS로만 만든 것

2. border-trick (삼각형 만들기)

border에 색을 주면 사각형의 각 면이 생김
한쪽만 색을 주고 나머지는 transparent로 하면 삼각형 모양이 됨
border-right: 16px solid #cdfffb;  /* 오른쪽 변 색칠 */
border-bottom: 16px solid transparent; /* 나머지는 투명 */
➡️ 색이 있는 border 한쪽만 보이면서 “삼각형 꼬리”가 생김

3. 위치 조정

  • position: absolute;
    → 부모(.text) 기준으로 꼬리 위치 결정
  • top: 10px → 위에서 10px
  • left: -10px
    → 왼쪽으로 10px 삐져나오게 해서 말풍선에 붙음