whatisthis?
practice - css / js ) Tab Menu 본문
Tab Menu
- Tab Menu
다양한 css skill을 터득.
📃 실습하면서 알게된 점 기록
background: -webkit-linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
-webkit-background-clip과 color
🔺mdn 문서 참고
(-webkit-text-fill-color 와 color의 차이는?)
___
content: attr(data-title);
content: attr(data-title);
이렇게하면 html마크업시
속성에 준 data속성을 css에서
content로 불러올 수 있다!
attr ()함수 이용
내친김에 스타일시트 함수를 알아보자! (CSS Functions)
attr() | HTML 속성값 반환 |
calc() | 사칙연산 수행 |
var() | 사용자 정의 특성값 삽입 |
linear-gradient() | 선형 그라디언트 |
radial-gradient() | 원형 그라디언트 |
cubic-bezier | 베지어 곡선 정의 (타이밍 function) |
+) gradient 정리
background, background-image 속성에서만 사용 가능.
최소 2개 지점 정의. (방향 지정도 가능)
syntax
{background-image: linear-gradient(direction, color-stop1, color-stop2, ...);}
+) 색상값 다음에 0~100%로 나타낸 위치 표시도 가능.
(IE10이상부터 지원가능 - 그 외에는 브라우저 접두어 붙여야함)
-webkit-
사파리 (Safari) , 크롬 (Chrome) , 안드로이드 , 아이폰
-ms-
익스플로러 (IE) ※ IE9 경우 2D 효과만 지원
-moz-
파이어폭스 (Firefox)
-o-
오페라 (Opera)
- reference : @rafaelavlucas
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>Tab Menu</title>
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<section id="wrapper">
<div class="content">
<div class="tabs">
<button class="tablinks active" data-country="London">
<p data-title="London">London</p>
</button>
<button class="tablinks" data-country="Paris">
<p data-title="Paris">Paris</p>
</button>
<button class="tablinks" data-country="Barcelona">
<p data-title="Barcelona">Barcelona</p>
</button>
<button class="tablinks" data-country="Madrid">
<p data-title="Madrid">Madrid</p>
</button>
</div>
<div class="wrapper_tabcontent">
<div id="London" class="tabcontent active">
<h3>London</h3>
<p>
London is the capital of Great Britain. It is one of the greatest
cities in the world. It is an important business and financial
centre. It is an intellectual centre, too. Everywhere in London,
there are open spaces: Hyde Park and Regent Park are the largest.
The City is the oldest part of London.
</p>
</div>
<div id="Paris" class="tabcontent">
<h3>Paris</h3>
<p>
Paris is in the Paris department of the Paris-Isle-of-France
region The French historic, political and economic capital, with a
population of only 2.5 million is located in the northern part of
France. One of the most beautiful cities in the world. Home to
historical monuments such as Notre Dame, the Eiffel tower (320m),
Bastille, Louvre and many more.
</p>
</div>
<div id="Barcelona" class="tabcontent">
<h3>Barcelona</h3>
<p>
Barcelona has been an urban laboratory since the high Medieval
Ages. A place of diversity, a backdrop for a multiplicity of
social and cultural processes on multiple scales that reflect
different ways of constructing the future, a city with a long
experience of urban life and social innovations.
</p>
</div>
<div id="Madrid" class="tabcontent">
<h3>Madrid</h3>
<p>
Madrid is in the middle of Spain, in the Community of Madrid. The
Community is a large area that includes the city as well as small
towns and villages outside the city. 7 million people live in the
Community. More than 3 million live in the city itself.
</p>
</div>
</div>
</div>
</section>
<script src="app.js"></script>
</body>
</html>
style.css
@import url("https://fonts.googleapis.com/css?family=IBM+Plex+Mono:400,400i|IBM+Plex+Sans+Condensed:400,400i|IBM+Plex+Sans:100,100i,400,400i,700,700i|IBM+Plex+Serif:400,400i");
:root {
--text: #686868;
--m01: #667eea; /* main 1*/
--m02: #764ba2; /* main 2*/
--n01: #f5f7fa; /* neutral 1*/
--n02: #c3cfe2; /* neutral 2*/
}
* {
box-sizing: border-box;
margin: 0;
}
body {
background-color: #2e2e2e;
font-family: "IBM Plex Sans", sans-serif;
}
/* reset CSS */
button {
border: none;
font-family: "IBM Plex Sans", sans-serif;
}
button:active,
button:hover {
outline: none;
box-shadow: none;
}
/* wrapper */
#wrapper {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
}
.content {
width: 100%;
max-width: 600px;
min-width: 260px;
margin: 10% 5% 0;
transition: all 0.3s ease;
}
/* Media Query 🔻🔻🔻🔻🔻🔻🔻🔻🔻🔻🔻 */
@media screen and (max-width: 512px) {
.content {
margin: 5% 4% 0;
}
.tabs {
height: 40px;
}
.tablinks {
height: 40px;
font-size: 12px;
}
.tablinks:hover.tablinks::before {
height: 0;
}
.tablinks.active {
height: 60px;
}
.tablinks:hover p {
color: #686868;
opacity: 0.6;
}
.tablinks p::before {
display: none;
}
.tabcontent h3 {
top: 65px;
}
.tabcontent p {
font-size: 14px;
line-height: 26px;
}
}
/* end 🔺🔺🔺🔺🔺🔺🔺🔺🔺🔺🔺🔺🔺 */
/* Tabs menu */
.tabs {
background-image: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
display: flex;
justify-content: space-between;
align-items: center;
height: 80px;
border-radius: 2px 2px 0px 0px;
}
/* Tabs link */
.tablinks {
background: transparent;
background-image: linear-gradient(
90deg,
transparent 70%,
rgba(255, 255, 255, 0.2) 100%
);
cursor: pointer;
width: 25%;
height: 80px;
position: relative;
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
overflow: hidden;
transition: 0.3s ease;
}
.tablinks::before {
content: "";
background-image: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
width: 100%;
height: 0;
position: absolute;
top: 0;
left: 0;
transition: all 0.3s ease-in-out;
z-index: 2;
}
.tablinks:hover::before {
height: 100%;
bottom: 0;
}
/* Tab active */
.tablinks.active {
background-color: #fff;
z-index: 0;
border-right: 0;
border-left: 0;
height: 110px;
bottom: 0px;
overflow: hidden;
}
.tablinks.active::before {
content: "";
width: 100%;
height: 5px;
top: 0;
left: 0;
}
/* Tabs text */
.tablinks.active p,
.tablinks.active:hover p {
opacity: 1;
background: -webkit-linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.tablinks p {
opacity: 0.6;
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
transition: all 0.5s ease;
color: #686868;
backface-visibility: hidden;
font-weight: 400;
}
.tablinks:hover p {
color: #fff;
opacity: 1;
}
/* Tabs text bigger */
.tablinks p::before {
content: attr(data-title);
position: absolute;
height: auto;
width: auto;
color: #fff;
align-items: center;
justify-content: center;
opacity: 0.1;
font-size: 40px;
transition: all 1s ease-out;
z-index: -1;
font-weight: 600;
top: 110%;
}
.tablinks:hover p::before {
top: -80px;
}
/* Tab contents */
.wrapper_tabcontent {
background-color: #fff;
z-index: 1;
position: relative;
opacity: 1;
padding: 40px 60px;
overflow: hidden;
transition: all 1s ease;
}
.tabcontent {
display: none;
}
.tabcontent.active {
transition: all 1s ease;
display: block;
}
/* Tab content line */
.wrapper_tabcontent::after {
content: "";
height: 5px;
width: 100%;
position: absolute;
background-image: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
left: 0;
bottom: 0;
z-index: -2;
transition: all 1s ease;
}
/* Title */
.tabcontent h3 {
font-size: 40px;
top: 75px;
transform: rotate(90deg);
position: absolute;
left: -90px;
opacity: 0.1;
width: 200px;
height: 60px;
background: -webkit-linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
animation: city 1s ease;
}
/* Text */
.tabcontent p {
color: #686868;
font-size: 16px;
line-height: 28px;
font-weight: 100;
transition: all 1s ease;
animation: fadeEffect 0.6s ease;
width: 100%;
}
/* Animations */
@keyframes tabEffect {
from {
top: -40px;
}
to {
top: 0px;
}
}
@keyframes city {
from {
left: -150px;
}
to {
left: -90px;
}
}
@keyframes fadeEffect {
from {
opacity: 0;
margin-left: 30px;
}
to {
opacity: 1;
margin-left: 0;
}
}
app.js
// variables
const tabLinks = document.querySelectorAll(".tablinks");
const tabContent = document.querySelectorAll(".tabcontent");
// 🔺 모든 tabLinks(버튼), tabcontent(div) - nodeList 형태
tabLinks.forEach(function (el) {
el.addEventListener("click", openTabs);
});
// 🔺 tabLinks 각 요소 클릭시 이벤트리스너
function openTabs(el) {
const btnTarget = el.currentTarget;
const country = btnTarget.dataset.country;
// 🔺 btnTarget = 누른 버튼 / country = 현재 누른 버튼의 dataset (data-country속성)
// 1. 우선, 모든 active 다 제거함
tabContent.forEach(function (el) {
el.classList.remove("active");
});
tabLinks.forEach(function (el) {
el.classList.remove("active");
});
// 2. div부분 찾아서(#London) active 속성 추가 & 현재 타겟(=버튼)에도 active 추가
document.querySelector("#" + country).classList.add("active");
// 🔺 아래 div부분. 즉, <div id="London" class="tabcontent"> 에 active 추가
btnTarget.classList.add("active");
}
result
https://github.com/thisisyjin/css-practice
🔺
깃헙에 추가로 올려놨다 :)
'PRACTICE > SELF' 카테고리의 다른 글
practice - js ) 슬라이드 페이지 (2) 터치형(드래그) (0) | 2022.03.11 |
---|---|
practice - js ) 슬라이드 페이지 (1) 버튼형 (0) | 2022.03.11 |
practice - css / jquery ) j쿼리로 아코디언메뉴 만들기 + 추가 (1) | 2022.03.10 |
practice - css / jquery ) j쿼리로 아코디언메뉴 만들기 (0) | 2022.03.10 |
practice - css / js ) j쿼리 없이 아코디언메뉴 만들기 (0) | 2022.03.10 |