공부하는 블로그

# Timeline CSS 작성 본문

기타

# Timeline CSS 작성

devtimothy 2019. 12. 15. 00:08

Timeline CSS 작성

빔캠프 의 작심삼일 CSS 코스를 듣고 있다. 왜 작심삼일이냐하면, 매주 토요일에 3주간 진행되기 때문이다. (3일)

그런데 사실 CSS라는게 참 애물단지 같고, 막연한 어려움을 가지고 있던 녀석이었다. 어떻게 공부해야 잘 하는 건지도 모르겠고, 알수 없는 것들 투성이에, 그냥 삽질 좀 하다보면, 그리고 구글링 좀 하다보면 어찌어찌 되는 녀석이었기에 공부를 미루고 미뤄왔던 것 같다.

지난주 토요일에는 첫 시간을 나갔는데, CSS의 block level elements와 inline의 특성과 선택자 우선순위 동작방식, 네거티브 마진에 대한 이해를 배웠다. MDN 을 통해서 CSS 속성이 가진 기본 값이 무엇인지에 대해서 생각해보게 되었다.

사실 MDN 문서에서 width 의 속성과 같은 문서를 자세히 살펴봐왔던 적이 없었는데, 이 시간을 통해서 이러한 문서를 보는 눈을 기를수 있어서 좋았다.

첫주차 숙제로는 Timeline CSS를 만들어오라는 숙제를 받았다. 배운 것들을 잘 활용할 수 있을만한 숙제를 내주신 것 같다.

대상

구글링을 하다가 마음에 드는 이미지를 발견했다.

이미지

똑같이는 아니고 최대한 비슷하게 만들고자 한다.

헤더 부분

헤더는 사실 별게 없다.

.header {
  background-color: rgb(107, 171, 163);
  text-align: center;
  padding: 30px;
}

.header .title {
  text-transform: uppercase;
  border-bottom: 1px solid rgb(196, 221, 219);
  font-weight: 500;
  font-size: 50px;
  color: rgb(34, 44, 63);
  margin-bottom: 0px;
}

.header .subtitle {
  margin-top: 5px;
  font-weight: 400;
  color: rgb(34, 44, 63);
}
<header class="header">
    <h1 class="title">timeline</h1>
    <div class="subtitle">History of Popular Social Media Platforms</div>    
</header>

css에서 클래스 선언 부분에 대한 정리를 한번 더 해야겠다.

  • 우선순위를 매기는 방식에 대해서도 기억해야한다.
  • .header .title { ... } 이런 식이면 .header 이하에 있는 모든 .title 를 지칭한다고 볼 수 있다.
  • 만약 .header .title 이 두번 선언되어 있으면? 브라우저에서는 아래쪽 CSS를 적용한다.

타임라인 부분

이제 진짜인 타임라인을 들어간다. 크게 나누자면

  • 점 (시작과 끝점)

  • 아이템

    • 연도
    • 서비스명
    • 설명
    • 사진
    • 기타: 오른쪽, 왼쪽에 번갈아가면서 나온다.

처음으로는 타임라인의 몸체(?)를 만든다.

.history {
  background-color: rgb(33, 43, 62);
  padding: 10px;
}
<div class="history"></div>

다음은 history 내에 점을 구현하도록 한다.

.circle {
  width: 20px;
  height: 20px;
  background-color: rgb(107, 171, 163);
  border-radius: 20px;
  border: 1px solid rgb(107, 171, 163);
  margin: auto;
}
<div class="circle"></div>

위와 같이 구현하면 점이 정 가운데로 간다는 것을 알수 있다. 여기서 주목할 것은

  • Block level element인 div로 설정
  • widthheight를 지정
  • margin; auto 로 지정

했다는 점이다. width, height, margin 의 기본 값이 어떻게 나와있는지 mdn을 통해서 살펴보라.

그다음은 아이템을 구현하도록 한다.

.item {
  width: 50%;
  text-align: right;
  position: relative;
  padding: 10px;
  border-right: 4px solid rgb(107, 171, 163);
  margin-left: -22px;
}
<div class="item"></div>

푸른 동그라미 아래 짧은 선 하나가 그어진 것을 볼 수 있다. 다음은 로고를 구현해본다.

.item .logo {
  display: inline-block;
  vertical-align: top;
  width: 60px;
  height: 60px;
  margin: 15px;
  padding: 5px;
  background-color: white;
  border-radius: 10px;
  text-align: center;
}

.item .logo img {
    margin: 5px;
}
<div class="logo">
    <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/ca/LinkedIn_logo_initials.png/600px-LinkedIn_logo_initials.png" alt="linkedin" width="50" height="50">
</div>

이미지를 적절한 걸 찾아서 다행이다. 중앙에 잘 들어간 것 같아보인다. 그런데 사실 억지로 끼워맞춘 느낌이 들어서 약간 찝찝한 기분이 든다. 강의 때 강사님께 여쭤보아야겠다.

다음은 가지(?)를 만들어본다.

.item .logo .line {
  background-color: rgb(107, 171, 163);
  height: 4px;
  width: 25px;
  position: absolute;
  top: 54px;
  right: 0;
}
<div class="logo">
  <div class="line"></div>
    <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/ca/LinkedIn_logo_initials.png/600px-LinkedIn_logo_initials.png" alt="linkedin" width="50" height="50">
</div>

가지에서는 position을 absolute로 주었다. 사실 더 적절한 방법이 있다면 그 방법을 사용하고 싶다. 그러나 내 역량 부족으로 이렇게 할 수밖에 없었다.

