HTML과 CSS 빵부스거리

이효범·2022년 4월 24일
0

빵부스러기

목록 보기
2/3
post-thumbnail

개발하며 알게되는 빵부스러기를 기록한다. 빵부스러기 시리즈는 새롭게 알게되는 빵이 있을 때마다 최신화하도록 한다.


트랜지션과 합이 안좋은 친구들

width, height, padding, margin, (border), top, right, left, bottom
그리고 display는 아예 안먹는다.


block요소와 inline 요소

block 요소한테 별도의 width값을 주지 않으면 기본성질은 부모의 width의 100%를 차지한다.
Inline-block 같은 경우는 별도로 width안주면
자신이 갖고 있는 자식의 contents의 사이즈 만큼만을 기준으로 width를 가진다.


height

height는 따로 값을 명시하지 않으면 자신이 갖고 있는 자식의 heigth 값들의 합을 기준으로 자신의 heigth를 설정하게 된다 (하지만 불안정한 heigth는 css가 처리해주지않는다).
그런데 만약 요소에게 height 40px로 줬는데 border 또한 1px 주면 border-box일 시 요소가 터져나가는 경우가 발생한다.
이럴 경우 overflow : visible을 이용해서 터져나가는걸 잘 감싸주는 트릭을 사용할 수 있다.

하나 더 참고할 것은 width의 기준점과 heigth의 기준점이 완전히 다르다는 것이다.
width는 부모의 width, heigth는 부모의 height 값을 기준으로 서로 다른 기준점이 설정된다.


WAI_ARIA

aria-lebel 은 마크업 상으로는 별도로 텍스트를 제공하지않지만 그래도 스크린리더로써 반드시 제공이 되면 좋을 그런 텍스트 정보들을 적을 때 사용한다.

aria-hidden은 정보로써 아무런 가치가 없는 애들에게 ‘얘네 그냥 무시해’ 라는 맥락을 전달하기 위해 사용한다.

role 이라는 녀석도 이와 비슷한 맥락인데, 말 그대로 역할이라는 뜻을 가진것처럼
html 마크업 만으로는 표현하기 어려운 태그들간의 관계와 "이 태그는 사실 이런 역할을 해~" 라는 뉘앙스를 좀 더 직접적으로 전달하기 위한 도구라고 이해하면 편하다.

role 에 사용할 수 있는 자식들은 정해져 있다.

하지만 그렇다고 해서 그냥 단순히

을 사용하면되는 것을 갖다가

이런 식으로 사용을 하는 것은 권장하지 않는다. 하지만 우리가 개발을 하다 보면 아티클을 아티클이라고 마크업 할 수 없는 상황이 벌어질 수 있기 때문에 위와 같은 방식으로도 사용할 수 있다는 것은 기억해두자!

role=“region” 는 지금 우리가 만들려고 하는게 캐러셀인데, 캐러셀은 전체 페이지 내용에서도 중요한 컨텐츠의 역할을한다. 즉 일종의 랜드마크라고 생각하면 편하다.
그래서 “야 이거 좀 중요한거야”라는 뉘앙스를 주려고 할 때 쓴다.
즉, 랜드마크인 컨텐츠라는 것을 표현을 할 때 주로 사용하며 이를 통해서 스크린리더가 이 요소를 굉장히 쉽게 접근을 할 수 있다.

role=“tablist” 밑 이미지에서 왼쪽 4개 사진이 탭리스트
role=“tab” 탭리스트 안의 아이템이 tab 이다.
role=“tabpannel” 중앙의 큰 사진이 탭패널이다.

그래서 tablisttabpannel의 관계를 서로 묶어줄 수 있다.
html 태그로만 하기에는 서로간의 긴밀한 관계를 명시해주기 어려운데 반해,
왼쪽의 탭리스트도 ol 태그를 쓰고 중앙의 탭패널도 그냥 같은 ol태그이지만
두 ol태그에 속성값으로 tablist, tabpannel 을 적어주면
서로간의 긴밀함을 명시해주는 역할을 한다.

