whatisthis?
CSS - Background practice (AirBnB card) 본문
Background practice (에어비앤비)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Background</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=Poppins:wght@400;500&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<article class="card">
<div class="card-image">
<button
type="button"
class="like-button"
aria-label="Like this property"
></button>
<!-- <img/> 대신 background-image를 활용해서 스타일 해보세요! -->
<!-- <img src="./assets/img-house.jpg" alt="Seoul AirBnB, hosted by Woohyeon Roh" /> -->
</div>
<div class="card-content">
<header class="card-header">
<div class="property-type">
<strong class="plus-badge">Plus</strong>
<span>Entire apartment</span>
</div>
<div class="property-rate">
<strong aria-label="Review: 4.97"> 4.97 </strong>
<span aria-label="Total 203 reviews">(203)</span>
</div>
</header>
<h1 class="card-title">Unwind in a Bright Space with Rustic Accents</h1>
<div class="card-detail">
<dl class="property-detail">
<div>
<dt class="sr-only">Rooms and beds</dt>
<dd>
<span>2 guests</span>
<span>1 bedroom</span>
<span>1 bed</span>
<span>1 bath</span>
</dd>
</div>
<div>
<dt class="sr-only">Amenities</dt>
<dd>
<span>Wifi</span>
<span>Kitchen</span>
</dd>
</div>
</dl>
</div>
</div>
</article>
</body>
</html>
style.css
.like-button {
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
}
/* ▼ WHERE YOUR CODE BEGINS */
* {
box-sizing: border-box;
margin: 0;
}
body {
font-family: "Poppins", sans-serif;
}
.sr-only {
display: none;
}
.card-image {
/* display: flex;
justify-content: center;
align-content: center;
overflow: hidden; */
width: 300px;
height: 200px;
background-image: url("./assets/img-house.jpg");
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
border-radius: 6px;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.plus-badge {
display: inline-block;
padding: 1px 8px;
border-radius: 4px;
margin-right: 6px;
font-size: 14px;
font-weight: 500;
line-height: 1.428571428571429;
color: #fff;
background-color: #92174d;
text-transform: uppercase;
}
.property-type span {
font-style: 16px;
line-height: 1.25;
color: #7d858f;
}
.property-rate {
font-style: 16px;
line-height: 1.25;
}
.property-rate strong {
color: #151b26;
font-weight: 400;
}
.property-rate span {
color: #7d858f;
}
.property-rate::before {
content: "";
position: relative;
top: 2px;
display: inline-block;
width: 16px;
height: 16px;
background-image: url("./assets/icon-star.svg");
background-repeat: no-repeat;
background-position: center center;
background-size: contain;
}
.card-title {
margin-bottom: 16px;
font-size: 20px;
line-height: 1.6;
font-weight: 400;
color: #151826;
}
key points
- 이미지가 세로로 길수도 있고, 가로로 길수도 있으므로
이것을 만약 img 태그로 마크업한다면
세로로 길면 width: 100% height: auto 해줘야하고
가로로 길면 height: 100% width: auto 해줘야한다.
사용자가 사진을 올릴 때 마다 사진이 가로로 긴지 세로로 긴지 파악해서
하나하나 조절하는것이 비효율적이므로
결국엔 background image를 이용하는것이 좋다.
.card-image {
width: 300px;
height: 200px;
overflow: hidden;
}
.card-image.vertical img {
width: 100%;
height: auto;
}
.card-image.horizontal img {
width: auto;
height: 100%;
}
🔺
img 로 마크업시 이런식으로 해야함. (vertical 과 horizontal은 js로 매번 판단하거나 해야함 .. )
나머지는 전부 타이포그래피 설정이거나
display: flex (헤더) 이므로 생략함.
.property-rate::before {
content: "";
position: relative;
top: 2px;
display: inline-block;
width: 16px;
height: 16px;
background-image: url("./assets/icon-star.svg");
background-repeat: no-repeat;
background-position: center center;
background-size: contain;
}
이부분을 잘 보면
4.97 앞에 별 아이콘(icon-star.svg)를 디자인적으로 넣는 것을 알 수 있다.
따로 마크업을 해주지 않았으므로 가상요소 ::before을 이용해서
content는 없게 하고,
width . height 설정을 위해 inline-block으로 설정하고,
background-image를 해준다.
(그에 따라오는 repeat, position, size 속성도)
참고로, sr-only 클래스에
이전에는 display: none을 줬었는데,
그러면 스크린리더가 보이지 않는 것 취급해서 읽어주지 않는다.
따라서 아래와 같이 position:absolute를 이용하자.
(확실하게 하려면 1px*1px과 opacity:0까지 다 하자.)
.sr-only {
position: absolute;
z-index: -100;
width: 1px;
height: 1px;
/* 0px로 주면 스크린 리더가 display:none 취급해서 안읽어줌 */
overflow: hidden;
opacity: 0;
}
detail들의 사이에 ▪ 을 찍어주기 위해서
가상요소를 사용했다.
.property-detail dd span::after {
content: "·";
margin: 0 8px;
}
가상요소는 기본적으로 inline 요소이다.
단, margin을 양옆으로는 줄 수 있으니 display: block을 줄 필요는 없다!
그리고, 마지막 span 뒤에는 ▪이 올 필요가 없으니
last-child를 이용해서 제외시켜준다.
.property-detail dd span:last-child::after {
content: "";
margin: 0;
}
그리고 두 div(dl)사이 간격을 띄워주자.
.property-detail div:first-child {
margin-bottom: 8px;
}
첫번째 요소만 띄우면 되므로 여기서도 first-child를 이용했다.
지금까지의 완성본 🔺
display: flex로 가로정렬
.card {
display: flex;
width: 840px;
padding: 24px;
}
이때, card-content가 딱 h1 크기만큼만 차지한다. (width가)
남는 공간을 다 차지하라고 하고 싶은데 ...
💡 flex-grow 속성
.card-content {
flex-grow: 1;
}
0 (늘이지 마)
1 (남는공간 차지하라고 해!)
이제 잘 적용된걸 알 수 있다!
- 정확히 padding 24px 남기고 잘 늘어남
+) 마지막으로 favorite 버튼 만들기.
.card-image .like-button {
position: absolute;
top: 12px;
left: 12px;
width: 36px;
height: 36px;
border-radius: 50%;
border: none;
background-color: #fff;
background-image: url(./assets/icon-favorite.svg);
background-position: center center;
background-repeat: no-repeat;
background-size: 24px 24px;
cursor: pointer;
}
+) absolute 하기위해 기준이 되는 .card-image에 positon: relative 줘야함.
ref lecture.
- https://edu.goorm.io/learn/lecture/20583
- https://github.com/rohjs/bugless-101/blob/master/css-basic/background/templates/style.css
'PRACTICE > SELF' 카테고리의 다른 글
CSS - Animation practice (0) | 2022.03.01 |
---|---|
CSS - Transition practice (1) | 2022.03.01 |
CSS - Typography Library 제작 (prac) (0) | 2022.02.28 |
CSS - 미디어쿼리 (Media Query) prac (0) | 2022.02.26 |
CSS - Flexbox prac.03 (0) | 2022.02.26 |