다음은 내용 부분을 구현한다.

        <div class="item">
      <div class="contents">
        <div class="year">2002</div>
        <div class="title">LinkedIn</div>
        <p class="description">
          A Business and employment-oriented social networking service that operates via websites and mobile apps
        </p>
      </div>
      <div class="logo">
        <div class="line"></div>
        <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/ca/LinkedIn_logo_initials.png/600px-LinkedIn_logo_initials.png"
          alt="linkedin" width="50" height="50">
      </div>
    </div>
        .item .contents {
      display: inline-block;
      width: 50%;
    }

    .item .contents .year {
      font-size: 35px;
      color: rgb(226, 87, 68);
      font-weight: bolder;
      margin: -10px 0;
    }

    .item .contents .title {
      font-size: 20px;
      color: rgb(104, 167, 160);
      font-weight: bold;
      margin: 0;
    }

    .item .contents .description {
      margin: 0;
      color: whitesmoke;
    }

.item .logo.item .contents 모두 display: inline-block 으로 주었다. 서로 inline 속성이 있어야 두 엘리먼트가 나란히 있을 수 있기 때문이다.

inline-block은 inline과 block 속성을 모두 가진 속성이라 이해하면 되는건가? 정확히 잘 모르겠다. 아무튼 왼쪽에 배치되는 아이템은 만들 수 있었다.

        <div class="item right">
      <div class="logo">
        <div class="line"></div>
        <img src="https://en.facebookbrand.com/wp-content/uploads/2019/04/f_logo_RGB-Hex-Blue_512.png" alt="facebook"
          width="50" height="50">
      </div>
      <div class="contents">
        <div class="year">2004</div>
        <div class="title">Facebook</div>
        <p class="description">
          An online social media and social networking service based in Menlo Park, California.
        </p>
      </div>
    </div>
.item.right {
  text-align: left;
  margin-left: auto;
  border-right: 0;
  border-left: 4px solid rgb(107, 171, 163);
  margin-right: -22px;
}

.item.right .logo .line {
  left: 0;
}

오른쪽에 배치되는 아이템은 비교적 간단하게 구성할 수 있었다.

여기서 궁금한 부분은 logo 구현 부분의 배치를 다르게 했는데, 다른 방법을 쓸 수 있는지가 궁금하다.

그리고 특징은... margin-left 속성을 auto로 주었다는 점이다. 이것이 없다면 오른쪽 배치된 아이템은 왼쪽에 딱 달라 붙어 있었겠지?

이로서 타임라인 앱을 만들어볼 수 있었다. CSS의 기초를 다잡는 시간으로서 재미있게 할 수 있는 프로젝트였다.

git repo

피드백

잘못된 네거티브 마진
.item {
  width: 50%;
  text-align: right;
  position: relative;
  padding: 10px;
  border-right: 4px solid rgb(107, 171, 163);
  margin-left: -22px;
}

.item.right {
  text-align: left;
  margin-left: auto;
  border-right: 0;
  border-left: 4px solid rgb(107, 171, 163);
  margin-right: -22px;
}

네거티브 마진을 item에 주는 건 좋지는 않다. 나중에 더 정신없어질수 있다. 위 코드에서 네거티브 마진 속성을 지운다. 그러면 border-left, border-right 했던 부분이 어그러지는 것을 볼 수 있다.

여기서 사실 box-sizing: border-box; 속성을 써야한다. 그리고 border-left, border-right 를 쓰는 것보다는 position: absolute; 로 설정을 해준다면 더욱 좋겠다.

여기서 재미있는 걸 하나 배웠는데, 바로 :before 이다.

.history {
  background-color: rgb(33, 43, 62);
  padding: 10px;
  position: relative;
}

.history:before {
  content: ' ';
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  background-color: rgb(107, 171, 163);
  width: 4px;
  margin-left: -2px;
  margin-top: 10px;
  margin-bottom: 10px;
}

가지치기를 위해서 만들었던 line 클래스도 사실은 안티패턴이라고 한다. css의 어떤 외형을 만들기 위해서 이런 식으로 쓰는 건 좋지 않은 방법이다.

.item .logo:after {
  content: ' ';
  background-color: rgb(107, 171, 163);
  height: 4px;
  width: 25px;
  position: absolute;
  top: 54px;
  right: 0;
}

.item .logo .line 에서 .line:after 로 바꾸었다. 그리고 .item.right .logo .line.item .right .logo:after 로 변환해준다.

inline-block 설정된 로고
.item .logo {
  display: inline-block;
  vertical-align: top;
  width: 60px;
  height: 60px;
  margin: 15px;
  padding: 5px;
  background-color: white;
  border-radius: 10px;
  text-align: center;
}

.item .logo img {
    margin: 5px;
}

.logo 클래스를 보면 .item 클래스와 함께 inline-block 처리가 되어있다. 그리고 오른쪽과 왼쪽의 로고 배치된 위치가 다르다. (왼쪽 아이템의 로고는 content 클래스 아래에 있고, 오른쪽 아이템의 로고는 content 클래스 위쪽에 있다.)

맘에 들지 않는다. 특히 이미지 사이즈가 달라진다면 width, height를 60px씩 설정한 것에 대해서는 분명 깨져버릴수밖에 없는 모습이다. 그래서 float을 주도록 한다.

.item .logo {
  vertical-align: top;
  margin: 15px;
  padding: 5px;
  background-color: white;
  border-radius: 10px;
  text-align: center;
  float: right;
}

.item.right .logo {
    float: left;
}

.item .logo img {
  vertical-align: top;
}

이미지도 vertical-align: top; 을 준다. 한결 모습이 나아졌다.

기타
  • .subtitle은 p 태그

  • .circle도 before, after로 소화 가능하게 할 것

  • h1, h3 같은건 한 브라켓 내에 주지 않는다.

    • 보통은 h 하나 주고 다음은 p
Comments