ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [HTML & CSS] Google Clone (1) Flex Container, 로고, footer
    FrontEnd/CSS 2021. 2. 21. 15:45

    Google 페이지를 클론코딩하는 작업을 했다. 기능적인 부분은 무시하고 외양에만 집중했다.

    분량 이슈로 나머지는 아래쪽에서 마무리했다.

    2021/02/22 - [FrontEnd/Prep] - [HTML & CSS] Google Clone (2) 내비게이션, 검색


     

    먼저 페이지를 Box 단위로 나누어 보았다.

     

     

    큰 박스 6개가 제일 먼저 눈에 띈다.

    위의 로그인 메뉴는 내비게이션인 것 같고, 로고는 아무 기능이 없는 그냥 로고 이미지, 중간의 검색창이 메인으로 보인다.

    검색창 아래에는 현재 설정된 언어를 보여주는 부분이 나오고, 그 아래로 접속한 국가, 마지막으로 정보 및 약관 라인이 있다.

    순서대로 nav, div, main, section, footer(div(접속국가), div(정보 및 약관) 태그로 구성하기로 한다.

     

     

    <!DOCTYPE html>
    <html>
      <head>
        <link rel="stylesheet" href="style.css">
      </head>
      <body>
        <nav>내비게이션</nav>
        <div class="logo">로고</div>
        <main class="search">검색</main>
        <section class="language">언어설정</section>
        <footer>
          <div class="location">접속국가</div>
          <div class="clauses">약관</div>
        </footer>
      </body>
    </html>

     


    [로고] margin: auto와 flexbox

    로고 이미지가 제일 간단하니까 로고 이미지를 먼저 추가하기로 한다.

    구글 홈페이지에 들어가서 이미지 주소를 복사해온 다음, 로고 부분에 추가해준다.

     

     

    <div class="logo">
      <img class="logoImg" alt="Google" src="https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png">
    </div>

     

     

    로고가 무사히 추가되었으니 가운데 정렬을 해야한다. 개발자 도구에서 로고를 어떻게 정렬했는지 살펴보니,

     

     

    부모태그에서 align-items: center를 주었다. align-items가 어떤 프로퍼티인지 MDN을 찾아보았다.

    align-self 프로퍼티를 부모 수준에서 직계 자식들한테 실행하는 프로퍼티라고 한다.

    flexbox에서는 교차축(flex축 반대축)에 요소들을 정렬하고, grid에서는 그리드 영역 내 블록축 안에서 요소를 정렬한다고 한다.

     

    그대로 부모에게 display: flex와 align-items를 줘본다.

    이동할 공간을 주기 위해서 height를 주고, 블록을 크기를 파악하기 위한 background-color도 주었다.

    .logo {
    	display: flex;
    	flex-direction: row;
    	align-items: center;
    	height: 300px;
    	background-color: lightgray;
    }

     

     

    flex축이 row니, 반대편인 column 방향으로 정렬되고 있다. flex-direction을 column으로 바꿔보니

     

     

    row방향으로 정렬되는 걸 확인할 수 있다.

    구글 홈페이지는 윈도우창의 세로 크기에 따라서 위의 회색 로고박스 크기가 달라지는데,

    구글 로고는 회색 로고박스의 end부분 중앙에 위치하고 있다.

    나도 따라서 flex-direction을 column으로 주고, 박스 내에서 로고의 위치를 바닥에 붙이는 속성을 찾아보았다.

    위 img를 감싸고 있는 부모는 아래 프로퍼티를 가지고 있다.

    min-height: 92px; /* 로고 이미지 높이 */
    max-height: 290px;
    height: 100%;
    margin-top: auto;

    div로 한 번 더 감싸고, 위의 프로퍼티를 적용해보니

    <div class="logo">
      <div class="logoWrapper">
        <img class="logoImg" alt="Google" src="https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png">
      <div>
    </div>

     

     

    의도대로 바닥 중앙 정렬이 되었다! 궁금해서 왜 그런지 살펴보니 이런 글이 있다.

    flexbox로 만들 수 있는 10가지 레이아웃의 3 - 브라우저 화면 아래에 붙는 푸터 부분에서,

    flex item에 margin-top: auto 속성을 적용하면 바깥 여백이 flex item을 위쪽에서 아래쪽으로 민다고 되어있다.

    flex item과 margin auto 키워드로 정보를 좀 찾아보니

    css-tricks.com/the-peculiar-magic-of-flexbox-and-auto-margins/

    사방 모두 auto margin의 반대로 정렬된다고 한다. css-tricks 포스트에서 참조한 아래 글에서

    hackernoon.com/flexbox-s-best-kept-secret-bd3d892826b6

     

    "If you apply auto margins to a flex item, that item will automatically extend its specified margin to occupy the extra space in the flex container, depending on the direction in which the auto-margin is applied."

    "flex 요소에 auto margin을 주면, 해당 요소는 flex 컨테이너에서 auto-margin이 지정된 방향으로 추가 공간을 확보하기 위해서, 지정된 margin 값을 자동적으로 초과하게 된다."

     

    방향을 명시하지 않으면 정중앙에 놓이게 되므로, 메인축에 하나 이상의 요소를 배치하는 방법이 된다고 한다.

    margin: auto를 2개 이상의 flex item에 지정하면 flex 컨테이너에 justify-content: space-around를 준 것과 같다고.

    그리고 auto margin을 쓰면 해당 요소가 메인축에서 점유할 수 있는 공간 전부를 마진이 먼저 가져가 버리기 때문에, text-align은 무용지물이 된다.

     

    이 로고박스가 늘어나기는 하는데, 일정 수준까지만 늘어나고 멈춘다. flex Container의 프로퍼티를 찾아봐서, logo 클래스에 max-height: 290px;을 줬다.

    이제 그 다음으로 컨텐츠가 적은 언어설정 부분을 만들어본다.

     

     


    [언어설정] flex-grow, flex-shrink

    이 부분도 위의 로고와 마찬가지로 flex다. 화면을 늘렸을 때, 로고박스는 최대 290px까지를 차지하고, 나머지 공감을 언어설정 파트가 가져간다.

    컨테이너는 늘어나지만 컨테이너 상에서 텍스트(Google 제공 서비스: English)의 위치는 그대로여야해서 div로 한 번 더 묶어줬다.

     

     

    <section class="language">
      <div class="langOption">
        Google 제공 서비스: <a>English</a>  
      </div>
    </section>

     

    먼저 텍스트 부분에 맞춰서 CSS를 주고

     

     

    .langOption {
    	font-size: small;
    	font-family: arial,sans-serif;
    	line-height: 28px;
    	text-align: center;
    }
    
    .langOption a {
    	color: #1a0dab;
    	padding: 0 3px;
    	text-decoration: none;
    }
    
    .langOption a:hover {
    	text-decoration: underline;
        cursor: pointer;
    }

    부모로 가서 flex를 주려는데 부모의 display가 flex가 아니고 block다. 그리고 flex-grow: 1이라는 프로퍼티를 가지고 있다.

     

     

    생각해보니 저 문구 부분은 고정된 위치에 있으니 flex될 게 없고, 이 문구를 감싸고 있는 공간 자체가 늘어나는 거니까

    맨처음에 나눴던 박스 6개를 가진 부모가 flex Container여야 한다.

    전체를 감싸는 div를 하나 추가해주고

    <body>
      <div class="mainFlexer">
        <nav>내비게이션</nav>
        <div class="logo"></div>
        <main class="search">검색</main>
        <section class="language"></section>
        <footer>
          <div class="location">접속국가</div>
          <div class="clauses">약관</div>
        </footer>
      </div>
    </body>

    flex가 적용될 수 있도록 CSS를 주었다.

    html, body {
      height: 100%;  /* 화면 전체를 점유 */
      margin: 0;
      padding: 0;
    }
    
    .mainFlexer {
      display: flex;
      flex-direction: column;
      height: 100%;  /* 얘도 화면 전체를 점유 */
    }
    
    .language {
      flex-grow: 1;  /* 늘어나라 */
      background-color: lemonchiffon;
    }

     

     

     

    화면에서 다른 요소들이 차지하는 부분을 빼고는 전부 점유하고 있음을 확인했다.

    기본값이 0이라서 나머지 부분은 신경쓰지 않아도 될 것 같다.

    flex-shrink는 이와는 반대로, flex-container가 flex-item 보다 작을 때, 크기를 줄일 건지를 설정하는 옵션이다.

    화면 크기가 작아져도 저 텍스트 사이즈가 여기서 더 이상 줄어들면 안 되니까 flex-shrink: 0;을 준다.

     

    이제 이 밑에 오는 footer를 만든다.

     

     


    [footer] justify-content: space-evenly;  flex-wrap: wrap;

    footer에는 접속국가 부분과 약관 부분이 있다.

     

     

    약관은 다시 2부분으로 나뉜다. Google 정보 ~ 검색의 원리가 한 묶음이고, 개인정보처리방침 ~ 설정이 한 묶음이다.

    각각은 a태그로 hover underline이 달려있다.

    일단 기본적인 부분을 채워주고

    <footer>
      <div class="location">
        대한민국
      </div>
      <div class="clauses">
        <div class="clausesWrapper">
          <a>Google 정보</a>
          <a>광고</a>
          <a>비즈니스</a>
          <a>검색의 원리</a>
        </div>
        <div class="clausesWrapper">
          <a>개인정보처리방침</a>
          <a>약관</a>
          <a>설정</a>
        </div> 
      </div>
    </footer>

    폰트, 색상, 배경색, 패딩을 맞춰줬다.

    footer {
      background-color: #f2f2f2;
    }
    
    .location {
      padding: 15px 30px;
      border-bottom: 1px solid #dadce0;
      font-size: 15px;
      color: rgba(0,0,0,.54);
      font-family: arial,sans-serif;
    }
    
    .clauses {
      font-size: 14px;
      font-family: 'Apple SD Gothic Neo',arial,sans-serif;
      color: #222;
      padding: 0 20px;
    }
    
    .clauses a {
      padding: 15px;
      color: #70757a;
      text-decoration: none;
      cursor: pointer;
    }
    .clauses a:hover {
      text-decoration: underline;
    }

     

     

    접속국가 부분은 문제가 없는데, 약관 부분이 두줄로 나온다.

    개발자도구에서 약관 ~ 설정을 감싸고 있는 div 태그를 살펴보니 justify-content: space-evenly; 속성이 부여되어 있다.

    MDN을 보니 flex container의 메인축에 놓인 자식들이나, grid container의 inline(row) 축에 놓인 자식들을 어떻게 정렬할 것인지를 결정하는 속성이라고 한다.

    다만 justify-content는 length와 auto margin이 적용된 뒤에 반영되므로, flexbox 레이아웃에서 flex-grow가 0이 아닌 자식이 있는 경우처럼, 특정 요소가 남은 공간을 이미 다 점유해버린 경우에는 효과가 없다고 한다.

     

    justify-content 속성을 줘야 하니까 display: flex를 주고, justify-content: space-evenly를 줬다.

    .clauses {
      /* 폰트 및 나머지 설정들 */
      display: flex;
      justify-content: space-evenly;
    }

     

     

    2줄인 문제는 해결 됐는데 a태그의 패딩 문제가 해결되지 않았다.

    분명히 a에 padding: 15px가 들어가있는데 세로 패딩이 전혀 반영되지 않았다.

    곰곰이 생각해보니 a는 inline 태그다. 당연히 세로 패딩이 반영될리가 없다.

    a { display: inline-block; }을 줬더니

     

     

     

    반영은 됐는데 실제 구글 페이지와 미묘하게 분할 상태가 다르다. 다시 개발자도구를 열어보니

     

     clausesWrapper에도 display: flex와 justify-content: space-evenly가 있다. 똑같이 반영해주니

    .clausesWapper {
      /* 폰트 및 나머지 설정들 */
      display: flex;
      justify-content: space-evenly;
    }

     

     

    해결되었다. 화면이 작아서 위의 텍스트가 다 들어가지 않는 경우, 구글 페이지는 이렇게 두 줄로 표시되는데,

    아무 설정 안 한 내 페이지는 한 블록의 넓이가 좁아진다. 이걸 해결하려면 clausesWrapper에 flex-wrap: wrap;을 주면 된다.

     

     

     

    그러면 이렇게 되는데, 이건 clausesWrapper의 부모인 clauses에 flex-wrap: wrap;가 없기 때문이다.

    clausesWrapper의 자식들은 두줄에 분배되었지만, clausesWrapper 자체는 clauses의 공간을 row 방향으로 나눠 갖고 있다.

     

     

    .clauses {
        flex-wrap: wrap;
    }
    

     

     

    성공!

     

     

    'FrontEnd > CSS' 카테고리의 다른 글

    [HTML & CSS] Google Clone (2) 내비게이션, 검색  (0) 2021.02.22
    [CSS] Font, Background  (0) 2021.02.21
    [CSS] Box Model , Display, Position, float  (0) 2021.02.19
    CSS - 선택자, 속성값, Reset CSS  (0) 2021.02.17

    댓글

Designed by Tistory.