추가적으로 더욱 긴밀한 연결을 위해서는 tab 친구들에게 다음과 같이 개별적으로 id 를 넣어주고 id="product-carousel-tab-1”,
tabpannel 에게는 aria-labelledby="product-carousel-tab-1”
와 같이 넣어주면 된다.
이렇게 해주면 시맨틱한 연결고리 완성이다(약간 라벨과 인풋의 관계랑 비슷하다).


Key-Value 태그

키와 발루 형태의 정보는 <dl> 태그를 이용하자.
또한 <output> 이라는 태그도 있다는 것을 기억하도록 하자.
이 태그는 우리가 select나 input에 대한 결과값으로 나오는 정보를 마크업할때 사용한다.
그래서 for 속성이 존재하는데
for=””select-1 select-2” 이런 식으로 속성값 넣어줘서 어떤 셀렉트, 어떤 인풋에 대한 결과값인지 바인딩해줄 수 있다.
그리고 이에 대응하도록 select-1, select-2 는 해당 셀렉트 태그의 id값으로 넣어주면된다 , 즉 라벨링 해주는 것이다.


테이블

테이블은 안에 세 개의 태그가 들어올 수 있다.

  • thead
  • tbody
  • tfoot

<thead> 같은 경우는 말 그대로 테이블의 헤더같은 역할을 해준다.
<tbody> 에는 데이터들을 담는, 일종의 테이블들의 본론이다.
<tfoot> 같은 경우에는 테이블에 결과값들이 있을 수 있는데, 가령 견적서 같은 경우에는 합계라고 하는 결과값이 포함되어야 하는데, 이런 친구들을 마크업하기 위한 태그라고 보면 된다.

물론 경우에 따라서 tbody만 사용하는 경우도 있다.

tr 이 있고 th, td 가 있다.
rrow 를 의미하고
h 는 테이블 안에서의 heading,
ddata 를 의미한다.

위와 같은 테이블은 다음과 같이 마크업을 할 수 있다.

<table>
  <tbody>
    <tr>
      <th scope="row">품명 및 모델명</th>
      <td>VO-HT015</td>
    </tr>
  </tbody>
</table>  

그리고 맨위의 <table> 태그에게는 일반적으로 다음과 같은 css 속성을 준다.

border-collapse: collapse;
table-layout: fixed; 

또한 vertical-align css 속성은 테이블에서만 사용하는것을 권장한다.


마진으로 요소의 너비 넓히기

별도의 width값을 안주고
양쪽에 마이너스 마진을 주면 그만큼 크기가 늘어난다.


fixed on scroll

=> position : sticky 를 사용하자.


Inline 요소 특

inline 한테는 트랜스폼을 쓸 수 없다. 그리고 마진 탑 바텀, 패딩 탑 바텀이 안먹는다.
따라서 이를 방지하기 위해 inline-block 주면 된다.


img태그와 figure 태그의 상관관계

이미지태그를 쓸 때 <figure> 태그를 쓰자.
<figcaption class="visually-hidden"> 태그는 <img> 태그의 alt 대용으로 넣어주면 된다.


wrapper vs group

그룹은 동일하게 생긴 요소들이 반복될 때 그룹핑 을 한다고 주로 말을 하고
wrapper 같은 경우는 레이아웃의 목적으로 자식 요소를 감쌀 때 쓰는 경향이 있다.


이미지 진정시키기

img ... 부모보다 절대 더 넘쳐흐르지 마라.. 진정해라...!
코드는 다음과 같다.

img {
  display: block;
  width: 100%;
  height: auto;
}

가상 요소

가상 요소는 기본적으로 displayinline 을 가진다.


order 속성

flexbox 에도 order 속성이 있다. 근데 그리드에서의 order 랑은 완전 다른 기능이라고 보면 된다. flexbox 에서 order 속성은 요소의 배치를 수직적이나 수평적으로 할 때 사용한다.


아티클 태그

<article> 태그는 섹셔닝 일레멘트의 하나로써, 섹션 태그와 되게 비슷하지만,
약간의 차이점은,
아티클 태그로 감싸는 내용자체가 일종의 완결성이 있어야하고
(즉 하나의 콘텐츠로써 기승전결이 있는 완결성이 있어야한다),

