CSS flex와 selector
1. 레이아웃
Atomic CSS 방법론
1:1로 클래스 이름과 구현을 일치시켜 아주 작은 단위로 CSS를 작성하는 기법
맨 처음 레이아웃을 리셋해주어야 한다
body태그의 default 여백, 브라우저마다의 차이(글꼴, 여백 등)가 있으므로!
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
}
2. flex
- 부모 요소에
display: flex;
, 자식 요소에flex: grow, shrink, basis
적용 - 위 설정이 된 경우, 자식 요소는 왼쪽부터 차례대로 배치된다.
flex-direction
: row(default), column;flex(default)
:0 1 auto;
❗️flex
하위 속성
flex : grow(팽창 지수) shrink(수축 지수) basis(기본 크기)
grow, shrink는 단위가 없고 비율에 따라 달라지는 값이다.
1. grow
예를 들어 grow === 1
이라면,
n개의 자식요소가 있고 grow의 총 합이 n일 때, 길이 1/n
을 적용한다.
.box {
flex: 1 1 auto;
}
/*
* 자식 박스가 총 세개인데, target만 2의 비율을 가집니다.
* 2(target) + 1(box2) + 1(box3) = 4 이므로,
* target의 비율은 50% 입니다.
*/
.target {
flex: 2 1 auto;
}
위의 경우를 예시로 확인해보자.
display: flex
가 적용된 부모요소인 outer가 있고, flex-grow
가 각각 1, 2로 적용된 자식요소인 box과 target이 있다.
총 grow의 합은 1*2 + 2 = 4인데, box는 1/4씩 차지하고 target은 2/4를 차지하는 것을 확인할 수 있다.
만약 모든 자식 박스의 flex-grow 속성이 0보다 큰 값을 동일하게 가진다면, 가로 길이는 모두 동일하다. (그 값이 무엇이든 상관없이!)
만약 임의의 A 박스를 제외한 모든 박스가 flex-grow를 0으로 가지면 A박스는 이 외 박스가 찌부된 상태(가로 길이가 없는 상태)로 나머지 영역을 모두 차지하게 된다.
2. shrink
웬만하면 기본값으로 사용하자! grow만으로 비율을 변경할 수 있을 뿐더러, 실제 크기를 예측하기 힘들어진다!
3. basis
grow 속성이 0일 때 고정되는 크기!
c.f. 레이아웃이 내맘대로 안될 때 참고하자
- width와 flex-basis를 동시에 적용하는 경우, flex-basis가 우선
- 콘텐츠가 많아 자식 박스가 넘치는 경우, width는 정확한 크기를 보장하지 않는다.
- (flex-basis를 사용하지 않는다면) 콘텐츠가 많아 자식 박스가 넘치는 경우를 대비해, width 대신 max-width를 써보자.
3. 정렬
- main axis(flex-direction), cross axis(main과 수직되는 방향)
Justify-content
- main axis 기준, 일반적으로 수평 정렬
- 수평으로 정렬하고자 하는 박스의 부모 박스에 적용해야한다!
- 속성값 옵션
flex-start
,flex-end
,center
,space-between
align-items
- main axis 기준, 일반적으로 수직 정렬
- 수평으로 정렬하고자 하는 박스의 부모 박스에 적용해야한다!
- 속성값 옵션
flex-start
,flex-end
,center
,stretch
4. Selector
*
전체 선택자 : 모든 요소를 낱개로 전부 선택한다
.A#B
A 클래스이면서 B id를 가진 요소
태그[id='이름']
속성 선택자 : 이름
을 id로 가지고 있는 태그
태그[속성]
속성 선택자 : 속성
을 가지고 있는 태그
A B
하위 선택자 : A의 하위에 있는 모든 B
A > B
자식 선택자 : A의 자식요소 중 B
A + B
형제 선택자 : A에 인접한 다음 형제요소인 B
A ~ B
형제 선택자 : A에 인접한 앞, 뒤 형제요소인 B
A:first-child
: A의 첫번째 자식요소
A > B:last-child
: A의 자식요소인 B 중 마지막 요소
A > B:nth-child(3)
: A의 자식요소인 B 중 세번째 요소
A:first-of-type
: A 요소 중 형제끼리 비교해 가장 첫번째 A 요소 (하나라면 그 요소)
A:last-of-type
: A 요소 중 형제끼리 비교해 가장 마지막 A 요소 (하나라면 그 요소)
A:nth-of-type
: A 요소 중 두번째 A 요소(하나라면 두번째가 아니니 X)
A:not(#이름)
: A 요소 중에 이름
을 id로 가지고 있는 태그를 제외하고 나머지
용어 정리
- 와이어프레임 : 화면 단위의 레이아웃 설계하는 작업
- 목업 : 실제품을 만들어보기 전, 실물과 비슷하게 시제품을 제작하는 작업 (기능은 없지만 외형정도)
- 프로토타입 : 처음부터 종료까지 핵심 동작이 가능하게 구현된 데모버전
- 하드 코딩 : 서버에서 데이터를 불러오지 않고 데이터를 코드 내부에 직접 입력하는 것
만들어보자
HTML 코드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>VScode</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="container">
<div class="col w10">
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
</div>
<div class="col w20">
<div class="row h40"></div>
<div class="row h40"></div>
<div class="row h20"></div>
</div>
<div class="col w70">
<div class="row h80"></div>
<div class="row h20"></div>
</div>
</div>
</body>
</html>
CSS 코드
*{
box-sizing: border-box;
}
body{
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container{
display: flex;
background-color: whitesmoke;
width: 70vw;
min-height: 80vh;
border: 1px solid blue;
padding: 0.4rem;
font-size: 0.8rem;
column-gap: 0.4rem;
}
.col{
display: flex;
flex-direction: column;
border: 1px solid red;
padding: 0.6rem;
row-gap: 0.4rem;
}
.w10{
flex: 1 0 0;
}
.w20{
flex: 2 0 0;
}
.w70{
flex: 7 0 0;
}
.icon{
border: 1px dotted red;
}
.icon::after{
content: "";
display: block;
padding-bottom: 100%;
}
.row{
border: 1px dotted blue;
/* margin: 1rem; */
}
.h80{
flex: 8 0 0;
}
.h40{
flex: 4 0 0;
}
.h20{
flex: 2 0 0;
}
화면의 중간에 배치하기
.container
를 화면 중간에 배치하기 위해서, 부모인 body에 아래 코드를 추가하였다.
justify-content: center;
align-items: center;
height: 100vh;
세로로 배열하기
각 .col
내에 .row
영역들을 세로로 배열하기 위해서 .col
에 아래 코드를 추가하였다. (display: flex;
는 당연히!)
flex-direction: column;
정사각형 반응형으로 만들기
.icon
이 화면의 가로만 줄어들더라도 정사각형 모양을 유지하기 위해서는 vw, %와 같이 부모 요소의 크기에 영향을 받는 단위는 사용할 수 없었다.
가상요소 ::after
를 사용하여 아래 코드를 추가하였다.
.icon::after{
content: "";
display: block;
padding-bottom: 100%;
}
❗️가상요소란, 실제로 html상에서는 없지만 가짜로 하나를 만들어주는 것이다.
내용은 없지만 (content: "";
) block 요소로 만들어 부모 요소로부터 주어진 width
만큼 세로 길이를 padding
으로 더해주는 방식이다.
이때 padding-bottom 은 padding-top 으로 변경해도 무방하다. 어쨌든 나 자신의 안쪽 위로 여백을 늘릴 것인지, 안쪽 아래로 여백을 늘릴 것인지의 차이이기 때문이다.
.icon::after
가 없을 때 컨텐츠가 없는 div
태그는 height
이 없으므로 아래와 같이 나타난다.
결국 영역을 만드는 것은 .icon::after
이기 때문에 박스 내에 컨텐츠가 없다면 .icon
은 없어도 무방하다. 하지만 컨텐츠가 있다면 아래와 같이 영역이 구성된다.
내용이 있을 때 내용을 정사각형 중간에 유지하면서 박스 자체도 정사각형을 유지할 수 있는 방법이 무엇일지 주말에 고민해보아야겠다.
width와 height을 연결하는 엄청난 아이디어라고 생각했다. 동시에, 오늘 스프린트 리뷰에서 'CSS는 정답이 없다'는 코치님의 말도 기억이 났다.
박스 사이에 간격 할당하기
space-between
을 써야하나, flex
로 박스의 길이가 이미 지정되어있는데 어떻게 여백을 만들어야하지 고민했는데 아주 간단한 방법이 있었다.
column-gap: 0.4rem;
row-gap: 0.4rem;
justify-content
나 align-items
처럼 부모요소에 지정해주면 된다.
Author And Source
이 문제에 관하여(CSS flex와 selector), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@titaniumdiana/CSS-seletor와-flex저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)