ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 레이아웃 따라 만들기 - HTML/CSS
    프론트엔드 2019. 12. 18. 20:34

    ※ 자바스크립트 프론트엔드 스터디에서 발표했던 내용을 정리한 글이기 때문에

    스터디원이 아니시라면 조금 이해가 어려우실 수 있습니다

     

    위 이미지와 같은 레이아웃을 제작하는 과정입니다.(desktop_components_02)

    Figma 링크 : https://www.figma.com/file/viEujZmbqeYG4FHhsi0H7o/responsive_web_components_mobikdesign_v1.0-(Copy)?node-id=0%3A1

     

    Figma

    Created with Figma

    www.figma.com

     

    먼저 HTML에서 반응형 웹 설정을 해주세요.

    <meta name="viewport" content="width=device-width" initial-scale=1.0>

     

    viewport : viewport란 웹페이지의 전체 영역 중 사용자의 기기 화면에 보여지는 영역을 말합니다. 위의 태그는 '웹페이지가 사용자의 화면에 어떤 크기, 비율로 보여질지'를 설정하는 태그입니다.

    width = device-width : 웹페이지의 '가로길이'를 사용자의 기기 화면 가로 길이에 맞춘다는 의미입니다.

    initial-scale=1.0 : 웹페이지에 첫 접속했을 때 화면의 비율을 말합니다. 1.0으로 설정해줘서 확대되거나 축소되지 않은 원래 크기로 보여지도록 설정했습니다.

     

    <link rel="stylesheet" href="style1.css" media="(min-width: 768px)">
    <link rel="stylesheet" href="style2.css" media="(min-width: 360px) and (max-width: 768px)">
    <link rel="stylesheet" href="style3.css" media="(max-width: 360px)">

    두번째 줄의 태그는 "사용자의 화면 가로길이가 360px이상 768px이하일 때, "style2.css"파일로 연결하라"는 의미의 태그입니다.

    사용자의 화면 너비 (가로길이)에 따라 다른 css파일로 연결됩니다.

    발표에서는 일단 너비가 768px 이상 일 때 연결되는 "style1.css"파일 하나만 작업해보겠습니다. (하나만 제대로 작업해보면 나머지 파일은 같은 방식으로 쉽게 작업할 수 있습니다)

     

    HTML에서 전체적인 구조를 작성해주세요.

    ※ HTML 전체 소스코드는 페이지 하단에 올려놨습니다(html소스는 구조만 파악한 뒤 그대로 복사붙여넣기 해서 사용하고, css소스는 직접 작성해보시는 것을 추천합니다)

    <div id="layout">
    
    <div id="navBar"></div>
    
    <div id="title"></div>
    
    <div id="wrapper"></div>
    
    <div id="footerSections"></div>
    
    <div id="bottomBar"></div>
    
    </div>

    레이아웃 전체를 div태그를 이용해 다섯 부분으로 나누고(navBar, title, wrapper, footerSections, bottomBar), "layout"이라는 id값을 가진 태그로 레이아웃 전체를 묶어줬습니다.

     

    CSS에서 레이아웃의 기본 틀을 구성합니다. (height or grid)

    두 가지 방법으로 해보겠습니다.

    첫 번째는,

    각각의 <div>태그에 height 값을 설정해서 레이아웃을 구성하는 방법입니다. 우리가 만들 레이아웃은 위에서 아래로, 세로로 쌓아나가는 기본적인 배치이기 때문에

    <div>태그로 묶인 각각의 '박스'에 높이만 설정해줘도 레이아웃의 틀이 완성됩니다.

    /* height 설정으로 layout 만들기 */
    
    
    
    #navBar { height: 64px; }
    
    #title { height: 200px; }
    
    #wrapper { height: 712px; }
    
    #footerSections { height: 184px; }
    
    #bottomBar { height: 48px; }

    높이는 Figma에서 보고 그대로 써줬습니다. (반응형 웹이라 가로길이는 화면너비에 따라 유동적으로 만들지만, 세로 길이는 그냥 '픽셀'을 사용해서 고정해줬습니다.)

     

    두 번째는,

    'grid'속성을 이용하는 방법입니다. grid는 표를 만드는 것처럼 레이아웃을 구성합니다.

    우리가 만드는 레이아웃이 5행으로 이뤄진 표라고 생각하고

    #layout {
    
    display: grid;
    
    grid-template-rows: 64px 200px 712px 184px 48px;
    
    }

    각 행의 높이를 64px, 200px, ...으로 설정했습니다. (rows는 행을 의미합니다)

    첫번째 방법과 동일한 틀이 만들어집니다.

    단, grid속성은 인터넷익스플로러에서는 지원이 되지 않거나 일부만 지원되니 참고하세요!(https://caniuse.com/#search=grid)

     

    Position을 설정합니다 ( 중요!! )

    navBar, title, wrapper, footerSections, bottomBar의 position을 relative로 설정해주세요!

    #navBar {
    
    position: relative;
    
    }
    
    
    
    #title {
    
    position: relative;
    
    }
    
    
    
    #wrapper {
    
    position: relative;
    
    }
    
    
    
    #footerSections {
    
    position: relative;
    
    }
    
    
    
    #bottomBar {
    
    position: relative;
    
    }
    
    

     

    아래와 같이 한꺼번에 설정할 수도 있습니다.

    #layout > * {
    
    position: relatvie;
    
    }

    /* layout 태그의 하위 태그들에 한꺼번에 스타일이 적용됩니다. */

     

    position을 relative로 설정해야하는 이유는, Figma에 있는 레이아웃의 css속성들을 확인해보시면 알 수 있습니다.

    대부분의 요소들이 "position: absolute"로 배치되어 있습니다.

    position:absolute로 설정을 하면, position이 static이 아닌(absolute/relative/fixed) 부모 태그를 기준으로 배치가 됩니다. 만약 position이 static이 아닌 부모태그를 찾을 수 없으면, <body>태그를 기준으로 배치가 됩니다.

    position 속성들 ↓

    더보기

    position 속성들

    static : position을 따로 설정하지 않았을 경우 기본적으로 부여되는 포지션.

    absolute : "position이 static이 아닌 상위 엘리먼트를 기준"으로 배치하는 것.

    (position이 static이 아닌 상위 엘리먼트가 없을 경우 body태그를 기준으로 배치됨.)

    relative : "원래의 위치 기준"으로 배치하는 것

    fixed : "전체화면 기준"으로 배치하는 것

     

    예를 들어 Figma에서 "HEADING TITLE" 요소를 보면 ,

    position: absolute; left: 5.78%; right: 5.62%; top: 24%; bottom: 48%;

    으로 배치가 되어 있습니다.

    "HEADING TITLE"의 상위 엘리먼트는 <div id="title">태그인데, title태그의 position은 static입니다.(포지션을 따로 설정하지 않았기 때문에 기본값인 static으로 설정되어있는 상태)

    따라서 "HEADING TITLE"은 포지션이 static이 아닌 상위태그가 없어 body태그를 기준으로 배치가 됩니다.

    그러니 body태그의 높이 기준으로 아래에서 48%만큼, 위에서 24% 떨어진 위치에 배치가 되는데,

    직접 해보면 아시겠지만 제대로 된 위치가 아닌 이상한 위치에 배치가 됩니다.

     

    제대로 배치되게 하려면 상위 엘리먼트인 <div id="title">태그 기준으로 배치되도록(title태그의 높이 200px 기준으로 위에서 24%, 아래서 48%떨어진 위치에 배치되어야 합니다)

    <div id="title">태그의 position을 absolute, relative, 혹은 fixed 셋 중 하나로 설정해줘야합니다.

    이 중 가장 적합한 속성은 relative입니다.

    fixed는 스크롤을 올리거나 내려도 계속 같은 자리에 있는 광고배너와 같은 특수한 경우에만 사용하고, absolute를 선택한다면 아예 전체 레이아웃 틀 자체를 absolute로 다시 짜야합니다.(이 방법은 위에서처 height / grid 로 레이아웃을 짜는 것에 비해 복잡합니다.)

    반면에 relative를 선택하고 top, left 값 등을 별도로 설정하지 않으면 원래 위치에 그대로 배치되기 때문에 우리가 앞에서 만든 레이아웃 틀을 건드리지 않고 진행할 수 있기 때문입니다.

     

    ------

    여기까지 하셨다면 나머지 부분은 figma에 있는 속성들을 복사+붙여넣기 하시면 됩니다!

     

    발표 때 제대로 보여드리지 못한 footerSections 배치하는 법만 추가로 설명해드리겠습니다.

     

    footerSections 배치하기

    HTML문서의 <div id="footerSections"> 태그 안에 footer section의 요소들을 작성해줍니다.

    아래 코드를 복붙하셔도 됩니다.

    <div id="footerSection1">
    	<div class="sectionName">footer section 01</div>
    	<div class="line1"></div>
    	<div class="line2"></div>
    	<div class="explain">Apparently we had reached a great height in the atmosphere, for the sky was a dead black, and the stars had ceased to twinkle.</div>
    </div>
    
    <div id="footerSection2">
    	<div class="sectionName">footer section 02</div>
    	<div class="line1"></div>
    	<div class="line2"></div>
    	<div class="explain">By the same illusion which lifts the horizon of the sea to the level of the spectator on a hillside, the sable cloud beneath was dished</div>
    </div>
    
    <div id="footerSection3">
    	<div class="sectionName">footer section 03</div>
    	<div class="line1"></div>
    	<div class="line2"></div>
    	<div class="explain">And the car seemed to float in the middle of an immense dark sphere, whose upper half was strewn with silver.</div>
    </div>
    
    <div id="footerSection4">
    	<div class="sectionName">footer section 04</div>
    	<div class="line1"></div>
    	<div class="line2"></div>
    	<div class="explain">Looking down into the dark gulf below, I could see a ruddy light streaming through a rift in the clouds.</div>
    </div>

     

    이제 footerSection1, 2, 3, 4의 자리를 각각 잡아줘야합니다.

    Figma에서 Footer_section_v01 , v02, v03, v04의 속성을 각각 복사해와서 붙여넣기 해주시면 돼요.

     

    #footerSection1 {
      position: absolute;
      left: 5.62%;
      right: 73.12%;
      top: 20.69%;
      bottom: 31.03%;
    }
    
    #footerSection2 {
      position: absolute;
      left: 28.12%;
      right: 50.62%;
      top: 20.69%;
      bottom: 31.03%;
    }
    
    #footerSection3 {
      position: absolute;
      left: 50.62%;
      right: 28.12%;
      top: 20.69%;
      bottom: 31.03%;
    }
    
    #footerSection4 {
      position: absolute;
      left: 73.12%;
      right: 5.62%;
      top: 20.69%;
      bottom: 31.03%;
    }
    
    

    각 섹션들의 자리배치를 해줬습니다.

     

    이제 세부적인 스타일을 적용해야합니다.

    .sectionName {
      font-family: Roboto;
      font-style: normal;
      font-weight: normal;
      font-size: 14px;
      line-height: 16px;
      letter-spacing: 0.04em;
      text-transform: uppercase;
      color: rgba(0, 0, 0, 0.8);
      margin-bottom: 15px;
    }
    
    .line1 {
      background: rgba(0, 0, 0, 0.08);
      height: 2px;
    }
    
    .line2 {
      background: linear-gradient(234.67deg, rgba(255, 255, 255, 0.16) 0.24%, rgba(255, 255, 255, 0) 100.87%), #006BE8;
      height: 2px;
      width: 30%;
      position: relative;
      bottom: 2px;
    }
    
    .explain {
      font-family: Roboto;
      font-style: normal;
      font-weight: normal;
      font-size: 12px;
      line-height: 20px;
      letter-spacing: 0.02em;
      color: rgba(0, 0, 0, 0.64);
      margin-top: 15px;
    }
    
    

    각 footer section안에 공통적으로 들어가있는 세부요소들(이름, 라인, 설명 등)은 id값 대신 class값을 지정해줬기 때문에 이렇게 한꺼번에 스타일을 적용할 수 있습니다.

    (id값은 하나의 태그에만 지정할 수 있고, class값은 여러개의 태그에 지정할 수 있기 때문에 여러 개의 태그에 한꺼번에 공통된 스타일을 적용하려면 class값을 지정합니다.)

     

    Footer Section 제목과 아래 영어로 된 설명을 구분하는 라인이 보이시죠?

    라인은 Figma에서 이미지로 export해서 써도 되지만 저는 직접 만들어봤습니다.

    1. line1과 line2에 각각 background color와 height값을 설정해줘서(background 색상코드는 figma참고, height는 2px) 회색과 파란색, 두 개의 라인을 만들어 줍니다.

    2. 떨어져있는 라인 두개가 겹쳐지게끔 아래쪽에 있는 파란색 라인을 position:relative;로 설정한 다음bottom:2px;로 설정해서 위로 2px올라오게 합니다. 라인 두개가 겹쳐졌습니다.

    3. 파란색 라인의 길이를 30%로 설정해주세요.( width: 30%; )

    이렇게 하면 라인이 완성됩니다.

     

    그리고 추가로

    .sectionName에는 margin-bottom:15px;

    .explain에는 margin-top:15px;

    마진을 각각 설정해줬습니다. (figma에서 footer section을 보시면 섹션이름과 라인, 아래 설명이 각각 15px만큼 떨어져있기 때문이에~)

     

    이 외에는 전부 피그마에서 복붙하시면 완성입니다!

     

    (참고! 안읽어도 상관없음

    • 사실 Figma의 레이아웃은 footer section의 모든 요소 하나하나에 일일히 다 id값을 주고 absolute로 위치를 잡아주는 방식으로 되어있는데요. 이렇게 하려면 중복된 소스코드가 많아지기 때문에 저는 그냥 footer section1, 2, 3, 4로 각각 묶어준 다음 이렇게 묶어준 네 개의 섹션만 absolute로 배치를 했어요.

    • 그리고 그 안의 세부적인 요소들은 absolute로 배치하는 대신 그냥 마진값과 포지션값을 살짝 조정해서 위치를 잡아줬습니다.

    )

     

    혹시라도 레이아웃을 만들면서 이해가 안되거나 어려운 부분이 있으시면 언제든지 저한테 질문해주세요~

    아니면 아래에 있는 소스코드를 잘 읽어보시면 어느정도 해결이 되실 거에요

    그럼 화이팅!! :D

     

    ※ 전체소스코드

    HTML 전체 소스코드입니다

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width" initial-scale=1.0>
      <title>JS Bin</title>
      <link rel="stylesheet" href="style1.css" media="(min-width: 768px)">
      <link rel="stylesheet" href="style2.css" media="(min-width: 360px) and (max-width: 768px)">
      <link rel="stylesheet" href="style3.css" media="(max-width: 360px)">
    </head>
    
    <body>
      <div id="layout">
        <div id="navBar">
          <div id="logo">LOGO</div>
          <div id="menu">
            <a class="links">menu link 01</a>
            <a class="links">menu link 02</a>
            <a class="links">menu link 03</a>
            <a class="links">menu link 04</a>
            <a class="links">menu link 05</a>
          </div>
          <input type="button" value="sign in" id="signIn">
        </div>
        <div id="title">
          <div id="heading">heading title</div>
          <div id="subtitle">heading subtitle text</div>
        </div>
        <div id="wrapper">
          <div id="inner">
            <div id="box1"></div>
            <div id="box2"></div>
          </div>
        </div>
        <div id="footerSections">
          <div id="footerSection1">
            <div class="sectionName">footer section 01</div>
            <div class="line1"></div>
            <div class="line2"></div>
            <div class="explain">Apparently we had reached a great height in the atmosphere, for the sky was a dead black, and the stars had ceased to twinkle.</div>
          </div>
    
          <div id="footerSection2">
            <div class="sectionName">footer section 02</div>
            <div class="line1"></div>
            <div class="line2"></div>
            <div class="explain">By the same illusion which lifts the horizon of the sea to the level of the spectator on a hillside, the sable cloud beneath was dished</div>
          </div>
    
          <div id="footerSection3">
            <div class="sectionName">footer section 03</div>
            <div class="line1"></div>
            <div class="line2"></div>
            <div class="explain">And the car seemed to float in the middle of an immense dark sphere, whose upper half was strewn with silver.</div>
          </div>
    
          <div id="footerSection4">
            <div class="sectionName">footer section 04</div>
            <div class="line1"></div>
            <div class="line2"></div>
            <div class="explain">Looking down into the dark gulf below, I could see a ruddy light streaming through a rift in the clouds.</div>
          </div>
        </div>
        <div id="bottomBar">
          <div id="copyright">© Copyright</div>
          <div id="facebook">ㅁ</div>
          <div id="twitter">ㅁ</div>
          <div id="instagram">ㅁ</div>
        </div>
      </div>
    
    </body>
    
    </html>

     

    CSS 전체 소스코드입니다

    #layout > * {
    	border: 1px solid gray;
    	position: relative;
    }
    #layout {
    	display: grid;
    	grid-template-rows: 64px 200px 712px 184px 48px;
    	margin-bottom: 60px;
    }
    #logo {
    	position: absolute;
    	width: 104px;
    	height: 32px;
    	left: 5.62%;
    	top: 16px;
    }
    #menu {
    	position: absolute;
    	left: 15%;
    	right: 18%;
    	top: 28.57%;
    	bottom: 42.86%;
    	text-align: center;
    	font-family: Roboto;
    	font-style: normal;
    	font-weight: normal;
    	font-size: 14px;
    	line-height: 16px;
    	/* identical to box height, or 114% */
    	
    	text-align: center;
    	letter-spacing: 0.04em;
    	text-transform: uppercase;
    	/* Text_blue */
    	
    	color: rgba(0, 0, 0, 0.88);
    }
    .links {
    	margin-left: 3%;
    }
    #signIn {
    	position: absolute;
    	left: 86.88%;
    	right: 5.62%;
    	top: 12.5%;
    	bottom: 12.5%;
    }
    #title {
    	background: linear-gradient(263.53deg, rgba(255, 255, 255, 0.32) 0.24%, rgba(255, 255, 255, 0.08) 100.87%), #006BE8;
    }
    #heading {
    	position: absolute;
    	left: 5.78%;
    	right: 5.62%;
    	top: 24%;
    	bottom: 48%;
    	font-family: Roboto;
    	font-style: normal;
    	font-weight: 500;
    	font-size: 64px;
    	line-height: 56px;
    	/* identical to box height, or 87% */
    	
    	align-items: center;
    	text-align: center;
    	letter-spacing: 0.08em;
    	text-transform: uppercase;
    	font-variant: small-caps;
    	/* #FFFFFF */
    	
    	color: #FFFFFF;
    }
    #subtitle {
    	position: absolute;
    	left: 5.78%;
    	right: 5.62%;
    	top: 64%;
    	bottom: 24%;
    	font-family: Roboto;
    	font-style: normal;
    	font-weight: 500;
    	font-size: 24px;
    	line-height: 24px;
    	/* identical to box height, or 100% */
    	
    	align-items: center;
    	text-align: center;
    	letter-spacing: 0.32em;
    	text-transform: uppercase;
    	/* #FFFFFF */
    	
    	color: #FFFFFF;
    }
    #wrapper {
    	background: gray;
    }
    #inner {
    	height: 584px;
    	margin-top: 48px;
    	margin-bottom: 80px;
    	margin-left: 8%;
    	margin-right: 8%;
    	display: grid;
    	grid-template-columns: 300px 1fr;
    }
    #box1 {
    	background-color: white;
    	margin-right: 16px;
    }
    #box2 {
    	background-color: white;
    }
    #footerSection1 {
    	position: absolute;
    	left: 5.62%;
    	right: 73.12%;
    	top: 20.69%;
    	bottom: 31.03%;
    }
    #footerSection2 {
    	position: absolute;
    	left: 28.12%;
    	right: 50.62%;
    	top: 20.69%;
    	bottom: 31.03%;
    }
    #footerSection3 {
    	position: absolute;
    	left: 50.62%;
    	right: 28.12%;
    	top: 20.69%;
    	bottom: 31.03%;
    }
    #footerSection4 {
    	position: absolute;
    	left: 73.12%;
    	right: 5.62%;
    	top: 20.69%;
    	bottom: 31.03%;
    }
    .sectionName {
    	font-family: Roboto;
    	font-style: normal;
    	font-weight: normal;
    	font-size: 14px;
    	line-height: 16px;
    	letter-spacing: 0.04em;
    	text-transform: uppercase;
    	color: rgba(0, 0, 0, 0.8);
    	margin-bottom: 15px;
    }
    .line1 {
    	background: rgba(0, 0, 0, 0.08);
    	height: 2px;
    }
    .line2 {
    	background: linear-gradient(234.67deg, rgba(255, 255, 255, 0.16) 0.24%, rgba(255, 255, 255, 0) 100.87%), #006BE8;
    	height: 2px;
    	width: 30%;
    	position: relative;
    	bottom: 2px;
    }
    .explain {
    	font-family: Roboto;
    	font-style: normal;
    	font-weight: normal;
    	font-size: 12px;
    	line-height: 20px;
    	/* or 167% */
    	
    	letter-spacing: 0.02em;
    	color: rgba(0, 0, 0, 0.64);
    	margin-top: 15px;
    	}
    #copyright {
    	position: absolute;
    	left: 41.25%;
    	right: 41.25%;
    	top: 33.33%;
    	bottom: 33.33%;
    	font-family: Roboto;
    	font-style: normal;
    	font-weight: 300;
    	font-size: 12px;
    	line-height: 16px;
    	text-align: center;
    	letter-spacing: 0.04em;
    	color: rgba(0, 0, 0, 0.48);
    }
    #instagram {
    	position: absolute;
    	left: 93.12%;
    	right: 5.62%;
    	top: 33.33%;
    	bottom: 33.33%;
    }
    #twitter {
    	position: absolute;
    	left: 91.25%;
    	right: 7.5%;
    	top: 33.33%;
    	bottom: 33.33%;
    }
    #facebook {
    	position: absolute;
    	left: 89.38%;
    	right: 9.38%;
    	top: 33.33%;
    	bottom: 33.33%;
    }

     

    댓글

Designed by Tistory.