그래서 헤딩 태그를 반드시 가지는 것이 좋다 (가령 <h2><h3> 태그같은).
다만 이런 헤딩 태그 녀석들은 visually-hidden 클래스를 줘서 디자인상으로는 안보이게 해줘도 좋다.

섹션 태그는 몇 개의 콘텐츠를 묶는 용도로 사용하고, 아티클 태그는 오로지 독립된 콘텐츠를 위해 쓴다고 생각하면 편하다.

time 태그

시간 정보에 대한 데이터를 다룰 때에는 <time> 태그를 사용하자.

그러면 브라우저가 태그가 감싸고 있는 정보가 시간에 대한 정보구나 하고 알 수 있다.

근데 좀 더 정확하게 전달하기위해서 datetime 이라는 속성을 꼭 줘야한다.
속성값으로 똑같이 시간에 대한 정보를 주면 된다.

<div class="misc">
  <time datetime="2021-01-01"> 2021.01.01 </time>
	<span>오늘의집 구매</span>
</div>

// 혹은 다음과 같이 사용하면 된다.
<time datetime="2021-01-02 21:41">
	2021122141</time>  

이에 대한 자세한 정보는 HTML time 를 참고한다.


사각형안에 이미지 깔끔하게 넣기

깔끔하게 고정된 높이 길이 값으로 이미지 넣어주는 방법이다.

