0%

网页元素制作

expanding Cards

演示地址:https://50projects50days.com/projects/expanding-cards/

Progress Steps

演示效果链接:https://50projects50days.com/projects/progress-steps/

思路:

1626277741081

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
}
}

Hidden Search Widget

演示链接: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* CSS**
    *{
    box-sizing: border-box;
    }
    body {
    background-color:#678;
    font-family: ‘Roboto’, sans-serif;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    overflow: hidden;
    margin: 0;
    }.search {
    position: relative;
    height: 50px;
    background-color: rgb(194, 152, 97);
    }.search .input {
    background-color: #fff;
    border: 0;
    font-size: 18px;
    padding: 15px;
    height: 50px;
    width: 50px;
    transition: width 0.3s ease-in;
    }
    .btn{
    background-color: #fff;
    border:0;
    cursor: pointer;
    font-size: 24px;
    position: absolute;
    top:0;
    left: 0;
    height: 50px;
    width:50px;
    transition: transform 0.3s ease-in;
    
    } .btn:focus,
    .input:focus{
    outline: none;
    
    } .fa-search:before {
    content: "\f002";
    
    }.search.active .input{
    width: 200px
    }.search.active .btn{
    transform: translateX(200px);
    }JS*****
    const search= document.querySelector(“.search”);
    const btn = document.querySelector(‘.btn’);
    const input= document.querySelector(‘.input’);
    btn.addEventListener(‘click’, ()=>{
    search.classList.toggle(‘active’);
    input.focus();
    })
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11



    ## scroll Animation

    演示参考地址:https://50projects50days.com/projects/scroll-animation/

    设计思路:将未显示的盒子先向沿着X轴的两个方向隐藏起来,设置overflow-x: hidden; 奇数和偶数的box方向错开,添加scroll事件,按JS设置的条件显示box;

    JS:主要用到window.innerHeight/5*4, 即页面可视高度的80%,可以用getBoundingClientRect().top取到每一个Box距离页面顶端的高度,然后比较两者的值,当box的top值<页面高度的80%时,box应该要显示出来。

*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

Playstation 5

Buy Now

XBox Seriese

Buy Now

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*****

Twitter Followers
Twitter Fllowers
FaceBook Fans

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

<small>Remained</small>

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**

***************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****

*****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

**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>
    <button class="up-button">
      <i class=" iconfont icon-xiajiantou"></i>
    </button>
</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**

****CSS8
*{
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)]
}

1
2
3

### GitHub Profile

**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=””;
}

})

1
2
3

### double Click

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

***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)]
}

1
2
3

### Good Cheap Fast

HTML**

How do you want your project to be?

Good
Cheap
Fast

*****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

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**

3 2 1 0

GET READY

GO

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

home work blog about

*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 *********

Image Password Strength

Change the password to see the effect

<button class="bg-black text-white py-2 mt-4 inlne-block w-full  rounded" type="submit">Submit</button>

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

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*

Verify Your Account

We emailed you the six digit code to cool_guy@email.com Enter the code below to confirm your email address.

This is design only. We didn't actually send you an email as we don't have your email, right?

******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 ***********

Live User Filter

Search by name and/or location
  • Loading....

***********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>
    

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

****************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************

Question text

  •   <li>
        <input type="radio" name="answer" id="b" class="answer">
        <label for="b" id="b_text">Question</label>
      </li>
    
      <li>
        <input type="radio" name="answer" id="c" class="answer">
        <label for="c" id="c_text">Question</label>
      </li>
    
      <li>
        <input type="radio" name="answer" id="d" class="answer">
        <label for="d" id="d_text">Question</label>
      </li>
    </ul>
    <button id=submit>Submit</button>
    

*************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*******

0%

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

*****CSS8
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))
}