FC) React & Redux로 시작하는 웹 프로그래밍 3주차 개발일지 - 2) 스타벅스 예제

Ogu·2022년 7월 18일
1

패캠 React&Redux

목록 보기
4/4
post-thumbnail

Chapter 10. 스타벅스 예제

1. 시작하기

🎈 프로젝트 시작, 스타일 초기화, 파비콘

프로젝트 시작

이미지, favicon.ico, favicon.png 파일 프로젝트에 가져온다.

파비콘

웹페이지를 나타내는 아이콘, 웹페이지의 로고를 설정한다.
favicon.ico 파일이 루트경로에 있으면 자동으로 아이콘으로 로딩된다.
favicon.ico파일의 화질이 낮아 favicon.png파일을 아이콘으로 쓰고 싶을 때는 아래와 같이 <link /> 를 이용한다.

<link rel="icon" href="./favicon.png">

스타일 초기화

reset.css cdn을 검색해 나오는 주소에서 html 을 복사해 head태그에 붙여넣는다.

🎈 오픈 그래프와 트위터 카드

오픈 그래프

웹페이지가 소셜 미디어로 공유될 때 우선적으로 활용되는 정보를 지정한다.
ex) kakao talk

ex) 슬랙

오픈 그래프는 <meta>를 사용한다.

오픈 그래프 속성들

<meta property="og:type" content="website" />
<meta property="og:site_name" content="Starbucks" />
<meta property="og:title" content="Starbucks Coffee Korea" />
<meta property="og:description" content="스타벅스는 세계에서 가장 큰 다국적 커피 전문점으로, 64개국에서 총 23,187개의 매점을 운영하고 있습니다." />
<meta property="og:image" content="./images/starbucks_seo.jpg" />
<meta property="og:url" content="https://starbucks.co.kr" />
  • og:type: 페이지의 유형(E.g, website, video.movie)
  • og:site_name: 속한 사이트의 이름
  • og:title: 페이지의 이름(제목)
  • og:description: 페이지의 간단한 설명
  • og:image: 페이지의 대표 이미지 주소(URL)
  • og:url: 페이지 주소(URL)

트위터 카드

웹페이지가 소셜 미디어(트위터)로 공유될 때 우선적으로 활용되는 정보를 지정한다.

<meta property="twitter:card" content="summary" />
<meta property="twitter:site" content="Starbucks" />
<meta property="twitter:title" content="Starbucks Coffee Korea" />
<meta property="twitter:description" content="스타벅스는 세계에서 가장 큰 다국적 커피 전문점으로, 64개국에서 총 23,187개의 매점을 운영하고 있습니다." />
<meta property="twitter:image" content="./images/starbucks_seo.jpg" />
<meta property="twitter:url" content="https://starbucks.co.kr" />
  • twitter:card: 페이지(카드)의 유형(E.g. summary, player)
  • twitter:site: 속한 사이트의 이름
  • twitter:title: 페이지의 이름(제목)
  • twitter:description: 페이지의 간단한 설명
  • twitter:image: 페이지의 대표 이미지 주소(URL)
  • twitter:url: 페이지 주소(URL)

SEO 란?

검색 엔진 최적화, Search Engine Optimization
구글이나 네이버 등에 자신의 웹 사이트/페이지를 노출할 수 있도록 정보를 최적화하는 작업

🎈 Google Fonts

  1. <link/>를 복사해 index.html파일의 head태그에서 main.css 위에 작성한다.
  2. css를 복사해 main.css에 작성한다.

🎈 GoogleMaterial Icons

Google Design

현재는 Material Design 3 버전이 나와있는 상태였다.

강의를 따라가기 위해 2버전의 아래 링크를 참고했다.
Material Design 2 >>

우리는 icon과 관련된 것만 사용할 것이기 때문에 아래를 참고한다.
->> 버전이 바뀌어 방법이 바뀐 것 같다.

GoogleMaterial Icons

강의때와 다르게 홈페이지가 GoogleFonts의 한 페이지로 이동된다. 주소가 바뀐 듯 하다.

⛔ 현재 버전이 달라서 강의와 같이 <span>의 클래스가 material-icons로 나오지 않는다.
유튜브에 찾아보니 현재는 span태그 위의 link를 복사해 붙여넣고 span태그를 사용해야 한다.
물론 강의와 똑같이 작성하면 정상적으로 작동하긴 한다.

