expanding Cards 演示地址:https://50projects50days.com/projects/expanding-cards/
Progress Steps 演示效果链接:https://50projects50days.com/projects/progress-steps/
思路:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 *************HTML*************** <div class="container"> <div class="progress-container"> <div class="progress" id="progress"></div> <div class="circle" active>1</div> <div class="circle">2</div> <div class="circle">3</div> <div class="circle">4</div> </div> <button class="btn" id="prev" disabled>Prev</button> <button class="btn" id="next">Next</button> </div> *************CSS*********** :root { --line-border-fill: #3498db; --line-border-empty: #e0e0e0; } * { box-sizing: border-box; } body { background-color: #f6f7fb; font-family: 'Muli', sans-serif; display: flex; align-items: center; justify-content: center; height: 100vh; overflow: hidden; margin: 0; } .container { text-align: center; } .progress-container { display: flex; justify-content: space-between; position: relative; margin-bottom: 30px; max-width: 100%; width: 350px; } .progress-container::before{ content:''; background-color: var(--line-border-empty); position: absolute; top:50%; left:0; transform: translateY(-50%); height: 4px; width:100%; z-index: -1; } .progress{ background-color: var(--line-border-fill); position: absolute; top: 50%; left: 0; transform: translateY(-50%); height: 4px; width:0%; z-index: -1; transition: 0.4s ease; } .circle{ background-color: #fff; color:#999; border-radius: 50%; height: 30px; width: 30px; display: flex; align-items: center; justify-content: center; border: 3px solid var(--line-border-empty); transition: 0.4 ease; } .circle.active{ border-color:var(--line-border-fill); } .btn{ background-color: var(--line-border-fill); color: #fff; border:0; border-radius: 6px; cursor:pointer; font-family: inherit; padding: 8px 30px; margin:5px; font-size: 14px; } .btn:active{ transform: scale(0.98); } .btn:focus{ outline:0; } .btn:disabled{ background-color: var(--line-border-empty); cursor: not-allowed; } } ***********JS*********** const progress = document.getElementById('progress') const prev = document.getElementById('prev') const next = document.getElementById('next') const circles = document.querySelectorAll('.circle') let currentActive = 1 next.addEventListener('click', () => { currentActive++ if(currentActive > circles.length) { currentActive = circles.length } update() }) prev.addEventListener('click', () => { currentActive-- if(currentActive < 1) { currentActive = 1 } update() }) function update() { circles.forEach((circle, idx) => { if(idx < currentActive) { circle.classList.add('active') } else { circle.classList.remove('active') } }) const actives = document.querySelectorAll('.active') progress.style.width = (actives.length - 1) / (circles.length - 1) * 100 + '%' if(currentActive === 1) { prev.disabled = true } else if(currentActive === circles.length) { next.disabled = true } else { prev.disabled = false next.disabled = false } }
演示链接:https://50projects50days.com/projects/hidden-search-widget/
设计思路:
1.在使用图标的时候使用伪类,注意导入fontAwesome的链接,且用标签包起来
2、search类大类中包含input和btn,将btn和input的宽高设置成一样的,search设成相对定位,btn设成绝对定位,将btn的top和left都设置为0 ,这样btn和input就可以位于同一位置。
3、在写JS时不必将btn和input都设置active,只要在search设置acitve类就可以了。
*HTML
Scroll to see the animation
Content
Content
Content
Content
Content
Content
Content
Content
**************CSS*************
*{
box-sizing: border-box;
}
body{
font-family: 'Roboto', sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 0;
overflow-x: hidden;
}
h1{
margin: 10px;
}
.box{ background-color: rgb(173, 173, 238); color: #fff; display: flex; align-items: center; justify-content: center; width: 400px; height: 200px; margin: 10px; box-shadow: 2px 4px 5px rgba(0,0,0, 0.3); transform: translateX(200%); transition: transform 0.4s ease; } .box:nth-of-type(even) { transform: translateX(-200%); }
.box.show { transform: translateX(0); }
.box h2 { font-size: 45px; }
JS const boxes = document.querySelectorAll(‘.box’); window.addEventListener(‘scroll’, checkBoxes); checkBoxes();
function checkBoxes(){ const triggerBottom = window.innerHeight/5*4; boxes.forEach(box=>{ let boxTop = box.getBoundingClientRect().top; if(boxTop<triggerBottom){ box.classList.add(‘show’); }else{ box.classList.remove(‘show’) } }) }
1 2 3 4 5 6 7 8 9 10 11 ### Split Landing Page(拆分登录页) 演示参考地址: https://50projects50days.com/projects/split-landing-page/# 设计思路: HTML和CSS : container 中包含split left 和split right 注意,这是多类选择器,包含两个类,两个split的宽度分辨设置成页面宽度的一半。然后对left 和right 进行定制设计,可添加伪类未图片设置透明背景色。 JS: 获取到lfet ,right和container,当鼠标发生mouseenter事件时,为container添加hover-right和hover-left类选择器,当鼠标发生mouseleave事件时,移除hover-right 和hover-left类选择器。
HTML
CSS
{ box-sizing: border-box; }
body { font-family: ‘Roboto’, sans-serif; height: 100vh; overflow: hidden; margin: 0; }
h1 { font-size: 3rem; color: #fff; position: absolute; left: 50%; top: 20%; transform: translateX(-50%); white-space: nowrap; }
.btn { position: absolute; display: flex; align-items: center; justify-content: center; left: 50%; top: 40%; transform: translateX(-50%); text-decoration: none; color: #fff; border: #fff solid 0.2rem; font-size: 1rem; font-weight: bold; text-transform: uppercase; width: 15rem; padding: 1.2rem; }
.split.left .btn:hover { background-color: var(–left-btn-hover-color); border-color: var(–left-btn-hover-color); }
.split.right .btn:hover { background-color: var(–right-btn-hover-color); border-color: var(–right-btn-hover-color); }
.container { position: relative; width: 100%; height: 100%; /* background: #333; */ }
.split { position: absolute; width: 50%; height: 100%; overflow: hidden; }
.split.left{ left: 0; background: url(‘https://50projects50days.com/projects/split-landing-page/ps.jpg' ); background-repeat: no-repeat; background-size: cover; }
.split.left::before { content: ‘’; position: absolute; width: 100%; height: 100%; background-color: rgba(110, 122, 190, 0.5); }
.split.right { right: 0; background: url(‘https://50projects50days.com/projects/split-landing-page/xbox.jpg' ); background-repeat: no-repeat; background-size: cover; }
.split.right::before { content: ‘’; position: absolute; width: 100%; height: 100%; background-color: rgba(43, 43, 43, 0.6); }
.split.right, .split.left, .split.right::before, .split.left::before { transition: all 1s ease-in; }
.hover-left .left { width: 75%; }
.hover-left .right { width: 25%; }
.hover-right .right { width: 75%; }
.hover-right .left { width: 25%; }
@media (max-width: 800px) { h1 { font-size: 2rem; top: 27%; }
.btn { padding: 1.1rem; width: 12rem; } }
JS ***** const left = document.querySelector(‘.left’); const right = document.querySelector(‘.right’); const container = document.querySelector(‘.container’); left.addEventListener(‘mouseenter’, ()=>container.classList.add(‘hover-left’)); left.addEventListener(‘mouseleave’, ()=>container.classList.remove(‘hover-left’));
right.addEventListener(‘mouseenter’, ()=>container.classList.add(‘hover-right’)); right.addEventListener(‘mouseleave’, ()=>container.classList.remove(‘hover-right’));
1 2 3 4 5 6 7 ### Faq Collapse 演示参考地址:https://50projects50days.com/projects/faq-collapse/ 设计思路:container中包含5个fqa, 在第一个fqa上添加active类选择器,让其第一个显示出来,在JS中可选中所有的.fqa-toggle(button),用forEach遍历所有的.fqa-toggle,当发生点击事件(用toggle实现)的时候,为fqa添加或者移除active。
HTML
Frequently Asked Question
Why shouldn't we trust atoms?
They make up everything
<div class="faq">
<h3 class="faq-title">
Why do you call someone with nop body and no nose?
</h3>
<p class="faq-text">Nobody knows.</p>
<button class="faq-toggle">
<i class="fas fa-chevron-down"></i>
<i class="fas fa-times"></i>
</button>
</div>
<div class="faq">
<h3 class="faq-title">
What's the object-oriented way to become wealthy?
</h3>
<p class="faq-text">Inheritance.</p>
<button class="faq-toggle">
<i class="fas fa-chevron-down"></i>
<i class="fas fa-times"></i>
</button>
</div>
<div class="faq">
<h3 class="faq-title">
How many tickles does it take to tickle an octopus?
</h3>
<p class="faq-text">Ten-tickles.</p>
<button class="faq-toggle">
<i class="fas fa-chevron-down"></i>
<i class="fas fa-times"></i>
</button>
</div>
<div class="faq">
<h3 class="faq-title">
What is 1+1?
</h3>
<p class="faq-text">Depends on who are you asking.</p>
<button class="faq-toggle">
<i class="fas fa-chevron-down"></i>
<i class="fas fa-times"></i>
</button>
</div>
CSS *
{ box-sizing: border-box; }
body { font-family: ‘Muli’, sans-serif; background-color: #f0f0f0; }
h1 { margin: 50px 0 30px; text-align: center; }
.faq-container { max-width: 600px; margin: 0 auto; }
.faq { background-color: transparent; border: 1px solid #9fa4a8; border-radius: 10px; margin: 20px 0; padding: 30px; position: relative; overflow: hidden; transition: 0.3s ease; }
.faq.active { background-color: #fff; box-shadow: 0 3px 6px rgba(0, 0, 0, 0.2); }
.faq.active::before, .faq.active::after { content: ‘\f075’; font-family: ‘Font Awesome 5 Free’; color: #2ecc71; font-size: 7rem; position: absolute; opacity: 0.2; top: 20px; left: 20px; z-index: 0; }
.faq.active::before { color: #3498db; top: -10px; left: -30px; transform: rotateY(180deg); }
.faq-title { margin: 0 35px 0 0; }
.faq-text { display: none; margin: 30px 0 0; }
.faq.active .faq-text { display: block; }
.faq-toggle { background-color: transparent; border: 0; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 16px; padding: 0; position: absolute; top: 30px; right: 30px; height: 30px; width: 30px; }
.faq-toggle:focus { outline: 0; }
.faq-toggle .fa-times { display: none; }
.faq.active .faq-toggle .fa-times { color: #fff; display: block; }
.faq.active .faq-toggle .fa-chevron-down { display: none; }
.faq.active .faq-toggle { background-color: #8bb8dd; }
*JS const toggles = document.querySelectorAll(‘.faq-toggle’); toggles.forEach(toggle=>{ toggle.addEventListener(‘click’,()=>{ toggle.parentNode.classList.toggle(‘active’) }) })
1 2 3 4 5 6 7 ### Random Choice Picker 演示参考链接:https://50projects50days.com/projects/random-choice-picker/ 设计思路:
***HTML
Enter all of the choices divided by a comma (',').
Press enter when you're done
*************CSS*********
*{
box-sizing: border-box;
}
body{ font-family: ‘Muli’, sans-serif; display: flex; align-items: center; justify-content: center; flex-direction: column; height: 100vh; text-align: center; background-color: rgb(109, 108, 189); overflow: hidden; margin: 0; }
.container{ width:500px; } h3{ color:aliceblue }
textarea{ border: none; display:block; font-family: inherit; width:100%; height:100px; padding: 10px; margin: 0 0 20px; } .tag{ background-color: rgb(247, 167, 77); border-radius: 50px; color:#fff; padding: 10px 20px; margin: 0 5px 10px 0; font-size: 14px; display: inline-block; }
.tag.highlight{ background-color: #273c75; }
JS *** const tagsEl = document.getElementById(‘tags’); const textarea = document.getElementById(‘textarea’); textarea.focus(); textarea.addEventListener(‘keyup’, (e)=>{ createTags(e.target.value); if(e.key===’Enter’){ setTimeout(() => { e.target.value=’’; }, 10); randomSelect(); } })
function createTags(input){ const tags = input.split(‘,’).filter(tag=>tag.trim() !==’’).map(tag=>tag.trim()); tagsEl.innerHTML=’’; tags.forEach(tag=>{ const tagEl= document.createElement(‘span’); tagEl.classList.add(‘tag’); tagEl.innerText = tag; tagsEl.appendChild(tagEl)
}) } function randomSelect(){ setTimeout(() => { const randomTag = pinkRandomTag(); highlightTag(randomTag); }, 1000); }
function pinkRandomTag(){ const tags = document.querySelectorAll(‘.tag’) return tags[0] }
function highlightTag(tag) { tag.classList.add(‘highlight’) }
1 2 3 ### Animated Navigation
*HTML
***CSS * { box-sizing: border-box; } body { background-color: #eafbff; background-image:linear-gradient( to bottom, #eafbff 0%, #eafbff 50%, #52909f 50%, #52909f 50% ); font-family: ‘Muli’,sans-serif; display: flex; align-items: center; justify-content: center; height: 100vh; margin:0; }
nav{
background-color: rgb(248, 247, 247);
padding:20px;
width:80px;
display:flex;
align-items: center;
justify-content: center;
border-radius: 3px;
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
transition: width 0.6 linear;
overflow-x: hidden;
}
nav.active {
width: 350px; }
nav ul { display: flex; list-style-type: none; padding: 0; margin: 0; width: 0; transition: width 0.6s linear; }
nav.active ul { width: 100%; }
nav ul li { transform: rotateY(0deg); opacity: 0; transition: transform 0.6s linear, opacity 0.6s linear;
}
nav.active ul li { opacity: 1; transform: rotateY(360deg); margin: 0 10px; }
nav ul a { position: relative; color: #000; text-decoration: none;
}
.icon { background-color: #fff; border: 0; cursor: pointer; padding: 0 10px; position: relative; height: 30px; width: 30px; }
.icon:focus { outline: 0; }
.icon .line { background-color: #5290f9; height: 2px; width: 20px; position: absolute; top: 10px; left: 5px; transition: transform 0.6s linear; }
.icon .line2 { top: auto; bottom: 10px; }
nav.active .icon .line1 { transform: rotate(135deg) translateX(3px) translateY(-2px) ; }
nav.active .icon .line2 { transform: rotate(-135deg) translateY(3px) translateX(2px) ;; }
JS ** const toggle = document.getElementById(‘toggle’); const nav= document.getElementById(‘nav’); toggle.addEventListener(‘click’, ()=>nav.classList.toggle(‘active’))
1 2 3 4 5 ### Incrementing Count 演示参考地址:https://50projects50days.com/projects/incrementing-counter/
HTML *****
CSS * *{ box-sizing: border-box; } body{ background-color:rgb(109, 64, 151) ; display: flex; font-family: ‘Roboto Mono’ ,sans-serif; align-items: center; justify-content: center; height: 100vh; margin:0; overflow: auto; color:aliceblue; } .count-container{ display: flex; flex-direction: column; justify-content: center; text-align: center; margin: 10px 40px; padding: 10px 10px;
}
.count-container .counter{ font-size: 60px; } .count-container i{ color:rgb(252, 251, 253); font-size: 90px; }
.count-container span{ color:aliceblue; font-size: 14px; }
@media(max-width:589px){ body{ flex-direction: column; } }
JS **** const counters= document.querySelectorAll(‘.counter’); counters.forEach(counter=>{ counter.innerHTML=”0”; const updataCounter=()=>{ let targert = counter.dataset.targert; let step = targert/200; let c= +counter.innerHTML; if(c<targert){ counter.innerHTML=${Math.ceil(c+step)}
setTimeout(updataCounter,1) } } updataCounter(); })
1 2 3 4 5 ### Drink Water 演示参考链接:https://50projects50days.com/projects/drink-water/
*HTML
Drink Water
Goal : 2 Liters
Select how many glasses of water that you have drank
250ml
250ml
250ml
250ml
250ml
250ml
250ml
250ml
CSS ** *{ box-sizing: border-box; }
body{ background-color: rgb(49, 122, 182); display: flex; align-items: center; justify-content: center; margin-top: 40px; flex-direction: column; color:aliceblue }
h1{ margin: 10px 0; } h3{ font-weight: 400px; margin: 10px 0; } .cup{ height: 330px; width: 150px; background-color: #fff; color:rgb(26, 130, 214); border-radius: 0 0 40px 40px; border:solid 4px #0c4aa7; margin: 30px 0; display: flex; flex-direction: column; overflow: hidden; } .remained{ display: flex; justify-content: center; flex-direction: column; align-items: center; text-align: center; flex:1; transition: 0.3s ease; }
.cup .remained span{ font-size: 20px; font-weight: bold; }
.cup .remained small{ font-size: 12px; }
.percentage{ background-color: aqua; display: flex; align-items: center; justify-content: center; font-size: 30px; font-weight: bold; height: 0; transition: 0.3 ease-in;
} .cups{ display: flex; flex-wrap: wrap; width: 280px; align-items: center; justify-content: center; } .cup.cup-small{ height: 95px; width: 50px; border-radius: 0 0 15px 15px; background-color:rgba(255, 255, 255, 0.9) ; cursor: pointer; font-size: 14px; align-items: center; justify-content: center; text-align: center; margin:5px; }
.cup.cup-small.full{ background-color: rgb(231, 152, 241); color:#fff; }
JS ***** const smallCups = document.querySelectorAll(‘.cup-small’); const listers = document.getElementById(‘liters’); const percentage= document.getElementById(‘percentage’); const remained = document.getElementById(‘remained’);
updateBigCup();
smallCups.forEach((cup, index)=>{ cup.addEventListener(‘click’ ,()=>{ highlightCups(index) }) })
function highlightCups(index){ smallCups.forEach((cup, index2)=>{ if(index2<=index){ cup.classList.add(‘full’); }else{ cup.classList.remove(‘full’); } }) updateBigCup(); }
function updateBigCup(){ const totalCups = smallCups.length; let fullCups = document .querySelectorAll(‘.cup-small.full’).length; if(fullCups===0){ percentage.style.visibility=”hidden”; percentage.style.height=0 }else{ percentage.style.visibility= ‘visible’; percentage.style.height= ${fullCups/totalCups*330}px
; percentage.innerText=${fullCups/totalCups*100}%
}
if(fullCups===totalCups){ remained.style.visibility=”hidden”; remained.style.height=0; }else{ remained.style.visibility=”visible”; listers.innerText=${2-fullCups*250/1000}L
} }
1 2 3 4 5 6 7 ### background Slide(背景幻灯片) 演示参考地址:https://50projects50days.com/projects/background-slider/ 设计思路:初始化一个常量=0去记录幻灯片的索引,当点击左边按钮的时候,索引值-1,当点击右按钮的时候,索引常量+1,注意当这个记录常量值魏边界值<0时候,将其赋值为图片的长度-1,当记录常量值大于图片长度-1时,将其赋值为0,就可以实现幻灯片的循环播放。并将当前的幻灯片设置为背景图片,同时为对当前的幻灯片添加active类,使其显示出来。
******HTML
<div
class="slide"
style="
background-image: url('https://images.unsplash.com/photo-1495467033336-2effd8753d51?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2100&q=80');
"
></div>
<div
class="slide"
style="
background-image: url('https://images.unsplash.com/photo-1522735338363-cc7313be0ae0?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2689&q=80');
"
></div>
<div
class="slide"
style="
background-image: url('https://images.unsplash.com/photo-1559087867-ce4c91325525?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2100&q=80');
"
></div>
**********CSS ************** *{ box-sizing: border-box; }
body { font-family: ‘Roboto’, sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; overflow: hidden; margin: 0; background-position: center center; background-size: cover; transition: 0.4s ease; }
body::before { content: ‘’; position: absolute; top: 0; left: 0; width: 100%; height: 100vh; background-color: rgba(0, 0, 0, 0.7); z-index: -1; } .slider-container { box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.5); height: 70vh; width: 70vw; position: relative; overflow: hidden; }
.slide { opacity: 0; height: 100vh; width: 100vw; background-position: center center; background-size: cover; position: absolute; top: -15vh; left: -15vw; transition: 0.4s ease; z-index: 1; }
.slide.active { opacity: 1; }
.arrow { position: fixed; background-color: transparent; color: #fff; padding: 20px; font-size: 30px; border: 2px solid orange; top: 50%; transform: translateY(-50%); cursor: pointer; } .arrow:focus{ outline: 0; }
.left-arrow{ left:calc(15vw - 68.5px); } .right-arrow{ right: calc(15vw - 65px); }
JS const body = document.body; const leftBtn = document.getElementById(‘left’); const rightBtn = document.getElementById(‘right’); const slides = document.querySelectorAll(‘.slide’);
let slideActive=0; rightBtn.addEventListener(‘click’, ()=>{ slideActive++; if(slideActive>slides.length-1){ slideActive=0; } setBgToBody(); setActiveSlide(); })
leftBtn.addEventListener(‘click’, ()=>{ slideActive–; if(slideActive<0){ slideActive=slides.length-1; } setBgToBody(); setActiveSlide(); })
setBgToBody();
function setBgToBody(){ body.style.backgroundImage = slides[slideActive].style.backgroundImage; }
function setActiveSlide(){ slides.forEach(slide=>{ slide.classList.remove(‘active’); }) slides[slideActive].classList.add(‘active’); }
1 2 3 4 5 ### Theme Clock 演示参考地址:https://50projects50days.com/projects/theme-clock/
HTML **Dark mode
***************CSS*********** *{ box-sizing: border-box; }
html{ transition: all 0.5s ease-in; } html.dark{ background-color: #111; color:rgb(255, 251, 251); }
body{ font-family: ‘Heebo’, sans-serif; height: 100vh; margin: 0; overflow: hidden; display: flex; align-items: center; justify-content: center; text-align: center; }
.toggle{ cursor: pointer; background-color: #000; color:#fff; border: 0; border-radius: 4px; padding: 8px 12px; position: absolute; top: 100px; }
.toggle:focus{ outline: 0; } .clock-container{ display: flex; flex-direction: column; justify-content: space-between; align-items: center; border:2px solid #456; }
.clock{ position: relative; width:200px; height:200px; border: 2px red solid; }
.needle{ background-color: #000; position: absolute; top:50%; left:50%; height: 65px; width:3px; transform-origin: bottom center; transition: all 0.5s ease-in; }
.needle.hour{ transform: translate(-50%,-100%) rotate(0deg); background-color:#3c72e7; } .needle.minute{ transform: translate(-50%,-100%) rotate(0deg); background-color:#151616; } .needle.second{ transform: translate(-50%, -100%) rotate(0deg); height: 100px; background-color: #e74c3c; } .center-point{ background-color: #e74c3c; width:10px; height: 10px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); border-radius: 50%; }
.center-point::after{ content: ‘ ‘; background-color: #000; width: 5px; height: 5px; position:absolute; top: 50%; left: 50%; /* 实现垂直居中 */ transform: translate(-50%, -50%); border-radius: 50%; }
time{ font-size: 60px; } .date{ color: #aaa; font-size: 14px; letter-spacing: 0.3px; text-transform: uppercase; } .date .circle{ background-color: #000; color: #fff; border-radius: 50%; height: 18px; width: 18px; display: inline-flex; align-items: center; line-height: 18px; justify-content: center; transition: all 0.5s ease-in; font-size: 12px; }
*******JS********** const toggle = document.querySelector(‘.toggle’); const hourEl = document.querySelector(‘.hour’); const minuteEl = document.querySelector(‘.minute’); const secondEl = document.querySelector(‘.second’); const timeEl = document.querySelector(‘.time’); const dateEl= document.querySelector(‘.date’);
const days = [“Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”]; const months = [“Jan”, “Feb”, “Mar”, “Apr”,”May”,”Jun”, “Jul”, “Aug”, “Sep”,”Oct”, “Nov”, “Dec”]
toggle.addEventListener(‘click’,(e)=>{ const html = document.querySelector(‘html’); if(html.classList.contains(‘dark’)){ html.classList.remove(‘dark’); e.target.innerHTML=’Dark mode’; }else{ html.classList.add(‘dark’); e.target.innerHTML=”Light mode”; } })
function setTime(){ const time = new Date(); const month = time.getMonth(); const day = time.getDay();//返回一星期中的某一天 const date = time.getDate();//返回一个月中的某一天 const hours = time.getHours(); const hoursForClock = hours >=13? hours%12 :hours; const minutes = time.getMinutes(); const seconds = time.getSeconds(); const ampm = hours>=12 ? “PM” : “AM”; hourEl.style.transform = translate(-50%, -100%) rotate(${hoursForClock /11*360}deg)
; minuteEl.style.transform = translate(-50%, -100%) rotate(${minutes/59*360}deg)
; secondEl.style.transform = translate(-50%, -100%) rotate(${seconds/59*360}deg)
;
timeEl.innerHTML = ${hoursForClock}:${minutes < 10 ?
0${minutes} : minutes} ${ampm}
dateEl.innerHTML = ${days[day]}, ${months[month]} <span class="circle">${date}</span>
} setTime() setInterval(setTime, 1000);
1 2 3 4 5 ### Button Ripple Effect(按钮波纹效果) 演示参考地址:https://50projects50days.com/projects/button-ripple-effect/
HTML ****CLICK ME *****CSS *{ box-sizing: border-box;
} body{ background-color: black; color:rgb(86, 151, 209); font-family:’Roboto’, sans-serif; height: 100vh; display: flex; align-items: center; justify-content: center; margin:0; overflow: hidden;
} .btn{ background-color: rgb(126, 37, 138); padding :15px 20px; color:azure; border:0; font-size: 14px; text-transform: uppercase; letter-spacing: 2px; margin : 10px 0; position: relative; cursor: pointer; overflow: hidden; } .btn:focus{ outline: 0; }
button .circle{ position: absolute; background-color: #fff; width: 100px; height: 100px; border-radius: 50%; transform: translate(-50%,-50%) scale(0); animation: scale 0.5s ease-out; }
@keyframes scale{ to{ transform: translate(-50%, -50%) scale(3); opacity: 0; } }
JS *** let btns = document.querySelectorAll(“.btn”);
btns.forEach(btn=>{ btn.addEventListener(‘click’, function(e){
const x = e.clientX; const y = e.clientY;
const buttonTop = e.target.offsetTop; const buttonLeft = e.target.offsetLeft;
const xInside = x-buttonLeft; const yInside = y-buttonTop;
const circle = document.createElement(‘span’); circle.classList .add(‘circle’); circle.style.left = xInside+”px”; circle.style.top = yInside +”px”; this.appendChild(circle); // setTimeout(()=>circle.remove(), 500); }) })
1 2 3 4 5 ### Drag N Drop 演示参考地址:https://50projects50days.com/projects/drag-n-drop/
HTML *
*CSS *{ box-sizing: border-box; } body{ background-color: rgb(111, 168, 214); display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; overflow: hidden; }
.empty{ width: 150px; height: 150px; background-color: aliceblue; border:2px solid black; margin: 0 10px; }
.fill{ background-image: url(‘https://source.unsplash.com/random/150x150' ); height: 145px; width: 145px; cursor: pointer; }
.hold{ border: solid 5px rgb(209, 33, 33); } .hovered{ background-color: #333; border-color: white; border-style: dashed; }
@media(max-width:500px){ body{ flex-direction: column; } }
JS const fill = document.querySelector(‘.fill’); const empties = document.querySelectorAll(‘.empty’);
fill.addEventListener(‘dragstart’, dragStart); fill.addEventListener(‘dragend’, dragEnd);
empties.forEach(empty=>{ empty.addEventListener(‘dragover’, dragOver); empty.addEventListener(‘dragenter’, dragEnter); empty.addEventListener(‘dragleave’, dragLeave); empty.addEventListener(‘drop’, dragDrop); })
function dragStart() { console.log(this); this.className += ‘ hold’; setTimeout(() => this.className = ‘invisible’, 0); }
function dragEnd() { this.className = ‘fill’; }
function dragOver(e) { e.preventDefault() }
function dragEnter(e) { // e.preventDefault(); this.className += ‘ hovered’; }
function dragLeave(){ this.className=”empty”; }
function dragDrop(){ this.className = ‘empty’; console.log(this); this.append(fill); }
1 2 3 4 5 ### Drawing App 演示参考地址:https://50projects50days.com/projects/drawing-app/
HTML ***
-
10
+
X
**CSS *{ box-sizing: border-box; } body{ background-color: #f5f5f5; font-family: ‘Roboto’ sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; margin:0; }
canvas{ border: 2px solid steelblue; }
.toolbox{ background-color: steelblue; border: 1px solid slateblue; display: flex; width: 804px; padding: 1rem; }
.toolbox >*{ background-color: #fff; border: none; display: inline-block; align-items: center; justify-content: center; font-size: 2rem; height: 50px; width: 50px; margin: 0.25rem; padding: 0.25rem; cursor: pointer; }
.toolbox >*:last-child{ margin-left: auto; }
JS * const canvas = document.getElementById(‘canvas’); const increaseBtn = document.getElementById(‘increase’); const decreaseBtn = document.getElementById(‘decrease’); const sizeEl = document.getElementById(‘size’); const colorEl = document.getElementById(‘color’); const clearEl = document.getElementById(‘clear’);
const ctx = canvas.getContext(‘2d’);
let size = 10; let isPressed = false; colorEl.value = ‘black’; let color = colorEl.value; let x; let y;
canvas.addEventListener(‘mousedown’, (e)=>{ isPressed=true; x=e.offsetX; y = e.offsetY; })
canvas.addEventListener('mouseup', (e)=>{
isPressed=false;
x=undefined;
y=undefined;
})
canvas.addEventListener('mousemove', (e)=>{
if(isPressed){
const x2 = e.offsetX;
const y2 = e.offsetY;
drawCircle(x2, y2);
drawLine(x, y, x2,y2);
x=x2;
y=y2;
}
})
function drawCircle(x, y){
ctx.beginPath();
ctx.arc(x, y, size, 0, Math.PI*2);
ctx.fillStyle = color;
ctx.fill();
}
function drawLine(x, y, x2, y2) { ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(x2, y2); ctx.strokeStyle = color; ctx.lineWidth = size*2; ctx.stroke(); }
increaseBtn.addEventListener(‘click’,()=>{ size+=5; if(size>50){ size=50; } sizeEl.innerText = size; })
decreaseBtn.addEventListener(‘click’, ()=>{ size-=5; if(size<5){ size = 5; } sizeEl.innerText = size; })
colorEl.addEventListener(‘change’, (e)=>{ color = e.target.value })
clearEl.addEventListener(‘click’, ()=>{ ctx.clearRect(0,0, canvas.width, canvas.height); })
1 2 3 4 5 ### kinetic-loader(动力轮车) 演示参考地址:https://50projects50days.com/projects/kinetic-loader/
**HTML
css ** *{ box-sizing: border-box; }
body{ background-color: #2c3e50; display: flex; align-items: center; justify-content: center; height: 100vh; overflow: hidden; margin: 0; }
.kinetic{ position: relative; height: 80px; width: 80px; background-color: rgb(218, 186, 100); }
.kinetic::after, .kinetic::before{ content: ‘’; position: absolute; top: 0; left: 0; width:0; height: 0; border: 80px solid transparent; border-bottom-color: #fff; border-left-color: rgb(231, 123, 123); animation: rotateA 2s linear infinite 0.5s; }
.kinetic::before{ transform: rotate(90deg); animation: rotateB 2s linear infinite ; }
@keyframes rotateA { 0%, 25% { transform: rotate(0deg); }
50%, 75% { transform: rotate(180deg); }
100% { transform: rotate(260deg); } }
@keyframes rotateB { 0%, 25% { transform: rotate(90deg); }
50%, 75% { transform: rotate(270deg); }
100% { transform: rotate(450deg); } }
*JS none
1 2 3 ### content placehoder 内容占位符
HTML **
CSS ***
{ box-sizing: border-box; }
body { background-color: #ecf0f1; font-family: ‘Roboto’, sans-serif; display: flex; align-items: center; justify-content: center; height: 100vh; overflow: hidden; margin: 0; }
img { max-width: 100%; }
.card { box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); border-radius: 10px; overflow: hidden; width: 350px; }
.card-header { height: 200px; }
.card-header img { object-fit: cover; height: 100%; width: 100%; }
.card-content { background-color: #fff; padding: 30px; }
.card-title { height: 20px; margin: 0; }
.card-excerpt { color: #777; margin: 10px 0 20px; font-size: 14px; }
.author { display: flex; }
.profile-img { border-radius: 50%; overflow: hidden; height: 40px; width: 40px; }
.author-info { display: flex; flex-direction: column; justify-content: space-around; margin-left: 10px; width: 100px; }
.author-info small { color: #aaa; margin-top: 5px; }
.animated-bg { background-image: linear-gradient( to right, #f6f7f8 0%, #edeef1 10%, #d5dbe2 20%, #dde2e7 100% ); background-size: 200% 100%; animation: bgPos 1s linear infinite; }
.animated-bg-text { border-radius: 50px; display: inline-block; margin: 0; height: 10px; width: 100%; }
@keyframes bgPos { 0% { background-position: 90% 0; } 100% { background-position: -150% 0; } }
**JS const header = document.getElementById(‘header’) const title = document.getElementById(‘title’) const excerpt = document.getElementById(‘excerpt’) const profile_img = document.getElementById(‘profile_img’) const name = document.getElementById(‘name’) const date = document.getElementById(‘date’)
const animated_bgs = document.querySelectorAll(‘.animated-bg’) const animated_bg_texts = document.querySelectorAll(‘.animated-bg-text’)
setTimeout(getData, 2500)
function getData() { header.innerHTML = ‘ ‘ title.innerHTML = ‘Lorem ipsum dolor sit amet’ excerpt.innerHTML = ‘Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolore perferendis’ profile_img.innerHTML = ‘ ‘ name.innerHTML = ‘John Doe’ date.innerHTML = ‘Oct 08, 2020’
animated_bgs.forEach((bg) => bg.classList.remove(‘animated-bg’)) animated_bg_texts.forEach((bg) => bg.classList.remove(‘animated-bg-text’)) }
1 2 3 4 5 ### Sticky Navbar 演示参考链接:https://50projects50days.com/projects/sticky-navbar/
**HTML
Welcome To My Website
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Maiores, consequuntur?
Content One
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Ratione dolorem voluptates eveniet tempora ut cupiditate magnam, sapiente, hic quo in ipsum iste soluta eaque perferendis nihil recusandae dolore officia aperiam corporis similique. Facilis quos tempore labore totam! Consectetur molestiae iusto ducimus error reiciendis aspernatur dolor, modi dolorem sit architecto, voluptate magni sunt unde est quas? Voluptates a dolorum voluptatum quo perferendis aut sit. Aspernatur libero laboriosam ab eligendi omnis delectus earum labore, placeat officiis sint illum rem voluptas ipsum repellendus iste eius recusandae quae excepturi facere, iure rerum sequi? Illum velit delectus dicta et iste dolorum obcaecati minus odio eligendi!
Content Two
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Pariatur provident nostrum possimus inventore nisi laboriosam consequatur modi nulla eos, commodi, omnis distinctio! Maxime distinctio impedit provident, voluptates illo odio nostrum minima beatae similique a sint sapiente voluptatum atque optio illum est! Tenetur tempora doloremque quae iste aperiam hic cumque repellat?
**CSS *{ box-sizing: border-box; margin: 0; padding: 0; }
body{ font-family: ‘Open Sans’ ,sans-serif; color:#222; padding-bottom: 50px; }
.container{ max-width: 1200px; margin: 0 auto; }
.nav{ background-color: #222; position: fixed; top:0; left:0; right: 0;
transition: all 0.3s ease-in-out; }
.nav .container { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; transition: all 0.3s ease-in-out; }
.nav ul{ display: flex; justify-content: center; list-style-type: none; align-items: center; }
.nav a{ color:#fff; text-decoration: none; padding: 7px 15px; transition: all 0.3s ease-in-out; }
.nav.active{ background-color: #fff; box-shadow: 0 2px 10px rgba(0,0,0,0.3); }
.nav.active a{ color:#000; }
.nav.active .container { padding:1px 0; height: 70px; }
.nav a.current, .nav a:hover{ color: #c0392b; font-weight: bold; }
.hero{ background-image: url(‘https://images.pexels.com/photos/450035/pexels-photo-450035.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260' ); background-repeat: no-repeat; background-size: cover; background-position: bottom center; height: 100vh; color:#fff; display:flex; align-items: center; justify-content: center; text-align: center; position: relative; margin-bottom: 20px; z-index: -1; }
.hero::before{ content: ‘’; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); z-index: -2; }
.hero h1{ font-size: 46px; margin: -20px 0 20px; }
.hero p{ font-size: 20px; letter-spacing: 1px; }
.content h2, .content h3{ font-size: 150%; margin: 20px 20px; }
.content p{ color: #555; line-height: 30px; letter-spacing: 1.2px; padding-left: 20px;; }
*JS const nav = document.querySelector(‘.nav’) window.addEventListener(‘scroll’, fixNav)
function fixNav() { if(window.scrollY >300) { nav.classList.add(‘active’) } else { nav.classList.remove(‘active’) } }
1 2 3 4 5 ### Double Vertical Slider 演示参考地址: https://50projects50days.com/projects/double-vertical-slider/
***HTML
Flying eagle
in the sunset
<div style="background-color: #2A86BA">
<h1>Nature flower</h1>
<p>all in pink</p>
</div>
<div style="background-color: #252E33">
<h1>Bluuue Sky</h1>
<p> with it's mountains</p>
</div>
<div style="background-color: #FFB866">
<h1>Lonely castle</h1>
<p>in the wilderness</p>
</div>
*CSS *{ box-sizing: border-box; margin: 0; padding: 0; }
body{ font-family: ‘Open Sans’, sans-serif; height: 100vh; }
.slider-container{ position: relative; color:white; width:100vw; height: 100vh; overflow: hidden;
}
.left{ position: absolute; width:35%; height:100%; top:0; left: 0; transition: transform 0.5s ease-in-out; } .left div{ height: 100%; display: flex; align-items: center; justify-content: center; flex-direction: column; } .left h1{ margin-top: -30px; margin-bottom: 10px; }
.right{ position: absolute; top:0; left:35%; height:100%; width: 65%; transition: transform 0.5s ease-in-out; } .right div{ width: 100%; height: 100%; background-size: cover; background-position: center center; background-repeat: no-repeat; }
button{ background-color: #fff; position: absolute; top:50%; left: 35%; padding: 10px 10px; font-size: 18px; border: none; cursor: pointer; z-index: 100; }
.up-button{ transform: translateY(-100%); border-top-right-radius: 5px; border-bottom-right-radius: 5px; }
.down-button{ transform: translateX(-100%); border-bottom-left-radius: 5px; border-top-left-radius: 5px; }
JS const sliderContainer = document.querySelector(“.slider-container”); const leftBtn = document.querySelector(‘.up-button’); const rightBtn = document.querySelector(‘.down-button’); const sliderRight = document.querySelector(‘.right’); const sliderLeft = document.querySelector(‘.left’); const slidersLength = sliderRight.querySelectorAll(‘div’).length;
let sliderActiveIndex=0; sliderRight.style.top = ${-(slidersLength - 1) * 100}vh
;
leftBtn.addEventListener(‘click’, ()=>changeSlide(‘up’)); rightBtn.addEventListener(‘click’, ()=>changeSlide(‘down’));
const changeSlide=(direnction)=>{ const sliderHeight = sliderContainer.clientHeight; if(direnction===’up’){ sliderActiveIndex++; if(sliderActiveIndex>slidersLength-1){ sliderActiveIndex=0; } }else if(direnction===”down”){ sliderActiveIndex–; if(sliderActiveIndex<0){ sliderActiveIndex=slidersLength-1; }
}
sliderRight.style.transform = translateY(${sliderActiveIndex*sliderHeight}px)
; sliderLeft.style.transform = translateY(-${sliderActiveIndex*sliderHeight}px)
;
}
1 2 3 4 5 ### toast notification 演示参考地址:https://50projects50days.com/projects/toast-notification/
HTML **
Show Notification
****CSS 8 *{ box-sizing: border-box; margin: 0; padding: 0; }
body{
background-color: rgb(150, 50, 243);
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 100vh;
overflow: hidden;
margin: 0;
position: relative;
}
button{ padding: 15px 7px; border-radius: 6px; border: 0ch; color:rgb(76, 15, 145); text-align: center; font-weight: bold; cursor: pointer; }
button:focus{ outline: none; }
button:focus{ transform: scale(0.98); }
#toasts{ position: fixed; bottom: 10px; right: 10px; display: flex; flex-direction: column; align-items: flex-end; background-color: rgb(209, 69, 13); }
.toast{ background-color: #fff; border-radius: 5px; padding: 1rem 2rem; margin:0.5rem; } .toast.info{ color:rebeccapurple; }
.toast.success{ color: green; }
.toast.error{ color: red; }
JS const button = document.querySelector(‘button’); const toasts = document.getElementById(‘toasts’);
const message = [‘Message One’, ‘Message Two’ ,’Message three’, ‘Message Four’]; const types = [‘info’, ‘success’, ‘error’];
button.addEventListener(‘click’, ()=>createNotification())
function createNotification(type=null, message=null){ const notif = document.createElement(‘div’); notif.classList.add(‘toast’); notif.classList.add(type ? type : getRandomType()); notif.innerText =message ? message: getRandomMessage(); toasts.appendChild(notif);
setTimeout(() => { notif.remove(); }, 3000); }
function getRandomType(){ return types[Math.floor(Math.random()*types.length)]; }
function getRandomMessage(){ return message[Math.floor(Math.random()*message.length)] }
**HTML
CSS ******* *{ margin: 0; padding: 0; box-sizing: border-box; }
body{ background-color: rgba(37, 22, 19, 0.795); display: flex; align-items: center; justify-content: center; flex-direction: column; height:100vh; margin: 0; overflow: hidden;
}
input{ padding: 15px 10px; width: 700px; border-radius: 7px; border: none; background-color: rgb(95, 28, 121); margin-bottom: 20px; box-shadow: 0 5px 10px rgba(154, 160, 185, 0.05), 0 15px 40px rgba(0, 0, 0, 0.1); color:white } input::placeholder{ color:aliceblue }
input:focus{ outline: none; }
.card{ max-width: 800px; background-color: #4c2885; border-radius: 20px; box-shadow: 0 5px 10px rgba(154, 160, 185, 0.05), 0 15px 40px rgba(0, 0, 0, 0.1); margin: 0.5rem 0rem; padding: 3rem; display: flex; }
.avatar{ border-radius: 50%; border: 10px solid #2a2a72; height: 150px; width: 150px; }
.user-info{ color:#eee; margin-left: 2rem; }
.user-info p{ border-bottom: 15px; } .user-info h2{ margin-bottom: 5px; }
.user-info ul{ list-style-type: none; display: flex; justify-content: space-between; padding: 0; max-width: 400px; margin-bottom: 5px; }
.user-info ul li{ display: flex; align-items: center; }
.user-info ul li strong{ font-size: 0.9rem; margin-left: 0.5rem; }
.repo{ text-decoration: none; color: #fff; background-color: #212a72; font-size: 0.7rem; padding: 0.25rem 0.5rem; margin-right: 0.5rem; margin-bottom: 0.5rem; display: inline-block; }
@media(max-width:500px){ .card{ flex-direction:column; align-items: center; } form{ max-width:400px; } } }
***JS const APIURL= ‘http://api.github.com/users/'
const main = document.getElementById(‘main’); const form = document.querySelector(‘.form’); const search = document.getElementById(‘search’);
async function getUser(username) { try{ const { data } =await axios(APIURL + username); createUserCard(data); getRepos(username); }catch(error){ if(error.response.status ===404){ createErrorCard(‘查询不到相关信息’); } } } async function getRepos(username){ try { const {data} =await axios(APIURL + username+’/repos?sort=created’); addReposToCard(data);
} catch (error) { createErrorCard(‘查询错误’); } }
function createUserCard(user){ const cardHtml = <div class="card"> <div > <img src="${user.avatar_url}" alt="${user.name}" class="avatar"> </div> <div class="user-info"> <h1>${user.name}</h1> <p> ${user.bio}</p> <ul> <il>${user.followers}<strong>Followers</strong></li> <il>${user.followering}<strong>Followering</strong></li> <il>${user.public_repos}<strong>Repos</strong></li> </ul> <div id="repos"></div> </div> </div>
main.innerHTML = cardHtml; }
function createErrorCard(msg){ const cardHtml = <div class="card"> <h1>${msg}</h1> </div>
main.innerHTML = cardHtml; }
function addReposToCard(repos){ const reposEl = document.getElementById(‘repos’); repos.slice(0, 5).forEach(repo=>{ let repoEl =document.createElement(‘a’); repoEl.classList.add(‘repo’); repoEl.href =repo.html_url; repoEl.innerHTML = repo.name; repoEl.target = “_blank”; reposEl.appendChild(repoEl); }) }
form.addEventListener(‘submit’, (e)=>{ e.preventDefault(); const user = search.value; if(user){ getUser(user); search.value=””; }
})
HTML
Double click on the image to it
You liked it 0 times
CSS * *{ box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: ‘Oswald’, sans-serif; text-align: center; overflow: hidden; margin: 0; }
h3 { margin-bottom: 0; text-align: center; }
small { display: block; margin-bottom: 20px; text-align: center; }
.fa-heart { color: red; }
.loveMe { height: 440px; width: 300px; background: url(‘https://images.unsplash.com/photo-1504215680853-026ed2a45def?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=334&q=80' ) no-repeat center center/cover; margin: auto; cursor: pointer; max-width: 100%; position: relative; box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22); }
.loveMe .fa-heart { position: absolute; animation: grow 0.6s linear; transform: translate(-50%, -50%) scale(0); }
@keyframes grow { to { transform: translate(-50%, -50%) scale(10); opacity: 0; } }
*JS let times = document.getElementById(‘times’); const div = document.querySelector(‘.loveMe’); let clickTimes = 0; let resetTime = 0; div.addEventListener(‘click’,(e)=>{ clickTimes++; resetTime++ times.innerText = clickTimes; if(resetTime==2){ resetTime=0; // const heart = document.createElement(‘i’) // heart.classList.add(‘fas’) // heart.classList.add(‘fa-heart’) // div.appendChild(heart); createHeart(e); }
})
const createHeart = (e) => { const heart = document.createElement(‘i’) heart.classList.add(‘fas’) heart.classList.add(‘fa-heart’) console.log(e);
const x = e.clientX
const y = e.clientY
const leftOffset = e.target.offsetLeft
const topOffset = e.target.offsetTop
const xInside = x - leftOffset
const yInside = y - topOffset
heart.style.top = `${yInside}px`
heart.style.left = `${xInside}px`
div.appendChild(heart);
setTimeout(() => heart.remove(), 1000)
}
1 2 3 ### Password Generator
*HTML
Password Generator
Generate Password
***CSSS *{ box-sizing: border-box; margin: 0; padding: 0; }
body{ background-color: rgb(127, 127, 226); display: flex; align-items: center; justify-content: center; height: 100vh; overflow: hidden; margin:0; flex-direction: column; color: white; }
.container{ background-color: blueviolet; padding: 10px 20px; box-shadow: 0px 2px 10px rgba(255, 255, 255, 0.2); width: 400px; display: flex; align-items: center; justify-content: center; flex-direction: column; } h1{ font-size: 24px; } .result-container{ display: flex; justify-content: space-between; width:100%; background-color: black; padding: 7px 7px;
}
.result-container span{ display: inline-block; width: 75%;
padding: 7px; }
.result-container button{ height: 40px; width:40px; background-color: rgb(151, 63, 235); font-size: 25px; color:aliceblue; margin-right: 0; border: none; } .result-container button i{ font-size: 23px; }
.setting{ width:100%;
} .setting .setting{ display: flex; margin-top: 15px; justify-content: space-between; width: 100%; } .setting label{ margin-right: 98px; } .setting input{ margin-right: 0px; }
.btn{ border: none; cursor: pointer; } .btn:focus{ outline: none;
} .btn-large{ background-color:rgb(74, 6, 105); padding: 10px 20px; margin: 15px 0; width: 100%; color: white }
JS **
const resultEl = document.getElementById(‘result’); const clipboardEl = document.getElementById(‘clipboard’) const lengthEl = document.getElementById(‘length’); const uppercaseEl = document.getElementById(‘uppercase’); const lowercaseEl = document.getElementById(‘lowercase’); const numbersEl = document.getElementById(‘numbers’); const symbolsEl = document.getElementById(‘symbols’); const generateEl = document.getElementById(‘generate’);
//点击复制按钮复制生成的密码 clipboardEl.addEventListener(‘click’ ,()=>{ const textarea = document.createElement(‘textarea’); const password = resultEl.innerHTML; if(!password) return; textarea.value= password; document.body.appendChild(textarea); textarea.select(); document.execCommand(‘copy’); textarea.remove(); alert(‘已成功复制代码’);
})
//点击生成密码按钮生成密码
generateEl.addEventListener(‘click’,()=>{ const length = +lengthEl.value; const hasLower = lowercaseEl.chcked; const hasUpper = uppercaseEl.chcked; const hasNumber = numbersEl.chcked; const hasSymbol = symbolsEl.checked; resultEl.innerText = generatePassword(hasLower,hasUpper,hasNumber,hasSymbol, length) console.log(resultEl.value); })
//存储所有的随机函数 const randomFunc = { lower: getRandomLower, upper: getRandomUpper, number: getRandomNumber, symbol: getRandomSymbol }
//生成代码函数 function generatePassword(lower, upper, number, symbol, length){ let generatedPassword =’’; let typesCount = lower+ upper+ number + symbol; if(typesCount==0) return ‘’; const typesArr=[{lower}, {upper}, {number},{ symbol}];
for(let i= 0; i<length; i++){ typesArr.forEach(type=>{ const funcName = Object.keys(type)[0] generatedPassword += randomFuncfuncName }) } const finalPassword = generatedPassword.slice(0, length) return finalPassword; }
function getRandomLower() { return String.fromCharCode(Math.floor(Math.random() * 26) + 97) }
function getRandomUpper() { return String.fromCharCode(Math.floor(Math.random() * 26) + 65) }
function getRandomNumber() { return String.fromCharCode(Math.floor(Math.random() * 10) + 48) }
function getRandomSymbol() { const symbols = ‘!@#$%^&*(){}[]=<>/,.’ return symbols[Math.floor(Math.random() * symbols.length)] }
HTML **
How do you want your project to be?
*****CSS body{ font-family: ‘Robot’, sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; overflow: hidden; margin: 0; }
.toggle-container { display: flex; align-items: center; margin: 10px 0; width: 200px; }
.toggle-container .label{ width: 80px; height :40px; position: relative; border-radius: 50px; background-color:rgb(192, 192, 186); margin: 0 10px; }
.toggle-container .label .ball{ position: absolute; top: 3px; left: 3px; width: 34px; height:34px; background-color: aliceblue; border-radius: 50%; animation: slideOff 0.3s linear forwards; } .toggle-container .toggle{ visibility: hidden; }
.toggle:checked+.label{ background-color: rgb(171, 113, 226); }
.toggle:checked +.label .ball{ animation: slideOn 0.3s linear forwards; } @keyframes slideOff{
0%{
transform: translateX(40px) scale(1);
}
50%{
transform: translateX(20px) scale(1.2);
}
100%{
transform: translateX(0px) scale(1);
}
}
@keyframes slideOn{ 0%{ transform: translateX(0px) scale(1); }
50%{ transform: translateX(20px) scale(1.2); }
100%{ transform: translateX(40px) scale(1); } }
*JS const toggles = document.querySelectorAll(‘.toggle’); const good = document.getElementById(‘good’); const cheap = document.getElementById(‘cheap’); const fast = document.getElementById(‘fast’);
toggles.forEach(toggle=>toggle.addEventListener(‘click’,(e)=>{ if(good.checked&&cheap.checked&&fast.checked){ if(e.target==cheap){ good.checked=false; }
if(e.target===fast){
cheap.checked=false;
}
if(e.target===good){
fast.checked=false;
}
} }))
1 2 3 4 5 ### Notes App 参考演示地址: https://50projects50days.com/projects/notes-app/
HTML + Add note
CSS * *{ box-sizing: border-box; padding: 0; margin: 0; }
body{ background-color: rgb(86, 194, 236); display: flex; justify-content: flex-start; flex-wrap: wrap; margin: 60px 40px;
}
.add{ position: fixed; top: 15px; right:20px; padding: 6px 15px; background-color: rgb(231, 119, 74); border:none; color:aliceblue; cursor: pointer; }
.add:active{ transform: scale(0.98); }
.note{ background-color: #fff; box-shadow: 0 0 10px 4px rgba(0, 0, 0, 0.1); margin: 30px 20px; height: 400px; width: 300px;
}
.tools{ background-color: rgba(236, 124, 33, 0.849); padding: 10px 12px; border: none; display: flex; justify-content: flex-end;
}
.tools button{
border: none; background-color: transparent; cursor: pointer; margin-left: 0.5rem; }
.tools button i{ color:white; cursor: pointer; font-size: 24px; }
.note textarea{ border:none; outline: none; font-family: inherit; height: 400px; width:100%; padding: 20px; }
.main{ padding: 20px; width:100%; word-wrap: break-word;
}
.hidden{ display: none; }
JS const addBtn = document.querySelector(‘.add’);
//localstage会将之前存储的字段显示出来,要不然打开页面以前的数据就没法显示 const notes =JSON.parse(localStorage.getItem(‘notes’)); if(notes){ notes.forEach(note=>addNewNote(note)); }
addBtn.addEventListener(‘click’, ()=>addNewNote())
function addNewNote(text=””) { const note = document.createElement(‘div’); note.classList.add(‘note’); document.body.appendChild(note) note.innerHTML = <div class="tools"> <button class="edit"> <i class="iconfont icon-bianji"></i></button> <button class="delete" > <i class="iconfont icon-shanchu"></i></button> </div> <div class="main ${text? "" : "hidden"}"></div> <textarea class ="${text ? "hidden" : ""}"></textarea>
const editBtn = note.querySelector(“.edit”); const deleteBtn = note.querySelector(“.delete”); const main = note.querySelector(‘.main’); const textAarea = note.querySelector(‘textarea’); //把缓存里的notesl里的值传入到textAarea和main中。 textAarea.value = text; main.innerHTML= text;
editBtn.addEventListener(‘click’, ()=>{ main.classList.toggle(‘hidden’); textAarea.classList.toggle(‘hidden’); })
deleteBtn.addEventListener(‘click’, ()=>{ note.remove(); updateLS(); })
textAarea.addEventListener(‘input’, (e)=>{
console.log(e.target); main.innerHTML=e.target.value; updateLS(); })
} //更新localStorage函数
function updateLS(){ const textnotes= document.querySelectorAll(‘textarea’); let notes = []; textnotes.forEach(textnote=>{ notes.push(textnote.value); localStorage.setItem(‘notes’, JSON.stringify(notes)); })
}
1 2 3 4 5 ### Animated Countdown 演示参考地址:https://50projects50days.com/projects/animated-countdown/
HTML **
GO
Replay
CSS * body{ font-family: ‘Roboto’ ,sans-serif; margin: 0; height: 100vh; overflow: hidden; }
h4{ font-size: 20px; margin: 5px; text-transform: uppercase; }
.counter{ position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; }
.counter.hide{ transform: translate(-50%,-50%) scale(0); animation: hide 0.2s ease-out; }
@keyframes hide{ 0%{ transform: translate(-50%, -50%) scale(1); }
100%{ transform: translate(-50%, -50%) scale(0); } }
.nums{ color:#3498db; font-size: 50px; position: relative; overflow: hidden; width: 250px; height: 50px;
}
.nums span{ position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%) rotate(120deg); transform-origin: bottom center; }
.nums span.in{ transform: translate(-50%, -50%) rotate(0deg); animation: goIn 0.5s ease-in-out; }
.nums span.out{ animation: goOut 0.5s ease-in-out; }
@keyframes goIn{ 0%{ transform: translate(-50%, -50%) rotate(120deg); }
30%{ transform:translate(-50%, -50%) rotate(-20deg); } 60%{ transform:translate(-50%, -50%) rotate(10deg); } 100%{ transform:translate(-50%, -50%) rotate(10deg); } }
@keyframes goOut{ 0%{ transform: translate(-50%, -50%) rotate(0deg); }
60%{ transform: translate(-50%, -50%) rotate(20deg); }
100%{ transform: translate(-50%, -50%) rotate(-120deg); } }
.final{ position:fixed; top: 50%; left: 50%; /* 先隐藏起来 */ transform: translate(-50%, -50%) scale(0); text-align: center; }
.final.show{ transform: translate(-50%,-50%) scale(1); animation: show 0.2s ease-out; }
@keyframes show{
0%{ transform: translate(-50%, -50%) scale(0); }
30%{ transform: translate(-50%, -50%) scale(1.4); }
100%{ transform: translate(-50%, -50%) scale(1); }
}
JS **** const counter = document.querySelector(‘.counter’); const nums = document.querySelectorAll(‘.nums span’); const final = document.querySelector(‘.final’); console.log(final); const replay = document.getElementById(‘replay’);
runAnimation();
function runAnimation(){ nums.forEach((num,index)=>{ const lastindex = nums.length-1; num.addEventListener(‘animationend’ ,(e)=>{ if(e.animationName==’goIn’ && index!==lastindex){
num.classList.remove('in');
num.classList.add('out');
}
else if(e.animationName==='goOut' && num.nextElementSibling){
num.nextElementSibling.classList.add('in')
}else{
counter.classList.add('hide');
final.classList.add('show');
}
})
}) }
replay.addEventListener(‘click’ ,()=>{ resetAnimation(); runAnimation(); })
function resetAnimation() {
final.classList.remove(‘show’); counter.classList.remove(‘hide’);
nums.forEach((num)=>{ num.classList.value=’’; })
nums[0].classList.add(‘in’); }
1 2 3 4 5 ### mobile Tab Navigation 演示参考地址:https://50projects50days.com/projects/mobile-tab-navigation/
**HTML
*CSS body{ background-color: #B88ACB; margin: 0; display: flex; align-items: center; justify-content: center; font-family: sans-serif; font-style: 16px; color:rgb(150, 149, 149)
}
.phone{ display: flex; flex-direction: column; align-items: center; justify-content: center; border: 3px solid #fff; border-radius: 15px; height: 600px; width: 400px; overflow: hidden; }
.phone .img{ position: relative; height: 90%; overflow: hidden; width:400px }
.img .content{ position: absolute; top:0; left: 0; height: 100%; width: 100%; object-fit: cover;
opacity: 0;
transition: opacity 0.4s ease }
.img .content.show{ opacity: 1; }
nav{ width: 100%; height: 10%;
}
nav ul{ list-style-type: none; display: flex; align-items: center; justify-content: space-between; text-align: center; padding: 12px 10px ; background-color: #fff;
} nav ul li{ cursor: pointer; }
nav ul li:hover{ color:#c580e2; } nav ul li.active{ color:#b963dd }
*****JS const imgs = document.querySelectorAll(‘.content’); const lis = document.querySelectorAll(‘li’);
lis.forEach((li, index)=>{ li.addEventListener(‘click’, ()=>{ hideAllImages(); hideAllLis()
li.classList.add('active');
imgs[index].classList.add('show')
}) })
function hideAllImages(){ imgs.forEach(img=>{ img.classList.remove(‘show’); }) }
function hideAllLis() { lis.forEach(li=>{ li.classList.remove(‘active’); }) }
1 2 3 4 5 6 7 8 9 10 11 12 13 ### Password strength Backgrond 参考演示地址: https://50projects50days.com/projects/password-strength-background/ #### 该项目是用tailwindcss框架写的,用的时候要插入引用 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/1.8.11/tailwind.min.css" integrity="sha512KO1h5ynYuqsFuEicc7DmOQc+S9m2xiCKYlC3zcZCSEw0RGDsxcMnppRaMZnb0DdzTDPaW22ID/gAGCZ9i+RT/w=="crossorigin="anonymous" />
*******HTML *********
CSS *
body{ display: flex; align-items: center; justify-content: center; flex-direction: column; height: 100vh; overflow: hidden; margin: 0; }
.background{ background: url(‘https://images.unsplash.com/photo-1556745757-8d76bdb6984b' ) no-repeat center/cover; position: absolute; top:-20px; left:-20px; right: -20px; bottom: -20px; z-index: -1; filter: blur(20px); }
JS * const bgImg = document.querySelector(‘.background’); const password = document.getElementById(‘password’);
password.addEventListener(‘input’ ,(e)=>{ const input = e.target.value const length = input.length const blurValue = 20 - length * 2 bgImg.style.filter = blur(${blurValue}px)
})
1 2 3 4 5 ### 3D background Boxes 参考演示地址: https://50projects50days.com/projects/3d-background-boxes/
HTML
Magic 🎩
CSS *
body { background-color: #fafafa; font-family: ‘Roboto’, sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; overflow: hidden; }
.magic{ background-color: #f9ca24; color:#fff; font-family: ‘Poppins’ , sans-serif; border: 0; border-radius: 3px; font-size: 16px; padding: 12px 12px; cursor: pointer; position: fixed; top: 20px; letter-spacing: 1px; box-shadow: 0 3px rgba(249, 202,36, 0.5); z-index: 100; }
.magic:focus{ outline: none; }
.magic:active{ box-shadow: none; transform: translateY(2px); }
.boxes{ display: flex; flex-wrap: wrap; justify-content: space-around; height: 500px; width: 500px; position: relative; transition: 0.4s ease; }
.boxes.big{ width: 600px; height: 600px }
.boxes.big .box{ transform: rotateZ(360deg);
}
.box{ background-image: url(‘https://media.giphy.com/media/EZqwsBSPlvSda/giphy.gif' ); position: relative; background-size: 500px 500px; background-repeat: no-repeat; width: 125px; height: 125px; transition: 0.3s ease;
}
.box:before{ content: ‘’; background-color: #f9ca24; position: absolute; bottom: -15px; left: 8px; height: 15px; width: 100%; transform: skewX(45deg); }
.box::after{ content: ‘’; background-color: #ebd281; position: absolute; top: 8px; right: -15px; width: 15px; height: 100%; transform: skewY(45deg); }
***JS
const boxesContainer = document.getElementById(‘boxes’) const btn = document.getElementById(‘btn’)
btn.addEventListener(‘click’, () => boxesContainer.classList.toggle(‘big’))
function createBoxes() { for (let i = 0; i < 4; i++) { for (let j = 0; j < 4; j++) { const box = document.createElement(‘div’) box.classList.add(‘box’) box.style.backgroundPosition = ${-j * 125}px ${-i * 125}px
boxesContainer.appendChild(box) } } }
createBoxes()
1 2 3 4 5 ### Verify Account Ui 演示参考链接: https://50projects50days.com/projects/verify-account-ui/
HTML *
******CSS body{ display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; overflow: hidden; margin: 0; }
.container{ height: 100%; width: 80%; border-left:3px solid #000; border-right:3px solid #000; display: flex; flex-direction: column; align-items: center; text-align: center; }
h1{ font-size: 40px; font-weight: 600; margin-top: 20px; }
h4{ font-size: 20px; max-width: 600px; margin-top: 20px; font-weight: 200; }
.input-container{ display: flex;
align-items: center; width: 100%; margin-top: 50px; justify-content: ;
}
.input{ border:1px solid rgb(211, 207, 207); width:136px; height: 160px; line-height: 160px; /* justify-content: space-between; */ text-align: center; margin: 9px; font-size: 75px; border-radius: 7px; -moz-appearance: textfield; }
.input::-webkit-outer-spin-button, .input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.input:valid{ border-color: #3498db; box-shadow: 0 10px 10px -5px rgba(0,0,0,0.25); }
.p{ max-width: 600px; margin-top: 60px; background-color: rgb(235, 215, 192); border-radius: 10px; padding: 13px 20px; text-align: center; line-height: 30px; }
@media(max-width:900px){ .input-container{ flex-wrap: wrap; }
@media(max-width:600px){ .input-container{ flex-wrap: wrap; }
.input{ font-size: 60px; height: 80px; max-width: 70px; } } }
JS ****** const inputs = document.querySelectorAll(‘input’); inputs[0].focus(); inputs.forEach((input ,index) => { input.addEventListener(‘keydown’, (e)=>{ if(e.key>=0 && e.key<=9){ inputs[index].value =’’; //每次输入后将值置空,保证下次输入的时候不会保存原先输入的值。 setTimeout(() => { if(index<inputs.length-1) inputs[index+1].focus(); }, 10); } else if(e.key==’Backspace’){ setTimeout(() => { inputs[index-1].focus(); }, 10); } }) });
1 2 3 4 5 ### Live User Filter 演示参考地址:https://50projects50days.com/projects/live-user-filter/
**********HTML ***********
***********CSS ************ body{ background-color: #f8f9fd; font-family: ‘Roboto’ , sans-serif; display: flex; align-items: center; justify-content: center; height: 100vh; overflow: hidden; margin-top: 10px; margin-bottom: 10px; }
.container{ border-radius: 5px; box-shadow: 3px 3px 10px rgba(0,0,0, 0.2); overflow: hidden; width: 400px; overflow-y: auto;
}
.title{ margin: 0; font-size: 26px; }
.subtitle{ display: inline-block; margin: 5px 0 20px; opacity: 0.8; font-size: 16px; }
.header{ background-color: #3e57db; color:#fff; padding: 30px 20px; }
.header input{ background-color: rgba(0,0,0,0.3); border: 0; border-radius: 50px; color: #fff; font-size: 14px; padding: 10px 15px; width: 100%; }
.header input:focus{ outline: none; }
.user-list{ list-style-type: none; background-color: #fff; width: 100%; max-height: 400px; overflow-y: auto; }
.user-list li{ display: flex; padding: 10px 12px; width: 100%; } .user-list:last-child{ padding-bottom: 20px; background-color: transparent; }
.user-list li img{ border-radius: 50%; height: 90px; width:90px; object-fit: cover; margin-left: 10px; }
.user-list .user-info{ margin-left: 10px; }
.user-list .user-info h4{ margin: 0 0 10px; font-size: 20px; font-weight: 600; }
.user-list .user-info p{ font-size: 14px; }
.user-list li:not(:last-of-type){ border-bottom: 1px solid #eee; }
.user-list li.hide{ display: none; }
***JS const filter = document.getElementById(‘filter’); const result = document.getElementById(‘result’); const resultItem = [];
getData(); filter.addEventListener(‘input’ , (e)=>{filterData(e.target.value)});
async function getData(){ const res = await fetch(‘https://randomuser.me/api?results=50' ); let {results} = await res.json(); console.log(results); result.innerHTML=’’;
results.forEach(user => { const li = document.createElement(‘li’); li.innerHTML = <img src ="${user.picture.large}" alt="${user.name.first}"> <div class="user-info"> <h4>${user.name.first} ${user.name.last}</h4> <p> ${user.location.city}, ${user.location.country}</p> </div>
result.appendChild(li); resultItem.push(li) });
}
function filterData(searchValue) { resultItem.forEach(item=>{ if(item.innerText.toLowerCase().includes(searchValue.toLowerCase())){ item.classList.remove(‘hide’); }else{ item.classList.add(‘hide’); } }) }
1 2 3 4 5 ### Feedback UI Design 演示参考地址: https://50projects50days.com/projects/feedback-ui-design/
***HTML
How satisfied are you with our
customer support performance?
Unhappy
<li>
<img src="https://image.flaticon.com/icons/svg/187/187136.svg">
<p>Neutral</p>
</li>
<li>
<img src="https://image.flaticon.com/icons/svg/187/187133.svg">
<p>Satisfied</p>
</li>
Send Review
Thank You!
We'll use your feedback to improve our customer support
***CSS body{ background-color: #FEF9F2; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; overflow: hidden; position: relative; }
.container1{ width: 600px; height: 400px; box-shadow: 0 10px 20px rgba(0,0,0, 0.3); display: flex; flex-direction: column; align-items: center; text-align: center; padding: 10px 10px; background-color: #fdfdfc; position: absolute; opacity: 1; }
.container1 h1{ font-size: 22px; max-width: 400px; font-weight: 400; }
.container1 ul{ list-style-type: none; display: flex; align-items: center; justify-content: center; padding-top: 15px; }
.container1 li{ padding: 15px 12px; margin: 0 5px; cursor: pointer;
width: 150px; height: 150px;
}
.container1 li img{ width:60px; height: 60px; margin-top: 10px; }
.container1 li p{ margin-top: 15px; color:#899 }
.container1 li:hover{ box-shadow: 0px 2px 5px rgba(20, 20, 20, 0.2); }
.container1 li.active{ box-shadow: 0px 2px 5px rgba(20, 20, 20, 0.2); }
button{ margin: 40px 0; padding: 15px 10px; width: 220px; border-radius: 7px; border: none; background-color:#f3ba10 ; color: #fdfdfc; font-size: 24px; cursor: pointer; outline: none; }
button:active{ transform: scale(0.98); }
.container2{ width: 600px; height: 300px; box-shadow: 0 10px 20px rgba(0,0,0, 0.3); display: flex; flex-direction: column; align-items: center; text-align: center; padding: 10px 10px; background-color: #fdfdfc; z-index: -1;
}
.container2 i{ color: red; font-size: 29px; margin-top: 20px; }
.container2 h3,p{ margin-top: 20px; } .container2 p{ max-width: 400px; font-size: 18px; }
****jS let lis=document.querySelectorAll(‘li’); let btn = document.getElementById(‘btn’);
const container1 = document.querySelector(‘.container1’) const container2 = document.querySelector(‘.container2’); const container2h3= document.querySelector(‘.container2 h3’);
lis.forEach(li => { li.addEventListener(‘click’, (e)=>{ removeChangeLi(); li.classList.add(‘active’) }) });
function removeChangeLi(){ lis.forEach(li=>{ li.classList.remove(‘active’); }) }
btn.addEventListener(‘click’, (e)=>{show()})
function show(){ if(lis[0].classList.contains(‘active’)){ container1.remove(); container2h3.innerText=’Feedback:Unhappy’; } else if(lis[1].classList.contains(‘active’)){ container1.remove(); container2h3.innerText=’Feedback:Neutrual’; } else{ container1.remove(); container2h3.innerText=’Feedback:Satisfied’; } }
1 2 3 4 5 6 7 8 9 10 其他浏览器内与该功能类似的伪类 - ::-moz-range-thumb //火狐 - ::-ms-thumb //IE ### custom Range Slider 演示参考链接:https://50projects50days.com/projects/custom-range-slider/
HTML ***
Custom Range Slider
50
****************CSS ************* body{ display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; overflow: hidden; background-image: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
}
h2 { position: absolute; top: 10px; }
.range-container { position: relative; }
input[type=’range’] { width: 300px; margin: 18px 0; -webkit-appearance: none; }
input[type=’range’]:focus { outline: none; }
input[type=’range’] + label { background-color: #fff; position: absolute; top: -25px; left: 110px; width: 80px; padding: 5px 0; text-align: center; border-radius: 4px; box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); }
input[type=’range’]::-webkit-slider-runnable-track { background: purple; border-radius: 4px; width: 100%; height: 10px; cursor: pointer; }
input[type=’range’]::-webkit-slider-thumb { -webkit-appearance: none; height: 24px; width: 24px; background: #fff; border-radius: 50%; border: 1px solid purple; margin-top: -7px; cursor: pointer; }
*JS const range = document.getElementById(‘range’)
range.addEventListener(‘input’, (e) => { const value = +e.target.value const label = e.target.nextElementSibling
const range_width = getComputedStyle(e.target).getPropertyValue('width')
const label_width = getComputedStyle(label).getPropertyValue('width');
//去掉’px‘这个单位 const num_width = +range_width.substring(0, range_width.length - 2) const num_label_width = +label_width.substring(0, label_width.length - 2)
const max = +e.target.max
const min = +e.target.min
const left = value * (num_width / max) - num_label_width / 2 + scale(value, min, max, 10, -10)
// const left = 300/110*value-40+(y2-y1)/(x2-x1)*3;
label.style.left = `${left}px`
label.innerHTML = value
1 2 3 4 5 ### quiz App 演示参考地址:https://50projects50days.com/projects/quiz-app/
**************HTML************
*************CSS*********** body{ background-color: #EAEEF4; display: flex; align-items: center; justify-content: center; height: 100vh; overflow: hidden; margin: 0; }
.quiz-container{ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); background-color: #fff; margin: 10px 0; padding: 25px 40px; width: 700px; border-radius: 8px;
}
.header-container{
} h2{ line-height: 45px; text-align: center; font-size: 34px;
}
.header-container ul{ list-style-type: none;
} .header-container ul li{ font-size: 25px; margin: 40px; }
.header-container ul li input{ transform: scale(1.3); color: #8E44AD
}
.header-container ul li label{ cursor: pointer; padding-left: 10px; }
button{ width:100%; background-color: #8E44AD; padding: 12px 12px; border: none; color: white; font-size: 20px; cursor: pointer; outline: none; margin-bottom: 10px; }
button:focus { outline: none; background-color: #5e3370; } button:hover { background-color: #732d91; }
.reload-button{ margin: 30px 0; }
**************JS********************* const quizData=[ { question: “Which language runs in a web browser?”, a: “Java”, b: “C”, c: “Python”, d: “JavaScript”, correct: “d”, },
{
question: "What does CSS stand for?",
a: "Central Style Sheets",
b: "Cascading Style Sheets",
c: "Cascading Simple Sheets",
d: "Cars SUVs Sailboats",
correct: "b",
},
{
question: "What does HTML stand for?",
a: "Hypertext Markup Language",
b: "Hypertext Markdown Language",
c: "Hyperloop Machine Language",
d: "Helicopters Terminals Motorboats Lamborginis",
correct: "a",
},
{
question: "What year was JavaScript launched?",
a: "1996",
b: "1995",
c: "1994",
d: "none of the above",
correct: "b",
},
]
const quiz = document.getElementById(‘quiz’); const questionEl= document.getElementById(‘question’); const answerEls = document.querySelectorAll(‘.answer’); const a_text = document.getElementById(‘a_text’);
const b_text = document.getElementById(‘b_text’); const c_text = document.getElementById(‘c_text’); const d_text = document.getElementById(‘d_text’); const submitBtn = document.getElementById(‘submit’);
let chengji = 0; let currentQuizIndex = 0;
loadQuiz();
function loadQuiz(){ clearAnswerData(); questionEl.innerText = quizData[currentQuizIndex].question; a_text.innerText = quizData[currentQuizIndex].a; b_text.innerText = quizData[currentQuizIndex].b; c_text.innerText = quizData[currentQuizIndex].c; d_text.innerText = quizData[currentQuizIndex].d; }
function clearAnswerData(){ answerEls.forEach(answerEl=>{ answerEl.checked = false; }) }
function getAnswer(){ let answer; answerEls.forEach(answerEl=>{ if(answerEl.checked===true){ answer = answerEl.id; } }) return answer; }
submitBtn.addEventListener(‘click’ ,()=>{ let answer = getAnswer(); if(answer){ if(answer===quizData[currentQuizIndex].correct){ chengji++; } if(currentQuizIndex<quizData.length-1){ currentQuizIndex++; loadQuiz(); }else{ quiz.innerHTML = <h2>You answered ${chengji}/${quizData.length} questions correctly</h2> <button onclick="location.reload()" class="reload-button">Reload</button>
} }else{ alert(‘未选择答案’) } })
1 2 3 4 5 ### Testimonial Box Switch 演示参考地址: https://50projects50days.com/projects/testimonial-box-switcher/
HTML *******
CSS body{ display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; margin:20px auto; }
.container{ background-color: #29788b; border-radius: 9px; padding: 40px; display: flex; justify-content: center; align-items: center; text-anchor: center; flex-direction: column; color:aliceblue; position: relative; }
.progress{ width:100%; height: 7px; background-color: rgb(91, 215, 236); animation: grow 20s linear infinite; transform-origin: left; }
span{ position: absolute; top: 20px; right: 20px }
@keyframes grow{ 0%{ transform: scaleX(0); } } p{ margin: 20px 0; max-width: 700px; line-height: 35px; font-size: 20px; } p::before{
}
p::after{
}
.info{ display: flex; justify-content: center; align-items: center; }
img{ width: 80px; height: 80px; object-fit: cover; border-radius: 50%; border: none; } .user-info{ margin-left: 15px; text-align: center; margin-top: 20px;
}
.user-info h3{ margin-bottom: -20px; }
JS ****** const pEl = document.querySelector(‘p’); const imgEl = document.querySelector(‘img’); const h3El = document.querySelector(‘h3’); const pinfoEl = document.querySelector(‘.pinfo’); const span = document.querySelector(‘span’)
const datas=[ { name: ‘Miyah Myles’, position: ‘Marketing’, photo: ‘https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&s=707b9c33066bf8808c934c8ab394dff6' , text: “I’ve worked with literally hundreds of HTML/CSS developers and I have to say the top spot goes to this guy. This guy is an amazing developer. He stresses on good, clean code and pays heed to the details. I love developers who respect each and every aspect of a throughly thought out design and do their best to put it in code. He goes over and beyond and transforms ART into PIXELS - without a glitch, every time.”, }, { name: ‘June Cha’, position: ‘Software Engineer’, photo: ‘https://randomuser.me/api/portraits/women/44.jpg' , text: ‘This guy is an amazing frontend developer that delivered the task exactly how we need it, do your self a favor and hire him, you will not be disappointed by the work delivered. He will go the extra mile to make sure that you are happy with your project. I will surely work again with him!’, }, { name: ‘Iida Niskanen’, position: ‘Data Entry’, photo: ‘https://randomuser.me/api/portraits/women/68.jpg' , text: “This guy is a hard worker. Communication was also very good with him and he was very responsive all the time, something not easy to find in many freelancers. We’ll definitely repeat with him.”, }, { name: ‘Renee Sims’, position: ‘Receptionist’, photo: ‘https://randomuser.me/api/portraits/women/65.jpg' , text: “This guy does everything he can to get the job done and done right. This is the second time I’ve hired him, and I’ll hire him again in the future.”, }, { name: ‘Jonathan Nunfiez’, position: ‘Graphic Designer’, photo: ‘https://randomuser.me/api/portraits/men/43.jpg' , text: “I had my concerns that due to a tight deadline this project can’t be done. But this guy proved me wrong not only he delivered an outstanding work but he managed to deliver 1 day prior to the deadline. And when I asked for some revisions he made them in MINUTES. I’m looking forward to work with him again and I totally recommend him. Thanks again!”, }, { name: ‘Sasha Ho’, position: ‘Accountant’, photo: ‘https://images.pexels.com/photos/415829/pexels-photo-415829.jpeg?h=350&auto=compress&cs=tinysrgb' , text: ‘This guy is a top notch designer and front end developer. He communicates well, works fast and produces quality work. We have been lucky to work with him!’, }, { name: ‘Veeti Seppanen’, position: ‘Director’, photo: ‘https://randomuser.me/api/portraits/men/97.jpg' , text: ‘This guy is a young and talented IT professional, proactive and responsible, with a strong work ethic. He is very strong in PSD2HTML conversions and HTML/CSS technology. He is a quick learner, eager to learn new technologies. He is focused and has the good dynamics to achieve due dates and outstanding results.’, }, ] let index= 0; let munMax=100;
getData(); function getData(){ let {name, position, photo, text} =datas[index];
imgEl.src=photo; h3El.innerText = name; pEl.innerText =text; pinfoEl.innerText = position;
index++; if (index > datas.length - 1) { index= 0; } } ///////////在中间加这段代码是为了在显示第一个人的信息的时候百分比能显示出来//////////////// let i=0; let id=setInterval(() => { if(i<=100){ span.innerText=i+’%’; i++; } },110) // ///////////////////////// setInterval(() => { getData();
let i=1; let id=setInterval(() => { span.innerText=i+’%’; i++; if(i>100){ clearInterval(id); i=0; } }, 200);
}, 20000);
1 2 3 4 5 ### Random Image Feed 演示参考地址: https://50projects50days.com/projects/random-image-feed/
****HTML
Random Image Feed
CSS ********* body { font-family: ‘Roboto’, sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; margin: 0; }
.title{ margin-top: 10; text-align: center; }
.container{ display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
}
.container img{ object-fit: cover; margin: 10px; height: 300px; width: 300px; max-width: 100%;
}
JS * const container = document.querySelector(‘.container’) const unsplashURL = ‘https://source.unsplash.com/random/' const count=15;
for(let i=0; i<15; i++){ let img=document.createElement(‘img’); img.src=${unsplashURL}${getRandomSize()}
; container.appendChild(img) }
function getRandomSize(){ return ${getRandomNum()}x${getRandomNum()}
} function getRandomNum(){ return Math.floor(Math.random()*10+ 300);
}
1 2 3 4 5 6 7 ### Todo List 演示参考地址:https://50projects50days.com/projects/todo-list/ 涉及到locaolstorage方面的内容
*HTML
todos
Left click to toggle completed.
Right click to delete todo
*****CSS 8 body{ display: flex;
justify-content: center; text-align: center; height: 100vh;
margin: 0; }
h1{ margin-top: 15px; color:#DBC7ED; font-size: 130px; letter-spacing: 3px; }
.inputcontainer{ box-shadow: 2px 3px 12px rgba(0,0,0, 0.2); width:500px; max-width: 100%; margin-bottom: 30px; }
input { border: none; color: #444; font-size: 2rem; padding: 0.5rem 2rem; display: block; width: 100%; outline: none; }
input::placeholder { color: #d5d5d5; } input:focus{ border: solid 2px #DBC7ED; }
ul{ background-color: #fff; padding: 0; margin: 0; list-style-type: none; }
li{ font-size: 35px; border-bottom: 1px solid rgba(88, 86, 86, 0.133); padding: 12px; }
li.completed{ color:rgb(248, 66, 10); text-decoration: line-through;
}
li:first-of-type{ border-top: 1px solid rgba(88, 86, 86, 0.133); } small{ font-size: 18px; max-width: 350px; color:rgb(121, 118, 118); }
small.last{ margin-top: 900px; }
**jS const input = document.getElementById(‘input’); const ul = document.querySelector(‘ul’); const lis = document.querySelectorAll(‘li’);
let notes = JSON.parse(localStorage.getItem(‘notes’)); notes.forEach(note=>{ addNote(note); })
input.addEventListener(‘keyup’ ,(e)=>{ if(e.keyCode==13){ addNote(); } })
function addNote(note){ let notetext = input.value; //这个判断可将以前保存在localstarage里面的数据显示出来。 if(note){ notetext = note.text; }
if(notetext){ let li =document.createElement(‘li’); li.innerHTML = notetext;
li.addEventListener('click', ()=>{
li.classList.toggle('completed');
upLS();
})
li.addEventListener('contextmenu' ,(e)=>{
e.preventDefault();
li.remove();
upLS();
})
ul.appendChild(li);
input.value='';
upLS();
} }
////更新Locastorage数据库 function upLS(){ let notes = []; let lis = document.querySelectorAll(‘li’) lis.forEach(li=>{ notes.push({ text: li.innerText, completed: li.classList.contains(‘completed’) }) })
localStorage.setItem(‘notes’, JSON.stringify(notes)) }