whatisthis?
practice - css ) BookStore UI 본문
BookStore UI
-codepen
🏆 KEY POINTS
- display: flex와 flex-shrink
- position: absolute
- FontAwesome 사용 - 다른 방법!
@import url(//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css);
.rating > label::before {
display: inline-block;
font-size: 0.9em;
font-family: FontAwesome;
content: "\f005";
}
- transition과 가상클래스
- overflow
overflow와 text-overflow의 차이는?
- text-overflow: ellipsis
텍스트가 넘치면 ellipsis (...) 로 중략되게 자동으로!
- white-space: nowrap
내용이 넘쳐도 줄바꿈 절대 X.
- display: --webkit-box
- ❗❗ rating - 별점 부분 CSS
<fieldset class="rating purple">
<input type="checkbox" id="star1" name="rating" value="5" />
<label class="full" for="star1"></label>
<input type="checkbox" id="star2" name="rating" value="4" />
<label class="full" for="star2"></label>
<input type="checkbox" id="star3" name="rating" value="3" />
<label class="full" for="star3"></label>
<input type="checkbox" id="star4" name="rating" value="2" />
<label class="full" for="star4"></label>
<input type="checkbox" id="star5" name="rating" value="1" />
<label class="full" for="star5"></label>
</fieldset>
우선, fieldset 안에 묶어두고,
checkbox와 label 쌍을 sibling이 되도록 마크업함.
순서대로 별5, 4, 3, 2, 1 임.
.rating > label {
float: right;
}
float: right해서 원래 5-4-3-2-1 이렇게 있던 거를
star1 | star2 | star3 | star4 | star5 |
이렇게 바꿔줌. float하므로 오른쪽으로 먼저 채운거임.
.rating > input:checked ~ label,
.rating:not(:checked) > label:hover,
.rating:not(:checked) > label:hover ~ label {
color: #d85d61;
}
그리고 input이 check되면 - :checked 라는 가상클래스 이용.
~label은 ? >> checked된것 이후 label들 다~ (sibling selector)
💡
즉, 마크업 순서가 5-4-3-2-1이였던 이유가
css 상 float:right되어있어 1-2-3-4-5이고, 5를 체크시
html구조상으론 5이후 라벨들 다~ (5,4,3,2,1 전부) 적용되도록 하는것임!
그리고, :not이라는 가상클래스도 나오는데, checked가 아닌 나머지 .rating,즉 인풋의 자식 라벨들에 hover시
라벨과 그 이후 라벨들에도 스타일을 적용해줌.
index.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>Book Store</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<header class="header">
<div class="browse">
<div class="browse-category">
Browse Category
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="feather feather-chevron-down"
>
<path d="M6 9l6 6 6-6" />
</svg>
</div>
<div class="search-bar">
<input type="text" placeholder="Search Book" />
</div>
</div>
<div class="header-title">read<span>books</span></div>
<div class="profile">
<div class="user-profile">
<img
src="https://randomuser.me/api/portraits/women/63.jpg"
alt="user123"
class="user-img"
/>
</div>
<div class="profile-menu">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="feather feather-menu"
>
<path d="M3 12h18M3 6h18M3 18h18" />
</svg>
Menu
</div>
</div>
</header>
<!-- book slide -->
<div class="book-slide">
<div
class="book js-flickity"
data-flickity-options='{ "wrapAround": true }'
>
<div class="book-cell">
<div class="book-img">
<img
src="https://images-na.ssl-images-amazon.com/images/I/81WcnNQ-TBL.jpg"
alt=""
class="book-photo"
/>
</div>
<div class="book-content">
<div class="book-title">BIG MAGIC</div>
<div class="book-author">by Elizabeth Gilbert</div>
<div class="rate">
<fieldset class="rating">
<input type="checkbox" name="rating" id="star5" value="5" />
<label class="full" for="star5"></label>
<input type="checkbox" name="rating" id="star4" value="4" />
<label class="full" for="star4"></label>
<input type="checkbox" name="rating" id="star3" value="3" />
<label class="full" for="star3"></label>
<input type="checkbox" name="rating" id="star2" value="2" />
<label class="full" for="star2"></label>
<input type="checkbox" name="rating" id="star1" value="1" />
<label class="full" for="star1"></label>
</fieldset>
<span class="book-voters">1.987 voters</span>
</div>
<div class="book-sum">
Readers of all ages and walks of life have drawn inspiration and
empowerment from Elizabeth Gilbert’s books for years.
</div>
<div class="book-see">See The Book</div>
</div>
</div>
<div class="book-cell">
<div class="book-img">
<img
src="https://i.pinimg.com/originals/a8/b9/ff/a8b9ff74ed0f3efd97e09a7a0447f892.jpg"
alt=""
class="book-photo"
/>
</div>
<div class="book-content">
<div class="book-title">Ten Thousand Skies Above You</div>
<div class="book-author">by Claudia Gray</div>
<div class="rate">
<fieldset class="rating blue">
<input type="checkbox" id="star6" name="rating" value="5" />
<label class="full1" for="star6"></label>
<input type="checkbox" id="star7" name="rating" value="4" />
<label class="full1" for="star7"></label>
<input type="checkbox" id="star8" name="rating" value="3" />
<label class="full1" for="star8"></label>
<input type="checkbox" id="star9" name="rating" value="2" />
<label class="full1" for="star9"></label>
<input type="checkbox" id="star10" name="rating" value="1" />
<label class="full1" for="star10"></label>
</fieldset>
<span class="book-voters">1.987 voters</span>
</div>
<div class="book-sum">
The hunt for each splinter of Paul's soul sends Marguerite racing
through a war-torn San Francisco.
</div>
<div class="book-see book-blue">See The Book</div>
</div>
</div>
<div class="book-cell">
<div class="book-img">
<img
src="https://images-na.ssl-images-amazon.com/images/I/81af+MCATTL.jpg"
alt=""
class="book-photo"
/>
</div>
<div class="book-content">
<div class="book-title">The Great Gatsby</div>
<div class="book-author">by F.Scott Fitzgerald</div>
<div class="rate">
<fieldset class="rating yellow">
<input type="checkbox" id="star16" name="rating" value="5" />
<label class="full" for="star16"></label>
<input type="checkbox" id="star17" name="rating" value="4" />
<label class="full" for="star17"></label>
<input type="checkbox" id="star18" name="rating" value="3" />
<label class="full" for="star18"></label>
<input type="checkbox" id="star19" name="rating" value="2" />
<label class="full" for="star19"></label>
<input type="checkbox" id="star20" name="rating" value="1" />
<label class="full" for="star20"></label>
</fieldset>
<span class="book-voters">1.987 voters</span>
</div>
<div class="book-sum">
The Great Gatsby, F. Scott Fitzgerald’s third book, stands as the
supreme achievement of his career.
</div>
<div class="book-see book-yellow">See The Book</div>
</div>
</div>
<div class="book-cell">
<div class="book-img">
<img
src="https://images-na.ssl-images-amazon.com/images/I/81UWB7oUZ0L.jpg"
alt=""
class="book-photo"
/>
</div>
<div class="book-content">
<div class="book-title">After You</div>
<div class="book-author">by Jojo Moyes</div>
<div class="rate">
<fieldset class="rating purple">
<input type="checkbox" id="star21" name="rating" value="5" />
<label class="full" for="star21"></label>
<input type="checkbox" id="star22" name="rating" value="4" />
<label class="full" for="star22"></label>
<input type="checkbox" id="star23" name="rating" value="3" />
<label class="full" for="star23"></label>
<input type="checkbox" id="star24" name="rating" value="2" />
<label class="full" for="star24"></label>
<input type="checkbox" id="star25" name="rating" value="1" />
<label class="full" for="star25"></label>
</fieldset>
<span class="book-voters">1.987 voters</span>
</div>
<div class="book-sum">
Louisa Clark is no longer just an ordinary girl living an ordinary
life. After the transformative six months spent.
</div>
<div class="book-see book-purple">See The Book</div>
</div>
</div>
</div>
<div class="btn-grp">
<button class="prev"><</button>
<button class="next">></button>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
style.css
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap");
@import url(//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css);
:root {
--body-color-light: #8b939c;
--body-color: #3d4954;
--border-color: #b8bec3;
--placeholder: #ccd0d2;
}
* {
box-sizing: 0;
margin: 0;
}
body {
font-family: "Roboto", sans-serif;
font-weight: 400;
color: var(--body-color);
width: 100%;
height: 100vh;
}
/* Reset CSS */
ul,
ol,
li {
list-style: none;
padding: 0;
}
a {
text-decoration: none;
color: inherit;
}
button {
border: none;
}
input,
button,
textarea {
font-family: "Roboto", sans-serif;
}
input:focus,
button:focus,
textarea:focus,
input:active,
button:active,
textarea:active {
outline: none;
box-shadow: none;
}
fieldset,
label {
margin: 0;
padding: 0;
display: inline-block;
vertical-align: middle;
}
/* Header page */
.header {
display: flex;
justify-content: space-between;
padding: 0 30px;
width: 100%;
height: 70px;
font-size: 14px;
font-weight: 500;
color: var(--body-color-light);
}
/* header - browse */
.header .browse {
display: flex;
align-items: center;
}
.header .browse .browse-category {
display: flex;
border-right: 1px solid var(--border-color);
white-space: nowrap;
}
.header .browse svg {
width: 16px;
margin: 2px 10px 0 8px;
}
.header .search-bar {
position: relative;
}
.header .search-bar input {
display: block;
width: 100%;
height: 100%;
border: none;
padding: 0 10px 0 40px;
color: var(--body-color);
font-weight: 600;
background-color: transparent;
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%238b939c' stroke-width='3' stroke-linecap='round' stroke-linejoin='round' class='feather feather-search'%3e%3ccircle cx='11' cy='11' r='8'/%3e%3cpath d='M21 21l-4.35-4.35'/%3e%3c/svg%3e");
background-repeat: no-repeat;
background-size: 15px;
background-position: 15px 50%;
}
.header .search-bar input::placeholder {
color: var(--placeholder);
}
/* header - title */
.header .header-title {
font-size: 16px;
font-weight: 400;
margin: auto 120px auto 0;
}
.header .header-title span {
font-weight: 700;
color: var(--body-color);
}
/* header - profile*/
.header .profile {
display: flex;
align-items: center;
flex-shrink: 0;
}
.header .user-profile {
position: relative;
cursor: pointer;
flex-shrink: 0;
}
.header .user-profile::before {
content: "";
position: absolute;
width: 7px;
height: 7px;
border-radius: 50%;
background-color: #f86d72;
border: 2px solid #fff;
right: 12px;
top: -2px;
}
.header .profile .user-img {
display: block;
width: 28px;
height: 28px;
border-radius: 50%;
margin-right: 15px;
}
.header .profile-menu {
display: flex;
border-left: 1px solid var(--border-color);
}
.header .profile-menu svg {
width: 16px;
margin: 0 8px 0 15px;
flex-shrink: 0;
}
/* Book Slide Page */
.book-slide {
width: 100%;
position: relative;
}
.book {
background-color: #fff;
display: flex;
width: calc(40% * 4);
margin-left: -10%;
}
.js-flickity {
transition: all 0.3s ease-out;
}
.book-cell {
position: relative;
display: flex;
padding: 25px;
width: 40%;
height: 200px;
margin-right: 1px;
}
.book-cell:nth-child(1) {
background-color: #fbadaf;
}
.book-cell:nth-child(2) {
background-color: #a4e0eb;
}
.book-cell:nth-child(3) {
background-color: #fdca95;
}
.book-cell:nth-child(4) {
background-color: #cbb5e2;
}
/* .flickity-page-dots {
display: none;
}
.flickity-prev-next-button .arrow {
fill: #d6d6d6;
}
.flickity-prev-next-button svg {
left: 25%;
top: 25%;
width: 50%;
height: 50%;
}
.flickity-prev-next-button.previous {
left: 15px;
}
.flickity-prev-next-button.next {
right: 15px;
}
.flickity-viewport {
overflow: visible;
} */
.book-photo {
width: 180px;
flex-shrink: 0;
bottom: -35px;
border-radius: 2px;
box-shadow: -2px 6px 19px 0px #7f818e;
transition: all 0.3s ease;
}
.book-photo:hover {
transform: scale(1.03);
}
.book-img {
flex-shrink: 0;
}
.book-title {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.book-author {
margin-top: 3px;
font-size: 14px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.book-content {
padding: 0 20px;
color: #fff;
overflow: hidden;
}
.rating {
border: none;
}
.rating > input {
display: none;
}
.rating > label::before {
margin-right: 5px;
margin-top: 10px;
font-size: 0.9em;
font-family: FontAwesome;
display: inline-block;
content: "\f005";
}
.rating > label {
color: #fff;
float: right;
}
.rating > input:checked ~ label,
.rating:not(:checked) > label:hover,
.rating:not(:checked) > label:hover ~ label {
color: #d85d61;
}
.blue > input:checked ~ label,
.blue:not(:checked) > label:hover,
.blue:not(:checked) > label:hover ~ label {
color: #458997;
}
.purple > input:checked ~ label,
.purple:not(:checked) > label:hover,
.purple:not(:checked) > label:hover ~ label {
color: #a76287;
}
.yellow > input:checked ~ label,
.yellow:not(:checked) > label:hover,
.yellow:not(:checked) > label:hover ~ label {
color: #ffad58;
}
/*
굳이 이건 왜하는지 모르겠음 🔻
*/
/*
.rating > input:checked + label:hover,
.rating > input:checked ~ label:hover,
.rating > label:hover ~ input:checked ~ label,
.rating > input:checked ~ label:hover ~ label {
color: #d85d61;
}
.blue > input:checked + label:hover,
.blue > input:checked ~ label:hover,
.blue > label:hover ~ input:checked ~ label,
.blue > input:checked ~ label:hover ~ label {
color: #458997;
}
.purple > input:checked + label:hover,
.purple > input:checked ~ label:hover,
.purple > label:hover ~ input:checked ~ label,
.purple > input:checked ~ label:hover ~ label {
color: #a76287;
}
.yellow > input:checked + label:hover,
.yellow > input:checked ~ label:hover,
.yellow > label:hover ~ input:checked ~ label,
.yellow > input:checked ~ label:hover ~ label {
color: #ffad58;
}
*/
.book-voters {
color: #fff;
vertical-align: sub;
font-size: 13px;
margin-left: 7px;
white-space: nowrap;
}
.book-sum {
margin-top: 20px;
font-size: 14px;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
min-width: 300px;
}
.book-see {
width: 160px;
padding: 8px;
margin-top: 25px;
border-radius: 20px;
background-color: #fff;
color: #fbadaf;
font-size: 14px;
font-weight: 600;
text-align: center;
}
.book-see:hover {
color: #ff6e72;
}
.book-see.book-blue {
color: #a4e0eb;
}
.book-see.book-blue:hover {
color: #22cdec;
}
.book-see.book-yellow {
color: #fdca95;
}
.book-see.book-yellow:hover {
color: #fb9124;
}
.book-see.book-purple {
color: #cbb5e2;
}
.book-see.book-purple:hover {
color: #a764ec;
}
/* buttons */
.btn-grp button {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 50px;
height: 50px;
z-index: 1;
background-color: rgba(0, 0, 0, 0.2);
border-radius: 50%;
font-size: 35px;
color: #fff;
transition: all 0.2s ease;
}
.btn-grp .prev {
left: 10px;
}
.btn-grp .next {
right: 10px;
}
.btn-grp button:hover {
background-color: rgba(0, 0, 0, 0.4);
}
원래는 슬라이드 기능 구현을 js로 하는데,
무려 3000줄이라서 (...) 내가 간단히 다시 작성중이다.
추후 수정해서 업로드함.
result
실습하면서 메모한거 🔻
text-overflow: ellipsis;
white-space: nowrap;
white-space: nowrap 이거는 줄바꿈 안되게.
text-overflow는
텍스트가 넘치면
ellipsis (...) 로 중략되게
__
.rating > label::before {
font-size: 0.9em;
font-family: FontAwesome;
display: inline-block;
content: "\f005";
}
폰트어썸 적용법
물론 import는 해야댐
svg는 색상변경도 되니까 참 편하다
얘도 그렇다.
텍스트처럼 취급하면된다.
__
.rating > label {
color: #fff;
float: right;
}
.rating > input:checked ~ label,
.rating:not(:checked) > label:hover,
.rating:not(:checked) > label:hover ~ label {
color: #d85d61;
}
이부분 개쩐다!
별 레이팅!
sibling selctor를 잘 쓰자.
html에선 5-4-3-2-1이고
float: right로 1-2-3-4-5로 시각적으로 보이게 한 후에
5클릭하면?
~ 선택자에 의해 5이후 label들 (5,4,3,2,1)이 다 색 적용되는것.
__
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
webkit box라는건데
3줄로 제한하는거
+) 얘도 ...로 중략되는듯??
Reference &
Thanks to @Aysenur Turk!
사담 & 후기 👻
codepen 탐험하다가 발견했는데,
js가 너무 크고 구식버전 이길래 우선 버리고 (...제이쿼리 너무 싫ㄷ ㅏ..)
넘 맘에들었던 슬라이드식 UI만 클론 해봤다.
별거아닌데 왜이렇게 오래걸린건지 .. 하하
암튼 이제 리액트 공부하러 갈 시간!
이번주는 바쁘게 CSS 클론해보고 컴포넌트별 간단한거 구현을 해봤다.
아직 배우고싶은건 많지만 ...
나중에 또 css 공부하러 올때쯤이면 아마
리액트와 노드에 익숙해져서
scss로 작성하러 올 것 같다 !
'PRACTICE > SELF' 카테고리의 다른 글
practice) input="file" 커스터마이징 + 이미지 띄우기 (0) | 2022.03.16 |
---|---|
practice) React.js - 틱택토(Tic Tac Toe) 게임 (0) | 2022.03.15 |
practice - css ) 슬라이드 페이지 - CSS only (JS❌) (0) | 2022.03.11 |
practice - js ) 슬라이드 페이지 (2) 터치형(드래그) (0) | 2022.03.11 |
practice - js ) 슬라이드 페이지 (1) 버튼형 (0) | 2022.03.11 |