⛔ 강의에 나온 방법

원하는 아이콘을 선택 후 <span>을 복사한다.

🎈 헤더

Header 태그

아래 두 줄은 같은 문장을 의미한다. html에서는 header태그를 따로 제공한다.

<!-- HEADER -->
<header></header>
<div class="header"></div>

img 태그

확대했을 때 로고의 아래쪽 여백이 남는 이유

-> img는 inline(글자) 요소, 영어의 base라인 밑의 공간을 기본적으로 가지고 있다.

아래와 같이 img를 block요소로 지정하면 여백이 제거된다.

img {
  display: block;
}

요소를 가운데 배치하는 방법

width, height, top, bottom, left, right, margin, position을 사용한다.
1. top, bottom, left, right를 이용해 양 끝의 기준점을 잡는다.
2. width, height를 지정해 브라우저가 margin을 이용해 자동으로 계산할 수 있도록 한다.
🔥 요소의 너비가 명확하게 지정되어있어야 한다!!

코드 작성

/* HEADER */
header {
  background-color: royalblue;

}
header .inner {
  width: 1100px;
  height: 120px;
  margin: 0 auto;
  background-color: orange;
  position: relative;

}
header .logo {
  height: 75px;
  position: absolute;   /* 부모요소 기준 배치 */
  top: 0;
  bottom: 0;
  left: 0;
  margin: auto;
}

link태그를 비워두는 방법

  1. #
  2. javascript:void(0)
<a href="#"></a>
<a href="javascript:void(0)"></a>

css 선택자로 구조를 먼저 정리 하기

ex)

header .sub-menu {

}

header .sub-menu ul.menu {   /* 띄어쓰기는 후손 선택자 */

}
header .sub-menu ul.menu li {

}
header .sub-menu ul.menu li a {

}
header .sub-menu .search {

}
header .sub-menu .search input {
  
}
header .sub-menu .search .material-icons {
  
}

사이드 메뉴 html, css

<div class="sub-menu">
        <ul class="menu">
          <li>
            <a href="/signin">Sign In</a>
          </li>
          <li>
            <a href="javascript:void(0)">My Starbucks</a>
          </li>
          <li>
            <a href="javascript:void(0)">Customer Service & Ideas</a>
          </li>
          <li>
            <a href="javascript:void(0)">Find a Store</a>
          </li>
        </ul>
        <div class="search">
          <input type="text" />
          <div class="material-icons">search</div>
        </div>
      </div>
/* - css -*/
a {
  text-decoration: none;  /* 밑줄 없애기 */
}



header .sub-menu ul.menu {   /* 띄어쓰기는 후손 선택자 */
  font-family: Arial, sans-serif;
  display: flex;
}
header .sub-menu ul.menu li {
  position: relative;
}
header .sub-menu ul.menu li::before {   /* ::는 가상요소 선택자, before는 인라인 */
  content:"";
  display: block;
  width: 1px;
  height: 12px;
  background-color: #e5e5e5;
  position: absolute;   /* absolute, fixed는 block요소로 자동으로 바뀜 */
  top: 0;
  bottom: 0;
  margin: auto 0;
}
header .sub-menu ul.menu li:first-child::before {
  display: none;   /* 첫번째 구분선을 안보이게 함 */
}
header .sub-menu ul.menu li a {
  /* background-color: red; */
  font-size: 12px;
  padding: 11px 16px;   /* 클릭할 수 있는 영역을 넓힘 */
  display: block;   /* a태그는 inline요소라 padding, margin등을 설정할 수 X */
  color: #656565;

}
header .sub-menu ul.menu li a:hover {
  color: #000;
}

검색

  • sub menu css
header .sub-menu .search {
  /* background-color: red; */
  height: 34px;
  position: relative;
}
header .sub-menu .search input {
  width: 36px;
  height: 34px;
  padding: 4px 10px;
  border: 1px solid #ccc;
  box-sizing: border-box;
  border-radius: 5px;
  outline: none;
  background-color: #fff;
  color: #777;
  font-size: 12px;
  transition: width .4s;
}
header .sub-menu .search input:focus {
  width: 190px;
  border-color: #669900;
}
header .sub-menu .search .material-icons {
  height: 24px;
  position: absolute;
  top: 0;
  bottom: 0;
  right: 5px;
  margin: auto;
}
  • ul과 search를 포함한 sub-menu를 flex로 변경