.review-image {
    width: 64px;
    height: 64px;
    margin-bottom: 8px;
    overflow: hidden;
    border-radius: 4px;

    img {
      display: block;
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
}

heightauto가 아닌 100% 를 준것은 들어오는 이미지 사이즈가 정사각형만 들어올 것이 아니기 때문이다. 따라서 모든 케이스를 커버하기 위해서는 height100% 를 주고 object-fit: cover 를 꼭 줘야한다.


가상 클래스 활용

다음은 재밌는 가상 클래스처럼 보이지만, 실제로 사용하게 되는 경우가 은근히 많다.

&:first-child:not(:last-child)

클래스 붙여쓰는게 무슨 뜻이었는지 까먹었을 때 보자


.product-section-header.sm-only {  // product-section-header 이면서
//  sm-only 라고 하는 클래스를 가지고 있는 녀석아 꺼져라!
    display: none;
}

가상 클래스의 우선순위

가상클래스를 부여하면 우선순위가 높아진다. 따라서 만약 가상 요소를 반응형 사이즈에 따라 해제하려고하면 !important 를 붙여주면된다.

예시는 다음과 같다.

.product-item {
    width: calc(50% - 10px); // (100% - 20px) / 2

    &:nth-child(1),
    &:nth-child(2) {
      margin-bottom: 20px;
    }

//... 생략

}

@include responsive(T) { // Desktop 사이즈부터는 다음과 같이 스타일링해준다.
    .product-item {
      width: calc(33.333% - 11px); // (100% - 32px) / 3
      margin-bottom: 0 !important;   // 이렇게 !important 때려버리자.

      &:last-child {
        display: none;
      }
    }
}  

position: absolute

어떤 요소를 별도의 width 값을 설정해주지 않은 상태에서
absolute를 시키면 얘는 자기가 갖고있는 콘텐츠의 사이즈만큼만 슈욱 다이어트를 한다.
그래서 "그러지 말아라(다이어트 하지 마라)."하고 width100% 로 챙겨주자.
그러면 relative 한 애의 width 만큼 잘 먹는다.


flex-shrink & flex-grow

flex-shrink : 0 하면 플렉스 박스 내에서 절대 사이즈가 안줄어든다.
즉, 무조건 자기 사이즈를 지킨다. 이를 통해 안전하게 요소가 찌그러지는걸 막을 수 있다.

약간 이런 느낌이라고 생각하면 편하다.
“걍 좀 공간이 남으면 넌 좀 늘어나라~” 하면 (공간이 비는대로 넉넉~하게 쫙 지가 늘어남)
flex-grow: 1;,
반대로 “야 넌 줄어드는거 절대 있을 수 없다~” 하면
flex-shirink: 0; 를 사용해준다.


반응형 이미지 종횡비 맞추기

&-image {
  margin-bottom: 8px;
  overflow: hidden;
  border-radius: 4px;
  
  img {
    dispaly: block;
    width: 100%;
    height: auto;
    transition: transform 200ms ease-in-out;
  }
}

위와 같이 이미지의 구조를 잡을 시, 다음과 같은 레이아웃

제각각인 이미지의 height 때문에 카드의 사이즈 또한 제각각이다.
물론 width: 100% 주고 height: auto 로 줬기 때문에 당연한 결과이다.

만약 이미지의 사이즈를 딱 정사각형으로만 맞춰야하는 상황이라면 어떻게 css를 설정해줄 수 있을까?

우선 object-fit: cover 를 사용하면 어떨까하는 생각이 먼저 든다.
object-fit 은 다음과 같다.
이미지를 감싸고 있는 컨테이너에 widthheight 값을 fix 해주고
그리고 imgwidthheigth 에게 100% 주고 object-fit: cover 를 사용해주는 방식이다.

하지만 만약 컨테이너의 width가 가변적인 상황이라면 어떨까? 이럴 때는 마음처럼 object-fit 이 잘 먹지 않게 된다.

우리는 현재 heightwidth 가 1:1 비율이어야 할 경우를 얘기하고 있다.
즉, 우리가 원하는 것은 이 heigth 의 길이가 width 의 길이랑 동일하게, width 가 커지면 그에 비례해서 height 의 길이도 늘어나길 바란다.
그런데 widthheigth 의 기준점이 완전히 다르니 height 한테 퍼센트를 줘서는 우리가 원하는 그 효과를 절대 낼 수가 없다는 것이 문제인 것이다.

이를 해결하기 위해서는 다른 방법을 쓸 수 있는데, 바로 패딩 혹은 마진을 이용하는 방법이다.

다음과 같이 css 를 설정해주면 우리가 원하는 목적을 달성할 수 있다.

&-image {
    position: relative;
    width: 100%;
    height: 0;
    padding-bottom: 100%;   // 패딩을 주는방법
    margin-bottom: 8px;
    overflow: hidden;
    border-radius: 4px;

    img {
      @include pos-center;
      display: block;
      width: 100%;
      height: 100%;
      transition: transform 200ms ease-in-out;
      object-fit: cover;
    }
  }

이에 대한 원리는 다음 그림을 보면서 이해해보자.

위처럼 패딩을 100%로 주니까 width 사이즈랑 동일한 크기인 135가 늘어난 걸 볼 수 있다(마진을 줘도 동일하다).
이건 css가 그냥 이렇게 동작하는 것인데, 딱히 이해할 필요도 없다.

그래도 원리를 알자면 패딩이나 마진은 width 가 사용하는 기준점을 갖다 쓰기 때문이다.

정리해보자, widthheight 는 서로간의 기준점이 다르다.
그래서 height 에 퍼센트 값을 줘서는 우리가 원하는 레이아웃을 잡을 수 없다.
하지만 width 와 패딩 및 마진은 퍼센트의 기준점이 같다.

그래서 우리가 어떤 요소의 종횡비를 유지하고싶다면 오히려 heigth 한테는 0 을 주고
우리가 원하는 비율만큼 패딩이나 마진을 주면 된다.

그리고 자식 요소인 이미지에게는 포지션 센터 속성을 주고 컨테이너 한테는 포지션 릴레이티브 속성을 준다.
그럼 아주 잘 맞게 이미지가 들어간다.

결국 위의 방식을 사용하면 이미지의 원래 사이즈가 어떻든간에 딱 맞게 정사각형으로 잘 나오게 된다.

두 번째로 생각해볼 수 있는 것은 aspect-radio: 1 / 1 이 생각난다.
이에 대해서는 밑에서 따로 다루도록 한다.


profile
I'm on Wave, I'm on the Vibe.

0개의 댓글