Position: 컨테이닝 블록, 스태킹 컨텍스트의 이해, inset
Position 속성 입문
스태킹 컨텍스트의 이해
inset의 이해
반응형 단위 - 뷰포트 기준에서의 vw, vh
◆ (day11/position/basic)
네거티브 마진은 위치이동은 하는건 맞지만 차지하는 공간이 다르다.
▼ transform (애니메이션 속성 때 주로 사용)
▼position
- static : 초기값
- relative(상대적인)
내위치 기준에서 상대적으로 움직인다. 절대적이아니며 환경에따라 위치가 달라진다
- absolute (절대적인)
속성을 적용하면 ypg텍스트가 사라진걸 볼수있다. 차지하고있는 공간을 버리는것이 핵심
▼다시 left값과 top값을 0으로 적용해보면 요소가 왼쪽 상단에 가는데
현재 내위치에서 이동하는 개념이 아닌 기준점이 절대 기준이된다. 즉 기준점은 전체 창(뷰포트)이다.(body가아님)
▼absolute는 상위 하위 요소 관계, 즉 아빠기준 절대적인 상태에서 상대적인 위치 여야하기에
최초위치가 뷰포트일수밖에없다.
▼만약 할아버지와 아버지 둘다 relative 주어지면 가장 가까운 아버지한테 기준점이 잡힌다.
▼또 한번, 할아버지에게 상대적으로 잡혀있으면 당연히 할아버지에게 기준점이 잡힌다.
이러한 상대적인, 절대적인 적용 순서 개념을 이해해야 한다.
상위에있는 어떤 요소일지라도 컨테이닝 블록으로 교체할 수있는 그런 개념이다.
absolute를 적용한 컨테이닝 블록자체가 상위요소를 찾는다.
찾다가 찾다가 결국 뷰포트 까지 올라간다. 그것이 최초의 컨테이닝 블록이다.
그 상위 요소에 relative가 적용 되어있으면 새로운 컨테이닝 블록이 되는것 !
똑같이 상위요소의 다음 즉 최상위 요소에 relative가 적용되면
마찬가지로 그것이 새로운 컨테이닝 블록이 되는 것이기에
상위 요소를 찾다가 뷰포트에서 기준점이 relative 속성값이 적용된 상위 요소로 적용이 되는 것이다.
이런식으로 내가 원하는 컨테이닝 블록을 지정하여 디자인을 하는것이다.
▼ position을 이용한 중앙정렬 (margin)
▼ position을 이용한 중앙정렬 (transform)
◆ (day12/basic)
▼ pos의 너비를 100px 주었으면 옆에는 가용공간이 생긴다. 다 지우고 pos에 absolute를 적용해보면
▼컨테이닝블록을 버리고 텍스트크기만큼 작아지고 왼쪽 상단에 붙은것 (인라인처럼 보이지면 사실 그렇지 않다)
▼아버지를 컨테이닝 블록으로 지정되어 기준이 아버지로 간것
근데 옆에 해당요소의 빈 공간은 가용 공간이 아니다. 그래서 마진이 적용이 되지않는다.
▲ ▼ right와 bottom 값을 적용해주면 컨테이닝 블록이 제공해주는 공간을 사용할수있게 확보할 수있다
즉 컨테이닝 블록을 모두 활용할 수 있는 좌표값이라고 보면된다.
▼ 너비 높이 각각 100px 주어지면 컨테이닝 블록, 가용공간 최대치 적용 상태에서
너비 높이 고정값을 주면 가용공간이 생긴다.
▼ 마진 값을 자동으로 주면 상하좌우 가용 공간이 생기면서 중앙에 배치된다
가용공간이 존재하기에 작동하는 것이며 당연한 이유이다.
이러한 개념들을 단축속성으로 사용가능하다.
▼ inset = top right bottom left
◆ (day12/circle)
기본적으로 나중에 작성한 마크업이 앞으로 먼저 튀어나온다
곂치는상황에서 원하는 요소를 앞으로 나오고싶게 할경우가 있을것이다.
예를들어 블루 원을 앞으로 나오고싶을경우
position relative 를 적용해야한다.
만약 relative 둘 다 적용할경우 마찬가지로 나중에 작성한 레드원이 먼저나온다
▼또한, 블루원이 앞으로 나오고 싶을땐 이때 z-index를 사용한다
▼z-index는 음수가 가능하다
▲ 음수 값을 적용해보면 파란원이 안보이는데 이 현상은 스태킹 컨텍스트라는 관계 안에서 의미가 있는 값이기 때문에
박스 기준으로 맨~뒤로 이동해버렸기 때문에 보이지 않는 것
(한마디로 1등 레드원, 2등 박스, 3등 파란원 즉 전교꼴찌)
▼ 만약 원 두개만 있고 배경을 지우면 다시 등장한다
▼ 박스 배경까지 등장하게 하려면 z-index값을 0 또는 -1이하 값 으로 적용 (0이 기준값)
▼ z-index
z-index 속성에 대해서 본격적으로 배우기 전에 먼저 z-index가 없을 때
어떻게 요소(element) 간의 상대적 깊이가 결정되는지에 대해서 이해하는 것이 중요하다.
z-index 속성을 너무 많이 사용하면 스타일 유지보수가 힘들어질 수 있기 때문에 될 수 있다면
z-index 속성을 아예 사용하지 않는 편이 낫기 때문이다.
기본적으로 z-index 속성이 적용되지 않은 요소 간에는 HTML 문서 상에서 나중에 나오는 요소가
먼저 나오는 요소보다 위로 올라오도록 되어 있는데,
따라서 다음과 같이 두 개의 원 div 요소가 겹쳐지면, 두 번째 원이 첫 번째 원 위에 올라오게 된다.
하지만 위에서 봤다시피 position 속성이 static이 아닌
relative나 absolute, fixed, sticky인 요소가 나타나기 시작하면 겹치는 순서가 바뀔 수 있는데,
예를 들어, 첫 번째 원의 position 속성을 relative로 바꿔주면, 두 번째 원이 밑으로 내려가는 것을 볼수있다.
또한 두 번째 원의 position 속성도 relative로 바꿔주면 다시 두 번째 상자가 첫 번째 원 위로 올라오게 된다.
정리를 해보면, z-index가 없을 때 요소 간 상대적 깊이는 일반적인 경우에 단독으로 쓸수 없기에
HTML 문서 상에서 요소가 나오는 순서와 각 요소의 position 속성이 static이냐 아니냐에 따라서 결정이 되며
- position 속성이 static이 아닌 요소는 무조건 position 속성이 static인 요소 위로 올라온다.
- position 속성이 static인 요소 간에는 HTML 문서 상에서 나중에 나오는 요소가 먼저 나오는 원소 위로 올라온다.
- position 속성이 relative나 absolute, fixed, sticky인 요소 간에는 HTML 문서 상에서 나중에 나오는 요소가 먼저 나오는 원소 위로 올라온다.
▶ z-index가 작동하지 않는다면 상위요소를 한번 살펴봐야한다.
▼ 스태킹 컨텍스트 (Stacking Context 쌓임 맥락)
기본 레이어링 규칙 이해하기
- HTML 문서 내에서 요소들이 기본적으로 쌓이는 순서
마크업 작성의 순서: 요소들은 HTML 문서의 소스 코드에서 등장하는 순서대로 화면에 표시된다.
즉, 후속 요소는 이전요소 위에 쌓인다.
position: relative가 적용된 요소는 위치 이동을 전제하고 있기 때문에 마크업 작성의 순서와 관계없이
앞으로 나와 보이게 된다.
(일반적인 문서의 흐름내에서, 텍스트나 이미지 콘텐츠는 때때로 background 관련 속성보다 위에 그려짐)
위에서 언급한 기본 레이어링 규칙만으로는 섬세한 쌓임 순서 관리가 어렵기때문에
상황에 따라 특정 요소를 새로운 스태킹 컨텍스트로 만들어 이러한 쌓임 순서를 관리하게 된다.
스택킹 컨텍스트가 된다면?
해당 요소는 기본 레이어링 규칙과 관계없이 앞으로 나옴 (독립적인 쌓임 맥락 형성)
해당 요소 내부의 z-index속성의 기준점이 됨
스택킹 컨텍스트를 생성하는 주요 조건
- position: absolute 또는 relative이고 z-index가 auto가 아닌 경우
- position: fixed 또는 sticky
- Flex Items 중 z-index가 auto가 아닌 경우
- opacity가 1보다 작은 경우
- transform 속성이 none이 아닌 경우
See the Pen z-index 삼매경 by VEAMCAMP (@veamcamp) on CodePen.
◆ (day12/happycode)
▼ 텍스트 밑에 밑줄을 긋고 싶을경우 가상요소를 사용한다
▼ position 속성을 사용하여 밋줄 긋기
▼ 뷰포트 기준으로 배치 되므로 부모에게 relative적용
▼ h1에게도 스태킹 컨텍스트 적용하기위해 z-index 초기값을 지정
▼ position을 사용하여 아이콘이나 특정요소등 을 추가해 위치 조정을 할 수있다.
◆ (day12/pixar)
<!DOCTYPE html>
<html>
<head>
<title>Responsive Pixar</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Caveat&family=Montserrat:wght@500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="contents">
<div class="l_wrapper">
<div class="container">
<div class="container-sidebar">
<a class="logo" href="#cover"></a>
<ul class="menu">
<li><a href="#about">ABOUT</a></li>
<li><a href="#works">WORKS</a></li>
<li><a href="#contact">CONTACT</a></li>
</ul>
</div>
<div class="container-main">
<section class="section" id="about">
<h2 class="section-title">About</h2>
<div class="description">
<div class="description-contents">
<h3>Pixar Animation Studio</h3>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel</p>
</div>
<img class="description-cover" src="images/about.png">
</div>
</section>
<section class="section" id="works">
<h2 class="section-title">Works</h2>
<ul class="grid">
<li class="movie movie_brown">
<img class="movie-cover" src="images/pixar03.png">
<h2>Cars</h2>
<p>commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam </p>
</li>
<li class="movie movie_orange">
<img class="movie-cover" src="images/pixar04.png">
<h2>Brave</h2>
<p>commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam </p>
</li>
<li class="movie movie_purple">
<img class="movie-cover" src="images/pixar05.png">
<h2>Wall_E</h2>
<p>commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam </p>
</li>
<li class="movie movie_orange">
<img class="movie-cover" src="images/pixar06.png">
<h2>Ratatouille</h2>
<p>commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam </p>
</li>
<li class="movie movie_white">
<img class="movie-cover" src="images/pixar07.png">
<h2>Monster Inc</h2>
<p>commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam </p>
</li>
<li class="movie movie_blue">
<img class="movie-cover" src="images/pixar08.png">
<h2>Finding Nemo</h2>
<p>commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam </p>
</li>
<li class="movie movie_orange">
<img class="movie-cover" src="images/pixar09.png">
<h2>ToyStory</h2>
<p>commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam </p>
</li>
<li class="movie movie_green">
<img class="movie-cover" src="images/pixar10.png">
<h2>A Bugs Life</h2>
<p>commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam </p>
</li>
</ul>
</section>
<section class="section" id="contact">
<h2 class="section-title">Contact</h2>
<div class="description">
<div class="description-contents">
<h3>Contact us</h3>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel</p>
</div>
</div>
</section>
</div>
</div>
</div>
</div>
<div class="footer">
<div class="l_wrapper">
Copyright by GL HTML
</div>
</div>
</body>
</html>
/* Reset */
body, ul, p {
margin: unset;
padding: unset;
}
li {
list-style-type: none;
}
a {
color: unset;
text-decoration: unset;
}
h1, h2, h3, h4, h5, h6 {
margin: unset;
font-weight: unset;
}
/* Typography */
:root {
font-family: 'Montserrat', sans-serif;
}
/* Layouts */
.l_wrapper {
max-width: 1140px;
padding: 0 30px;
margin: 0 auto;
position: relative;
}
/* Components */
body {
background-color: #000;
color: #888;
}
.menu {
font-size: 20px;
margin: 20px 0;
}
.menu li a {
display: block;
padding: 4px 18px;
}
.grid {
display: grid;
grid-template-columns: repeat( auto-fit, minmax( 200px, 1fr) );
gap: 20px;
}
.contents {
padding: 60px 0;
}
.movie {
border-radius: 10px;
background-color: #111;
overflow: hidden;
height: 100%;
}
.movie_red { color: #b92f19; }
.movie_blue { color: #336699; }
.movie_brown { color: #c67722; }
.movie_orange { color: #e4512e; }
.movie_purple { color: #8711d2; }
.movie_green { color: #75d211; }
.movie_white { color: #ddd; }
.movie-cover {
max-width: 100%;
height: auto;
border-bottom: 5px solid currentColor;
vertical_align: top;
}
.movie h2 {
font-weight: bold;
margin: 12px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.movie p {
line-height: 1.3;
margin: 12px;
color: #444;
}
.container {
display: flex;
}
.container-sidebar {
width: 200px;
}
.container-main {
flex-basis: 0;
flex-grow: 1;
min-width: 0;
}
.logo {
width: 200px;
height: 220px;
display: block;
background-image: url(images/logo.png);
background-size: cover;
transition: all .4s;
}
.logo:hover {
background-image: url(images/logo-hover.png);
}
.section {
margin-bottom: 40px;
}
.section-title {
font-family: 'Caveat', cursive;
padding: 40px 0 30px;
font-size: 30px;
color: white;
}
.description {
display: flex;
gap: 40px;
}
.description-contents {
flex-grow: 1;
flex-basis: 0;
min-width: 0;
}
.description-cover {
width: 320px;
}
.description h3 {
color: salmon;
margin-bottom: 20px;
}
.footer {
border-top: 1px solid #555;
padding: 30px 0;
font-size: 1rem;
}
▼ 커버스타일링 시작
창크기에 맞춰서 조절되는 작업을 하기위해
전체 뷰포트에 꽉채우게 끔 먼저 높이를 %보단 vh단위를 사용한다.
%는 상위요소의 %이기때문에 body의 높이를 받아오기 때문에
body의 높이는 auto이며 앞뒤가 맞지않아적용이 되지 않는다.
결론은 height 100%는 부모의 높이 기준이기에 부모의 높이는 auto이므로 적용안됨.
▼height vw를 사용하면 높이를 너비 기준으로 잡겠다는 뜻이다.
반응형이 알아서 작동되게 비율이 잡힘
vh이나 vw는 패딩이나 폰트크기등등.. px 대신 사용할 수있는 단위들이다(그대신 화면 난리날듯)
▼ aspect-ratio 사용하여 부모 너비 기준으로 잡히기 때문에 좀더 효율적으로 비율이 유지된다.
▼ 하지만 큰 컨텐츠가 들어가면 min height 처럼 유연하게 늘어난다 (느슨하게)
그렇기에 기본 스타일 초기화해준다.
▼이미지가 맥시멈으로 커질수있는 기준을 제한을 걸기위해 이미지 기본 스타일 초기화
▼ 두 요소들이 공간을 차지하고 있는건 맞지만 이미지와 h1을 곂치게 해야하기위해 position absolute는 이미지에 준다
현재 마크업으로 잡혀있는데 배경이미지 처럼 연출하게 하기위하기에
이미지가 body를 차지하지 않는다라고 잡기위함이다.
▼이미지가 넘쳐 흐르므로 커버에 hidden을 적용
▼ 하지만 두가지 문제가 있다 이미지가 짤려나오고 h1이 보이지않는다.
h1을 보여주고 이미지를 맨 뒤로 보내기위해 z-index를 사용한다.
▼ object fit (참고서- https://www.daleseo.com/css-object-fit/ )
이미지가 짤려나오는걸 해결하기위해 우선 이미지의 크기를 전부다 나오게 하기위해
너비와 높이를 %값으로 주고 object-fit이라는 속성을 사용한다.
이미지랑 비디오를 한번에 object라고 부르며 이것에 대한 fit. 즉 딱 맞게 들어간다는것
이미지를 마크업으로 작업했기 때문에 object fit을 사용한것일뿐 background-size cover 랑 동일하다.
이 기법을 언제쓰냐면 업로드 페이지같은 곳에서 사용자가 이미지 업로드를 할때 다양한 사이즈로 업로드를 한다.
페이지에 출력되려면 업로드된 이미지 크기를 그대로 업로드 해버리면 수많은 업로더가 올린 이미지들의
비율 자체도 다르고 레이아웃이 깨지기때문에 cover 즉 object fit을를 적용하여 억지로 줄인다(?) 라고 보면될듯하다.
결론은 css 기법을 이용하여 background-image를 연출하게 적용 한것 (실제는 마크업)
▼ h1을 중앙 하단 배치하기위해 cover에 flex를 적용해본다.
▼ 그라디언트 적용위해 가상요소 사용
▼ absolute로 적용한상태에서 opacity로 반투명 적용
▼ z-index는 이미지가 맨뒤로 가야하고 커버가 이미지보다 앞으로 있어야 하기 때문에 -1 음수 값으로 하고
css gradient 페이지를 사용하여 코드레벨로 직접 설정하기보단 외부 도움(?)으로 적용해준다.
https://www.colorzilla.com/gradient-editor/
▼ vw 단위를 h1에 넣어서 반응형에 맞춰 적용 되게끔 설정하고 글 사이 간격등 스타일 적용
▼ ID 셀렉터를 이용하여 메뉴바에 위치이동 기능을 만들수있다.
▼ 화면이 스크롤 되어도 메뉴가 항상 따라다닐 수있게 고정시킨다.
RESULT
'BootCamp Review' 카테고리의 다른 글
2024.08.19 (Day 14) - HTML/CSS [grid 그리드 레이아웃 I] (0) | 2024.08.20 |
---|---|
2024.08.15,19 (Day 13~14) - HTML/CSS [INCREDIBLE] (0) | 2024.08.19 |
2024.08.12 (Day 10) - HTML/CSS [Flexbox III] (0) | 2024.08.18 |
2024.08.08 (Day 9) - HTML/CSS [Flexbox II] (0) | 2024.08.18 |
2024.08.07 - Figma(특강) (0) | 2024.08.18 |