header .sub-menu {
  display: flex;
}
  • input박스가 아닌 돋보기를 눌렀을 때도 hover가 되도록 해야함 -> JS로 해결
    main.js 생성, script태그 연결
<script defer src="./js/main.js"></script>

search클래스를 가진 div요소를 클릭하면 input요소에 focus를 하게 한다.

const searchEL = document.querySelector('.search')
const searchInputEl = searchEL.querySelector('input')

searchEL.addEventListener('click', function(){
  // Logic..
  searchInputEl.focus();
});

input 요소에 focus가 되면 클래스가 search인 div요소에 focused라는 클래스를 추가한다.
위의 상황에서 input요소에 html특성중 palceholder기능을 추가한다.

searchInputEl.addEventListener('focus', function() {
  searchEL.classList.add('focused');
  searchInputEl.setAttribute('placeholder', '통합검색');
})

blur상태이면 palceholder 문장을 제거한다.

searchInputEl.addEventListener('blur', function() {
  searchEL.classList.remove('focused');
  searchInputEl.setAttribute('placeholder', '');
});

focused 상태일 때 돋보기 아이콘이 천천히 사라지게 한다.

header .sub-menu .search .material-icons {
  height: 24px;
  position: absolute;
  top: 0;
  bottom: 0;
  right: 5px;
  margin: auto;
  transition: .4s;    /* transition 작성 */
}
header .sub-menu .search.focused .material-icons {   /* .search.focused 붙여써야 일치선택자 */
  opacity: 0;
}

side menu 바들을 오른쪽 상단에 위치하게 한다.

header .sub-menu {
  position: absolute;
  top: 10px;
  right: 0;
  display: flex;
}

🎈 메인 메뉴

메인 메뉴 ul

<ul class="main-menu">
        <li class="item">
          <div class="item__name">COFFEE</div>
          <div class="item__contents">
            <div class="contents__menu">
              <div class="inner">
                COFFEE
              </div>
            </div>
            <div class="contents__texture">
              <div class="inner">
                COFFEE
              </div>
            </div>
          </div>
        </li>
        <li class="item">
          <div class="item__name">MENU</div>
          <div class="item__contents">
            <div class="contents__menu">MENU</div>
            <div class="contents__texture">MENU</div>
          </div>
        </li>
        <li class="item">
          <div class="item__name">STORE</div>
          <div class="item__contents">
            <div class="contents__menu">STORE</div>
            <div class="contents__texture">STORE</div>
          </div>
        </li>
        <li class="item">
          <div class="item__name">RESPONSIBILITY</div>
          <div class="item__contents">

          </div>
        </li>
        <li class="item">
          <div class="item__name">MY STARBUCKS REWARDS</div>
          <div class="item__contents">

          </div>
        </li>
        <li class="item">
          <div class="item__name">WHAT'S NEW</div>
          <div class="item__contents">

          </div>
        </li>
      </ul>

메인 메뉴 CSS

header .main-menu {
  position: absolute;
  bottom: 0;
  right: 0;
  z-index: 1;   /* 요소의 쌓임 순서 */
  display: flex;
}
header .main-menu .item {
  
}
header .main-menu .item .item__name {
  padding: 10px 20px 34px 20px;
  font-family: Arial, sans-serif;
  font-size: 13px;
}
header .main-menu .item:hover .item__name {
  background-color: #2c2a29;
  color: #669900;
  border-radius: 6px 6px 0 0;
}
header .main-menu .item .item__contents {
  width: 100%;
  position: fixed;  /* 뷰포트 기준 */
  left: 0;
  display: none;
}
header .main-menu .item:hover .item__contents { 
  display: block;   /* item에 마우스를 올리면 contents가 출력됨 */
}
header .main-menu .item .item__contents .contents__menu {
  background-color: red;
  height: 200px;
}
header .main-menu .item .item__contents .contents__texture {
  background-color: orange;
  height: 100px;
}
  • hover를 했을때 itemname과 itemcontents 모두에게 영향이 가야하기 때문에 header .main-menu .item:hover .item__contents 와 같이 hover를 작성한다.

  • inner 클래스
    화면의 중앙으로 원하는 만큼의 너비를 사용해 가운데 정렬을 한다.
    공통적인 내용의 inner와 header바로 자식선택자 inner를 구분해 작성한다.

<li class="item">
          <div class="item__name">COFFEE</div>
          <div class="item__contents">
            <div class="contents__menu">
              <div class="inner">
                COFFEE
              </div>
            </div>
            <div class="contents__texture">
              <div class="inner">
                COFFEE
              </div>
            </div>
          </div>
        </li>

html 태그 구조 정리
inner부분의 div를 ul로 바꾸고, 중간의 ul을 바꾸고 바로 li태그를 사용한다.

<li class="item">
          <div class="item__name">COFFEE</div>
          <div class="item__contents">
            <div class="contents__menu">
              <ul class="inner">
                <li></li>
              </ul>
            </div>
            <div class="contents__texture">
              <div class="inner">
                
              </div>
            </div>
          </div>
        </li>

contents__menu 구조

<div class="contents__menu">
              <ul class="inner">
                <li>
                  <h4>커피</h4>
                  <ul>
                    <li>스타벅스 원두</li>
                    <li>스타벅스 비아</li>
                    <li>스타벅스 오리가미</li>
                  </ul>
                </li>
                <li>
                  <h4>에스프레소 음료</h4>
                  <ul>
                    <li>도피오</li>
                    <li>에스프레소 마키아또</li>
                    <li>아메리카노</li>
                    <li>마키아또</li>
                    <li>카푸치노</li>
                    <li>라떼</li>
                    <li>모카</li>
                    <li>리스트레또 비안코</li>
                  </ul>
                </li>

              </ul>
            </div>

contents__menu CSS
header .main-menu .item .item__contents .contents__menu > ul > li ul는 삭제함

header .main-menu .item .item__contents .contents__menu {
  background-color: #2c2a29;
}
header .main-menu .item .item__contents .contents__menu > ul {
  display: flex;
  padding: 20px 0;
}
header .main-menu .item .item__contents .contents__menu > ul > li {
  width: 220px;
}
header .main-menu .item .item__contents .contents__menu > ul > li h4 {
  padding: 3px 0 12px 0;
  font-size: 14px;
  color: #fff;
}
header .main-menu .item .item__contents .contents__menu > ul > li ul li{
  padding: 5px 0;
  font-size: 12px;
  color: #999;
  cursor: pointer;  /* cursor가 손모양으로 변함 */
}

contents__texture 구조

<div class="contents__texture">
              <div class="inner">
                <h4>나와 어울리는 커피 찾기</h4>
                <p>스타벅스가 여러분에게 어울리는 커피를 찾아드립니다.</p>
                <h4>최상의 커피를 즐기는 법</h4>
                <p>여러가지 방법을 통해 다양한 풍미의 커피를 즐겨보세요.</p>
              </div>
            </div>

contents__texture CSS

header .main-menu .item .item__contents .contents__texture {
  padding: 26px 0;
  font-size: 12px;
  background-image: url("../images/main_menu_pattern.jpg");
}
header .main-menu .item .item__contents .contents__texture h4 {
  color: #999;
  font-weight: 700;
}
header .main-menu .item .item__contents .contents__texture p {
  color:#669900;
  margin: 4px 0 14px;   /* 상 중 하 */
}

contents__menu에서 메뉴를 클릭했을때 글씨색 초록색

header .main-menu .item .item__contents .contents__menu > ul > li ul li:hover {
  color: #669900;

🎈 BEM

HTML 클래스 속성의 작명법
Block Element Modifier

  • 요소__일부분 : Underscore(Lodash) 기호로 요소의 일부분을 표시
  • 요소--상태 : Hyphen(Dash) 기호로 요소의 상태를 표시

ex) css에서 .container .name일 때, container 바로 자식 name과 container .item.name 까지 원치 않는 스타일이 들어간다.

profile
Hello! I am Ogu, a developer who loves learning and sharing! 🐤🐤 <br> こんにちは!学ぶことと共有することが好きな開発者のOguです!🐤

0개의 댓글