├── .gitignore ├── .vscode └── settings.json ├── 01-social-icon-hover-glow-effect ├── bilibili.svg ├── index.html └── style.css ├── 02-login-form-glass-effect ├── background.jpeg ├── index.html ├── package.json └── style.css ├── 03-chatting-ui ├── index.html ├── package.json └── style.css ├── 04-svg-text-drawing-effect ├── index.html ├── package.json └── style.css ├── 05-button-hover-border-drawing-effect ├── index.html ├── package.json └── style.css ├── 06-libra-ui-concept ├── README.md ├── img │ ├── btc.svg │ ├── lib-black.svg │ ├── lib-blue.svg │ ├── lib.svg │ ├── ltc.svg │ ├── menu.svg │ ├── plus.svg │ ├── readmore.svg │ ├── xpm.svg │ └── xrp.svg ├── index.html ├── package.json └── style.css ├── 07-3d-cubic-images ├── index.html └── style.css ├── 08-parallax-scrolling ├── index.html └── style.css ├── 09-japanese-pronunciation ├── index.html └── style.css ├── 10-navigation-bar ├── index.html └── style.css ├── 11-canvas-bar-chart └── index.html ├── 12-skill-progress-bar ├── index.html └── style.css ├── 13-css-3d-tutorial ├── index.html └── style.css ├── 14-image-slider ├── index.html ├── index.js └── style.css ├── 15-responsive-navbar ├── background.jpg ├── index.html ├── index.js └── style.css ├── 16-svg-animation-truck ├── index.html ├── style.css └── undraw_factory_dy0a.svg ├── 17-upload-button ├── index.html ├── index.js └── style.css ├── 18-elsa-magic-effect ├── index.html ├── index.js └── proton.min.js ├── 19-profile-card ├── index.html ├── index.js ├── me.jpeg └── style.css ├── 20-typewritter-effect ├── index.html ├── index.js └── style.css ├── 21-range-slider ├── index.html ├── index.js └── style.css ├── 22-face-reco-mask ├── face-api.min.js ├── index.html ├── index.js ├── mask.svg ├── models │ ├── face_landmark_68_model-shard1 │ ├── face_landmark_68_model-weights_manifest.json │ ├── face_recognition_model-shard1 │ ├── face_recognition_model-shard2 │ ├── face_recognition_model-weights_manifest.json │ ├── ssd_mobilenetv1_model-shard1 │ ├── ssd_mobilenetv1_model-shard2 │ └── ssd_mobilenetv1_model-weights_manifest.json ├── style.css └── woman.jpg ├── 23-fullwebsite-design-agency ├── images │ ├── activity01-image.jpg │ ├── adult-business-computer-contemporary-380769.jpg │ ├── apple-apple-device-design-desk-285814.jpg │ ├── apple-laptop-notebook-office-39284.jpg │ ├── blur-close-up-code-computer-546819.jpg │ ├── bokeh-photography-of-person-holding-turned-on-iphone-1440727.jpg │ ├── business-woman-2697954_1920.jpg │ ├── gray-laptop-computer-showing-html-codes-in-shallow-focus-160107.jpg │ ├── man-wearing-black-suit-2955376.jpg │ ├── people-in-couch-1024248.jpg │ ├── person-holding-a-smartphone-892757.jpg │ ├── person-using-black-and-white-smartphone-and-holding-blue-230544.jpg │ ├── photo-of-imac-near-macbook-1029757.jpg │ ├── red-suspension-bridge-3493772.jpg │ ├── selective-focus-photograph-of-man-wearing-gray-suit-jacket-1138903.jpg │ ├── smiling-woman-wearing-black-sweater-1587009.jpg │ └── watercrafts-on-river-3464632.jpg ├── index.html ├── index.js ├── libs │ ├── anime │ │ └── anime.min.js │ ├── glide │ │ ├── glide.core.min.css │ │ ├── glide.min.js │ │ └── glide.theme.min.css │ ├── isotope │ │ └── isotope.pkgd.min.js │ ├── scrollReveal │ │ └── scrollreveal.min.js │ └── smooth-scroll │ │ └── smooth-scroll.polyfills.min.js ├── style.css └── videos │ └── working-man.mp4 ├── 24-fetch-get-data ├── index.html ├── index.js └── style.css ├── 25-neumorphism-tabs ├── icons │ ├── icon1.svg │ ├── icon2.svg │ └── icon3.svg ├── index.html ├── index.js └── style.css ├── 26-glassmorphism ├── background.jpg └── index.html ├── 27-glitch-effect └── index.html ├── 28-css-colors └── index.html ├── 29-resizable-element └── index.html ├── 30-gradient-background-animation └── index.html ├── 31-05-wechat-emoji-effect ├── 3145-bomb.json ├── 43215-pumpkins-sticker-4.json ├── 9990-explosion.json ├── emoji.svg ├── index.html ├── index.js ├── lottie.min.js ├── me.png ├── style.css └── you.png ├── 31-webcomponent-get-started ├── BlogPost.js ├── PostList.js └── index.html ├── 32-place-item-center └── index.html ├── 33-text-image-layout ├── index.html └── undraw_static_assets_rpm6.svg ├── 34-drag-drop-api └── index.html ├── 35-collision-physics ├── index.html ├── index.js └── style.css ├── 36-tech-website ├── assets │ └── images │ │ ├── bilibili.svg │ │ ├── email.svg │ │ ├── github.svg │ │ ├── logo.svg │ │ ├── main.svg │ │ └── wechat.svg ├── index.html └── style.css ├── 37-container-queries └── index.html ├── 38-horizontal-scrolling └── index.html ├── 39-web-animations └── index.html ├── 40-multi-column-layout └── index.html ├── 41-css-scroll-snap ├── base.css ├── fullscreen-snap-proximity.html ├── fullscreen-snap-x.html ├── fullscreen-snap-y-padding.html ├── fullscreen-snap-y.html ├── index.html └── list-scroll-y.html ├── 42-clipboard-api ├── base.css └── index.html ├── 43-css-gradient-shadow └── index.html ├── 44-css-pointer-events ├── 2021-12-20-19-52-11.png └── index.html ├── 45-URLSearchParams └── index.html ├── 46-css-aspect-ratio ├── 2021-12-20-20-29-28.png └── index.html ├── 47-css-custom-scrollbar └── index.html ├── 48-css-clay-morphism ├── index.html └── style.css ├── 49-html-buit-in-dialog ├── index.html ├── index.js └── style.css ├── 50-css-grid-irregular-layout ├── images │ ├── travel1.png │ ├── travel2.png │ └── travel3.png ├── index.html └── style.css ├── 51-css-scroll-based-animation ├── .vscode │ └── settings.json ├── images │ ├── image1.jpg │ └── image2.jpg ├── index.html ├── scroll.html └── view.html ├── 52-day-night-toggle-button ├── index.html ├── script.js └── style.css ├── 53-screenshot-html2-canvas ├── cafe.jpg ├── html2canvas.min.js └── index.html ├── 54-navbar-dark-bouncing └── index.html ├── 55-beautiful-table └── index.html ├── 56-animation-button └── index.html ├── 57-login-form-glass-2 ├── bg.jpg └── index.html ├── LICENSE ├── README-zh_CN.md ├── README.md ├── babel.config.json ├── bilibili.jpg ├── index.html ├── index.js ├── package.json ├── react-dom.js ├── react.js ├── src └── index.js ├── style.css ├── yarn-error.log └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.port": 5501 3 | } -------------------------------------------------------------------------------- /01-social-icon-hover-glow-effect/bilibili.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /01-social-icon-hover-glow-effect/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 社交按钮分享hover发光特效 13 | 14 | 15 |
16 | 33 |
34 | 35 | 36 | -------------------------------------------------------------------------------- /01-social-icon-hover-glow-effect/style.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | margin: 0; 4 | } 5 | 6 | * { 7 | box-sizing: border-box; 8 | } 9 | 10 | ul, 11 | li { 12 | margin: 0; 13 | padding: 0; 14 | } 15 | 16 | li { 17 | list-style: none; 18 | } 19 | 20 | main { 21 | display: flex; 22 | align-items: center; 23 | justify-content: center; 24 | width: 100vw; 25 | height: 100vh; 26 | position: relative; 27 | background: #2c3a47; 28 | z-index: 25; 29 | } 30 | 31 | ul { 32 | display: flex; 33 | } 34 | 35 | ul li { 36 | margin: 0 18px; 37 | } 38 | 39 | li a { 40 | position: relative; 41 | display: block; 42 | color: white; 43 | width: 64px; 44 | height: 64px; 45 | font-size: 36px; 46 | text-align: center; 47 | line-height: 66px; 48 | border-radius: 50%; 49 | background: #2c3a47; 50 | transition: 0.6s; 51 | } 52 | 53 | li a:hover { 54 | text-shadow: 0 0 4px #25ccf7; 55 | } 56 | 57 | li a::before { 58 | content: ""; 59 | position: absolute; 60 | width: 100%; 61 | height: 100%; 62 | top: 0; 63 | left: 0; 64 | border-radius: 50%; 65 | background: #25ccf7; 66 | transition: 0.6s; 67 | transform: scale(0.8); 68 | z-index: -1; 69 | } 70 | 71 | li a:hover::before { 72 | box-shadow: 0 0 14px 2px #25ccf7; 73 | transform: scale(1.05); 74 | } 75 | 76 | /* bilibili */ 77 | .svg-icon { 78 | transition: 0.6s; 79 | filter: invert(1); 80 | } 81 | 82 | li a:hover .svg-icon { 83 | filter: invert(1) drop-shadow(0 0 2px rgb(37, 204, 247)); 84 | } 85 | 86 | @media screen and (max-width: 512px) { 87 | ul { 88 | flex-direction: column; 89 | } 90 | 91 | ul li { 92 | margin: 18px 0; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /02-login-form-glass-effect/background.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/02-login-form-glass-effect/background.jpeg -------------------------------------------------------------------------------- /02-login-form-glass-effect/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 13 | 14 | Static Template 15 | 16 | 17 |
18 |
19 |

登 录

20 | 25 | 30 | 31 |
32 |
33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /02-login-form-glass-effect/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "glass-login-form", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.html", 6 | "scripts": { 7 | "start": "serve" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/codesandbox-app/static-template.git" 12 | }, 13 | "keywords": [], 14 | "author": "Ives van Hoorne", 15 | "license": "MIT", 16 | "bugs": { 17 | "url": "https://github.com/codesandbox-app/static-template/issues" 18 | }, 19 | "homepage": "https://github.com/codesandbox-app/static-template#readme", 20 | "devDependencies": { 21 | "serve": "^11.2.0" 22 | } 23 | } -------------------------------------------------------------------------------- /02-login-form-glass-effect/style.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | margin: 0; 4 | font-family: "PingFang SC", "Microsoft Yahei", sans-serif; 5 | } 6 | 7 | .container { 8 | width: 100vw; 9 | height: 100vh; 10 | display: flex; 11 | align-items: center; 12 | justify-content: center; 13 | background: url("./background.jpeg") fixed no-repeat; 14 | background-size: cover; 15 | } 16 | 17 | .login-form { 18 | width: 240px; 19 | height: 220px; 20 | display: flex; 21 | flex-direction: column; 22 | padding: 40px; 23 | text-align: center; 24 | position: relative; 25 | z-index: 100; 26 | background: inherit; 27 | border-radius: 18px; 28 | overflow: hidden; /* 隐藏多余的模糊效果 */ 29 | } 30 | 31 | .login-form::before { 32 | content: ""; 33 | width: calc(100% + 20px); 34 | height: calc(100% + 20px); 35 | position: absolute; 36 | top: -10px; 37 | left: -10px; 38 | overflow: hidden; 39 | background: inherit; 40 | box-shadow: inset 0 0 0 200px rgba(255, 255, 255, 0.25); 41 | filter: blur(6px); 42 | z-index: -1; 43 | } 44 | 45 | .login-form h2 { 46 | font-size: 18px; 47 | font-weight: 400; 48 | color: #3d5245; 49 | } 50 | 51 | .login-form input, 52 | .login-form button { 53 | margin: 6px 0; 54 | height: 36px; 55 | border: none; 56 | background-color: rgba(255, 255, 255, 0.3); 57 | border-radius: 4px; 58 | padding: 0 14px; 59 | color: #3d5245; 60 | } 61 | 62 | .login-form input::placeholder { 63 | color: #3d5245; 64 | } 65 | 66 | /* 补充,取消选中高亮蓝框 */ 67 | .login-form button:focus, 68 | .login-form input:focus { 69 | outline: 0; 70 | } 71 | 72 | .login-form button { 73 | margin-top: 24px; 74 | background-color: rgba(57, 88, 69, 0.4); 75 | color: white; 76 | position: relative; 77 | overflow: hidden; 78 | cursor: pointer; 79 | transition: 0.4s; 80 | } 81 | 82 | .login-form button:hover { 83 | background-color: rgba(12, 80, 38, 0.67); 84 | } 85 | 86 | .login-form button:focus { 87 | outline: 0; 88 | } 89 | 90 | .login-form button::before, 91 | .login-form button::after { 92 | content: ""; 93 | display: block; 94 | width: 80px; 95 | height: 100%; 96 | background: rgba(179, 255, 210, 0.5); 97 | opacity: 0.5; 98 | position: absolute; 99 | top: 0; 100 | left: 0; 101 | transform: skewX(-15deg); 102 | filter: blur(30px); 103 | overflow: hidden; 104 | transform: translateX(-100px); 105 | } 106 | 107 | .login-form button::after { 108 | width: 40px; 109 | background: rgba(179, 255, 210, 0.3); 110 | left: 60px; 111 | opacity: 0; 112 | filter: blur(5px); 113 | } 114 | 115 | .login-form button:hover::before { 116 | transition: 1s; 117 | transform: translateX(320px); 118 | opacity: 0.7; 119 | } 120 | 121 | .login-form button:hover::after { 122 | transition: 1s; 123 | transform: translateX(320px); 124 | opacity: 1; 125 | } 126 | -------------------------------------------------------------------------------- /03-chatting-ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chatting-ui", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.html", 6 | "scripts": { 7 | "start": "serve" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/codesandbox-app/static-template.git" 12 | }, 13 | "keywords": [], 14 | "author": "Ives van Hoorne", 15 | "license": "MIT", 16 | "bugs": { 17 | "url": "https://github.com/codesandbox-app/static-template/issues" 18 | }, 19 | "homepage": "https://github.com/codesandbox-app/static-template#readme", 20 | "devDependencies": { 21 | "serve": "^11.2.0" 22 | } 23 | } -------------------------------------------------------------------------------- /03-chatting-ui/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: "PingFang SC", sans-serif; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | ul, 10 | li { 11 | margin: 0; 12 | padding: 0; 13 | } 14 | 15 | .container { 16 | display: flex; 17 | align-items: center; 18 | justify-content: center; 19 | } 20 | 21 | .page { 22 | width: 375px; 23 | height: 812px; 24 | box-shadow: 0px 4px 16px 0px 25 | rgba(0, 0, 0, 0.1); 26 | margin: 48px 0; 27 | } 28 | 29 | /* 背景 */ 30 | .main-panel { 31 | background: #0061c4; 32 | max-height: 100%; 33 | display: flex; 34 | flex-direction: column; 35 | } 36 | 37 | /* 导航 */ 38 | nav { 39 | padding: 48px 24px 30px 24px; 40 | } 41 | 42 | .buttons { 43 | display: flex; 44 | justify-content: space-between; 45 | color: white; 46 | } 47 | 48 | .menu { 49 | display: flex; 50 | justify-content: space-between; 51 | } 52 | 53 | .menu li { 54 | list-style: none; 55 | color: rgba(255, 255, 255, 0.68); 56 | font-size: 18px; 57 | margin-top: 48px; 58 | } 59 | 60 | .menu .active { 61 | color: white; 62 | } 63 | 64 | /* 常用联系人 */ 65 | .middle-panel { 66 | background: #f2f8fc; 67 | border-radius: 34px; 68 | padding: 30px 24px 100px 24px; 69 | margin-bottom: -80px; 70 | } 71 | 72 | .favorite-menu { 73 | display: flex; 74 | justify-content: space-between; 75 | } 76 | 77 | .favorite-menu span { 78 | font-size: 16px; 79 | color: #6f6f6f; 80 | } 81 | 82 | .favorite-menu i.fas { 83 | color: #6f6f6f; 84 | } 85 | 86 | .people { 87 | display: flex; 88 | justify-content: space-between; 89 | overflow: auto; 90 | flex-shrink: 0; 91 | margin-right: -20px; 92 | } 93 | 94 | .profile { 95 | text-align: center; 96 | padding: 20px 10px 0 20px; 97 | } 98 | 99 | .profile:first-child { 100 | padding-left: 0; 101 | } 102 | .profile:last-child { 103 | padding-right: 0; 104 | } 105 | 106 | .profile img, 107 | .message img { 108 | width: 60px; 109 | height: 60px; 110 | border-radius: 50%; 111 | object-fit: cover; 112 | object-position: center; 113 | } 114 | 115 | .profile .profile-name { 116 | font-size: 14px; 117 | color: #a5a9ad; 118 | margin-top: 6px; 119 | } 120 | 121 | /* 聊天面板 */ 122 | .message-panel { 123 | background: white; 124 | position: relative; 125 | border-radius: 48px 48px 0 0; 126 | overflow: hidden; 127 | display: flex; 128 | } 129 | 130 | .mask { 131 | width: 100%; 132 | height: 64px; 133 | border-radius: 48px 48px 0 0; 134 | background-image: linear-gradient( 135 | 180deg, 136 | rgba(255, 255, 255, 1) 0%, 137 | rgba(255, 255, 255, 0.6) 60%, 138 | rgba(255, 255, 255, 0) 100% 139 | ); 140 | position: absolute; 141 | } 142 | 143 | .messages { 144 | overflow: auto; 145 | padding-right: 12px; 146 | padding-bottom: 24px; 147 | } 148 | 149 | .message { 150 | display: flex; 151 | align-items: center; 152 | padding: 10px 12px 10px 24px; 153 | } 154 | 155 | .message .info { 156 | flex: 4; 157 | padding-left: 20px; 158 | font-size: 14px; 159 | min-width: 0; 160 | } 161 | 162 | .message .info .name { 163 | color: #a5a9ad; 164 | padding-bottom: 8px; 165 | } 166 | 167 | .message .info .content { 168 | color: #657081; 169 | text-overflow: ellipsis; 170 | white-space: nowrap; 171 | overflow: hidden; 172 | } 173 | 174 | .message .time { 175 | flex: 1; 176 | font-size: 14px; 177 | color: #858a98; 178 | padding-top: 4px; 179 | align-self: flex-start; 180 | text-align: right; 181 | } 182 | 183 | .message.new { 184 | background: rgba(27, 131, 246, 0.05); 185 | border-radius: 0 24px 24px 0; 186 | } 187 | 188 | .message .new-message-icon { 189 | background: rgba(239, 102, 102, 1); 190 | border-radius: 7px; 191 | font-size: 12px; 192 | color: white; 193 | padding: 3px 6px; 194 | margin-top: 6px; 195 | } 196 | -------------------------------------------------------------------------------- /04-svg-text-drawing-effect/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Static Template 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 | 25 | 26 | 27 | 28 | 35 | 36 | 37 | 38 | 39 | 40 | 峰华前端 41 | 42 | 43 |
44 | 45 | 46 | -------------------------------------------------------------------------------- /04-svg-text-drawing-effect/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "animated-text", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.html", 6 | "scripts": { 7 | "start": "serve" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/codesandbox-app/static-template.git" 12 | }, 13 | "keywords": [], 14 | "author": "Ives van Hoorne", 15 | "license": "MIT", 16 | "bugs": { 17 | "url": "https://github.com/codesandbox-app/static-template/issues" 18 | }, 19 | "homepage": "https://github.com/codesandbox-app/static-template#readme", 20 | "devDependencies": { 21 | "serve": "^11.2.0" 22 | } 23 | } -------------------------------------------------------------------------------- /04-svg-text-drawing-effect/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #2f3542; 3 | } 4 | 5 | .container { 6 | display: flex; 7 | align-items: center; 8 | justify-content: center; 9 | height: 100vh; 10 | width: 100vw; 11 | } 12 | 13 | .logo_text { 14 | font-family: "PingFang SC"; 15 | font-size: 84px; 16 | fill: none; 17 | stroke: url("#geekColor"); 18 | stroke-width: 1; 19 | stroke-dasharray: 10 800; 20 | stroke-dashoffset: 10; 21 | 22 | animation: 3s linear 0s drawing forwards; 23 | } 24 | 25 | /* 绘画动画 */ 26 | @keyframes drawing { 27 | to { 28 | stroke-dasharray: 800; 29 | stroke-dashoffset: 0; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /05-button-hover-border-drawing-effect/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 13 | 17 | Static Template 18 | 19 | 20 |
21 |
22 | 23 | 28 | 29 |
30 | 按钮 31 |
32 |
33 |
34 | 35 | 36 | -------------------------------------------------------------------------------- /05-button-hover-border-drawing-effect/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "button-hover", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.html", 6 | "scripts": { 7 | "start": "serve" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/codesandbox-app/static-template.git" 12 | }, 13 | "keywords": [], 14 | "author": "Ives van Hoorne", 15 | "license": "MIT", 16 | "bugs": { 17 | "url": "https://github.com/codesandbox-app/static-template/issues" 18 | }, 19 | "homepage": "https://github.com/codesandbox-app/static-template#readme", 20 | "devDependencies": { 21 | "serve": "^11.2.0" 22 | } 23 | } -------------------------------------------------------------------------------- /05-button-hover-border-drawing-effect/style.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | padding: 0; 4 | margin: 0; 5 | font-family: "PingFang SC"; 6 | } 7 | 8 | .container { 9 | display: flex; 10 | align-items: center; 11 | justify-content: center; 12 | width: 100vw; 13 | height: 100vh; 14 | background: #2f3542; 15 | } 16 | 17 | .button-wrapper { 18 | position: relative; 19 | width: 240px; 20 | height: 60px; 21 | text-align: center; 22 | } 23 | 24 | .rectangle { 25 | stroke-width: 8px; 26 | stroke: #ff6348; 27 | fill: transparent; 28 | /* Core part of the animation */ 29 | stroke-dasharray: 100 500; 30 | stroke-dashoffset: -372; 31 | } 32 | 33 | .btn { 34 | color: white; 35 | font-size: 18px; 36 | letter-spacing: 6px; 37 | position: relative; 38 | top: -48px; 39 | } 40 | 41 | @keyframes extend { 42 | to { 43 | stroke-dasharray: 600; 44 | stroke-dashoffset: 0; 45 | stroke-width: 2; 46 | } 47 | } 48 | 49 | .button-wrapper:hover .rectangle { 50 | animation: 0.5s extend linear forwards; 51 | } 52 | 53 | /* if reverse animation is needed, use transition instead of keyframes */ 54 | 55 | /* .rectangle { 56 | stroke-width: 8px; 57 | stroke: #ff6348; 58 | fill: transparent; 59 | stroke-dasharray: 100 500; 60 | stroke-dashoffset: -372; 61 | transition-property: all; 62 | transition-duration: 0.5s; 63 | } */ 64 | /* 65 | .button-wrapper:hover .rectangle { 66 | 67 | stroke-dasharray: 600; 68 | stroke-dashoffset: 0; 69 | stroke-width: 2; 70 | } */ 71 | -------------------------------------------------------------------------------- /06-libra-ui-concept/README.md: -------------------------------------------------------------------------------- 1 | 设计图出自(Thanks for the sketch design):[Prateek Saini](http://www.dribbble.com/prateeksaini2802) 2 | 3 | 代码原创且开源,欢迎取用。 4 | 5 | 图片: [pexels](https://www.pexels.com/) 6 | 7 | Music: [bensound](https://www.bensound.com) 8 | 9 | 作者微信: zxuqian 10 | 11 | QQ 群:644722908 12 | -------------------------------------------------------------------------------- /06-libra-ui-concept/img/btc.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /06-libra-ui-concept/img/lib-black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Shape 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /06-libra-ui-concept/img/lib-blue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Shape 5 | Created with Sketch. 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 | -------------------------------------------------------------------------------- /06-libra-ui-concept/img/lib.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Shape 5 | Created with Sketch. 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 | -------------------------------------------------------------------------------- /06-libra-ui-concept/img/ltc.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /06-libra-ui-concept/img/menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | menu 5 | Created with Sketch. 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 | -------------------------------------------------------------------------------- /06-libra-ui-concept/img/plus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Combined Shape 5 | Created with Sketch. 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 | -------------------------------------------------------------------------------- /06-libra-ui-concept/img/readmore.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | arrow 5 | Created with Sketch. 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 | -------------------------------------------------------------------------------- /06-libra-ui-concept/img/xpm.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /06-libra-ui-concept/img/xrp.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /06-libra-ui-concept/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "libra-concept-ui", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.html", 6 | "scripts": { 7 | "start": "serve" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/codesandbox-app/static-template.git" 12 | }, 13 | "keywords": [], 14 | "author": "Ives van Hoorne", 15 | "license": "MIT", 16 | "bugs": { 17 | "url": "https://github.com/codesandbox-app/static-template/issues" 18 | }, 19 | "homepage": "https://github.com/codesandbox-app/static-template#readme", 20 | "devDependencies": { 21 | "serve": "^11.2.0" 22 | } 23 | } -------------------------------------------------------------------------------- /07-3d-cubic-images/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /07-3d-cubic-images/style.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | margin: 0; 4 | } 5 | 6 | * { 7 | box-sizing: border-box; 8 | } 9 | 10 | body { 11 | background-color: #2f3542; 12 | } 13 | 14 | main { 15 | display: flex; 16 | align-items: center; 17 | justify-content: center; 18 | height: 100vh; 19 | } 20 | 21 | .cube { 22 | width: 250px; 23 | height: 250px; 24 | transform-style: preserve-3d; 25 | transform-origin: 125px 125px 0; 26 | animation: rotate-cube 10s ease-in-out infinite; 27 | } 28 | 29 | .cube > div { 30 | width: 250px; 31 | height: 250px; 32 | background-size: cover; 33 | background-position: center center; 34 | opacity: 0.8; 35 | position: absolute; 36 | box-shadow: inset 0 0 4px 2px rgba(106, 106, 106, 0.4); 37 | } 38 | 39 | /* 前 */ 40 | .cube .img1 { 41 | background-image: url("https://images.pexels.com/photos/274131/pexels-photo-274131.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940"); 42 | transform: rotateY(0deg) translateZ(125px); 43 | } 44 | 45 | /* 右 */ 46 | .cube .img2 { 47 | background-image: url("https://images.pexels.com/photos/1480690/pexels-photo-1480690.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940"); 48 | transform: rotateY(90deg) translateZ(125px); 49 | } 50 | 51 | /* 左 */ 52 | .cube .img3 { 53 | background-image: url("https://images.pexels.com/photos/36487/above-adventure-aerial-air.jpg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940"); 54 | transform: rotateY(-90deg) translateZ(125px); 55 | } 56 | 57 | /* 下 */ 58 | .cube .img4 { 59 | background-image: url("https://images.pexels.com/photos/338713/pexels-photo-338713.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940"); 60 | transform: rotateX(90deg) translateZ(125px); 61 | } 62 | 63 | /* 上 */ 64 | .cube .img5 { 65 | background-image: url("https://images.pexels.com/photos/325044/pexels-photo-325044.jpeg?cs=srgb&dl=close-up-of-fish-over-black-background-325044.jpg&fm=jpg"); 66 | transform: rotateX(-90deg) translateZ(125px); 67 | } 68 | 69 | /* 后 */ 70 | .cube .img6 { 71 | background-image: url("https://images.pexels.com/photos/404280/pexels-photo-404280.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940"); 72 | transform: rotateY(180deg) translateZ(125px); 73 | } 74 | 75 | @keyframes rotate-cube { 76 | 0% { 77 | transform: rotateX(0deg) rotateY(0deg); 78 | } 79 | 20% { 80 | /* 右边图片 */ 81 | transform: rotateY(-90deg); 82 | } 83 | 40% { 84 | /* 上 */ 85 | transform: rotateX(-90deg); 86 | } 87 | 60% { 88 | /* 左 */ 89 | transform: rotateY(90deg); 90 | } 91 | 80% { 92 | /* 下 */ 93 | transform: rotateX(90deg); 94 | } 95 | 100% { 96 | transform: rotateX(0deg) rotateY(0deg); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /08-parallax-scrolling/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 |
12 |

纯 CSS 实现视差滚动效果

13 |
14 |
15 |
16 |

17 | 《洛神赋》是中国三国时期曹魏文学家曹植创作的辞赋名篇。此赋虚构了作者自己与洛神的邂逅和彼此间的思慕爱恋,洛神形象美丽绝伦,人神之恋飘渺迷离,但由于人神道殊而不能结合,最后抒发了无限的悲伤怅惘之情。全篇大致可分为六段:第一段写作者从洛阳回封地时,在恍惚之际看到洛神伫立山崖;第二段写洛神容仪服饰之美;第三段写作者爱慕洛神既识礼仪又善言辞,虽相互赠答,但担心遇合受阻;第四段写洛神为“君王”之诚所感后将来而未至的情状和举动;第五段写洛神来临扈从之多,终以人神道殊,含恨离去;第六段写洛神去后作者对顾望思慕不忍离去的深情。全赋辞采华美,描写细腻,想象丰富,情思绻缱,若有寄托。 18 |

19 |

20 | 黄初三年,余朝京师,还济洛川。古人有言,斯水之神,名曰宓妃。感宋玉对楚王神女之事,遂作斯赋。其辞曰:余从京域,言归东藩。背伊阙,越轘辕,经通谷,陵景山。日既西倾,车殆马烦。尔乃税驾乎蘅皋,秣驷乎芝田,容与乎阳林,流眄乎洛川。于是精移神骇,忽焉思散。俯则末察,仰以殊观,睹一丽人,于岩之畔。乃援御者而告之曰:“尔有觌于彼者乎?彼何人斯?若此之艳也!”御者对曰:“臣闻河洛之神,名曰宓妃。然则君王所见,无乃日乎?其状若何?臣愿闻之。”余告之曰:“其形也,翩若惊鸿,婉若游龙。荣曜秋菊,华茂春松。仿佛兮若轻云之蔽月,飘摇兮若流风之回雪。远而望之,皎若太阳升朝霞;迫而察之,灼若芙蕖出渌波。秾纤得衷,修短合度。肩若削成,腰如约素。延颈秀项,皓质呈露。芳泽无加,铅华弗御。云髻峨峨,修眉联娟。丹唇外朗,皓齿内鲜,明眸善睐,靥辅承权。瑰姿艳逸,仪静体闲。柔情绰态,媚于语言。奇服旷世,骨像应图。披罗衣之璀粲兮,珥瑶碧之华琚。戴金翠之首饰,缀明珠以耀躯。践远游之文履,曳雾绡之轻裾。微幽兰之芳蔼兮,步踟蹰于山隅。于是忽焉纵体,以遨以嬉。左倚采旄,右荫桂旗。壤皓腕于神浒兮,采湍濑之玄芝。余情悦其淑美兮,心振荡而不怡。无良媒以接欢兮,托微波而通辞。愿诚素之先达兮,解玉佩以要之。嗟佳人之信修,羌习礼而明诗。抗琼[王弟]以和予兮,指潜渊而为期。执眷眷之款实兮,惧斯灵之我欺。感交甫之弃言兮,怅犹豫而狐疑。收和颜而静志兮,申礼防以自持。于是洛灵感焉,徙倚彷徨,神光离合,乍阴乍阳。竦轻躯以鹤立,若将飞而未翔。践椒涂之郁烈,步蘅薄而流芳。超长吟以永慕兮,声哀厉而弥长。尔乃众灵杂遢,命俦啸侣,或戏清流,或翔神渚,或采明珠,或拾翠羽。从南湘之二妃,携汉滨之游女。叹匏瓜之无匹兮,咏牵牛之独处。扬轻袿之猗靡兮,翳修袖以延伫。休迅飞凫,飘忽若神,陵波微步,罗袜生尘。动无常则,若危若安。进止难期,若往若还。转眄流精,光润玉颜。含辞未吐,气若幽兰。华容婀娜,令我忘餐。于是屏翳收风,川后静波。冯夷鸣鼓,女娲清歌。腾文鱼以警乘,鸣玉鸾以偕逝。六龙俨其齐首,载云车之容裔,鲸鲵踊而夹毂,水禽翔而为卫。于是越北沚。过南冈,纡素领,回清阳,动朱唇以徐言,陈交接之大纲。恨人神之道殊兮,怨盛年之莫当。抗罗袂以掩涕兮,泪流襟之浪浪。悼良会之永绝兮。哀一逝而异乡。无微情以效爱兮,献江南之明。虽潜处于太阳,长寄心于君王。忽不悟其所舍,怅神宵而蔽光。于是背下陵高,足往神留,遗情想像,顾望怀愁。冀灵体之复形,御轻舟而上溯。浮长川而忘返,思绵绵督。夜耿耿而不寐,沾繁霜而至曙。命仆夫而就驾,吾将归乎东路。揽騑辔以抗策,怅盘桓而不能去。 21 |

22 |
23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /08-parallax-scrolling/style.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | margin: 0; 4 | font-family: Helvetica, "PingFang SC", "Microsoft Yahei", sans-serif; 5 | } 6 | 7 | * { 8 | box-sizing: border-box; 9 | } 10 | 11 | html { 12 | /* 需隐藏最外层不可见区域以使视差生效 */ 13 | overflow: hidden; 14 | } 15 | 16 | body { 17 | /* 开启3d空间,数值越小3D效果越大 */ 18 | perspective: 1px; 19 | /* 在3D空间进行transform */ 20 | transform-style: preserve-3d; 21 | overflow-x: hidden; 22 | overflow-y: auto; 23 | /* 需要设置高度以使时差生效 */ 24 | height: 100vh; 25 | } 26 | 27 | header { 28 | display: flex; 29 | align-items: center; 30 | justify-content: center; 31 | position: relative; 32 | transform-style: inherit; 33 | /* 需要设置高度以使时差生效 */ 34 | height: 100vh; 35 | } 36 | 37 | header h1 { 38 | background-color: rgba(0, 0, 0, 0.7); 39 | color: white; 40 | padding: 1em 4em; 41 | font-size: 3em; 42 | } 43 | 44 | header::before { 45 | position: absolute; 46 | content: ""; 47 | display: block; 48 | top: 0; 49 | bottom: 0; 50 | left: 0; 51 | right: 0; 52 | background-image: url(https://images.pexels.com/photos/2310815/pexels-photo-2310815.jpeg?cs=srgb&dl=photo-of-opened-metal-windows-2310815.jpg&fm=jpg); 53 | background-size: cover; 54 | /* 核心,按z轴向远处移动1px,大小会缩小一倍,使用scale放大到原图大小 */ 55 | transform: translateZ(-1px) scale(2); 56 | z-index: -1; 57 | } 58 | 59 | main { 60 | display: flex; 61 | justify-content: center; 62 | position: relative; 63 | background-color: #222f3e; 64 | } 65 | 66 | article { 67 | width: 90vw; 68 | max-width: 960px; 69 | padding: 6em 0; 70 | color: white; 71 | font-size: 18px; 72 | text-align: justify; 73 | letter-spacing: 0.075em; 74 | text-indent: 2em; 75 | line-height: 1.8em; 76 | } 77 | 78 | /* 屏幕适配 */ 79 | 80 | @media screen and (max-width: 1024px) { 81 | header h1 { 82 | font-size: 2.5em; 83 | padding: 1em 1.5em; 84 | } 85 | } 86 | 87 | @media screen and (max-width: 600px) { 88 | header h1 { 89 | font-size: 1.5em; 90 | padding: 1em 1em; 91 | } 92 | 93 | article { 94 | font-size: 1em; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /10-navigation-bar/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CSS 导航条 9 | 10 | 11 |
12 | 22 |
23 | 24 | 25 | -------------------------------------------------------------------------------- /10-navigation-bar/style.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | margin: 0; 4 | font-family: "PingFang SC", "Microsoft Yahei", sans-serif; 5 | } 6 | 7 | * { 8 | box-sizing: border-box; 9 | } 10 | 11 | ul, 12 | li { 13 | margin: 0; 14 | padding: 0; 15 | } 16 | 17 | body { 18 | background-color: #1e272e; 19 | } 20 | 21 | nav { 22 | display: flex; 23 | justify-content: center; 24 | align-items: center; 25 | height: 100vh; 26 | } 27 | 28 | ul { 29 | position: relative; 30 | display: flex; 31 | } 32 | 33 | ul li { 34 | /* 如果设置为inline-block,会有空隙 */ 35 | /* https://stackoverflow.com/questions/19038799/why-is-there-an-unexplainable-gap-between-these-inline-block-div-elements */ 36 | list-style: none; 37 | width: 120px; 38 | line-height: 40px; 39 | text-align: center; 40 | } 41 | 42 | ul li a { 43 | color: white; 44 | text-decoration: none; 45 | } 46 | 47 | .slider { 48 | width: 100px; 49 | height: 40px; 50 | background-color: #5352ed; 51 | border-radius: 4px; 52 | position: absolute; 53 | left: 10px; 54 | bottom: 0; 55 | z-index: -1; 56 | transition: all ease 0.4s; 57 | animation: 2s ease-in-out waves infinite; 58 | } 59 | 60 | li:nth-child(1):hover ~ .slider { 61 | left: 10px; 62 | } 63 | 64 | li:nth-child(2):hover ~ .slider { 65 | left: 128px; 66 | } 67 | 68 | li:nth-child(3):hover ~ .slider { 69 | left: 248px; 70 | } 71 | 72 | li:nth-child(4):hover ~ .slider { 73 | left: 368px; 74 | } 75 | 76 | li:nth-child(5):hover ~ .slider { 77 | left: 488px; 78 | } 79 | 80 | @keyframes waves { 81 | from { 82 | clip-path: polygon( 83 | 0% 17%, 84 | 9% 10%, 85 | 18% 4%, 86 | 30% 0%, 87 | 43% 1%, 88 | 49% 4%, 89 | 57% 7%, 90 | 66% 10%, 91 | 78% 11%, 92 | 89% 11%, 93 | 96% 9%, 94 | 100% 7%, 95 | 100% 100%, 96 | 0% 100% 97 | ); 98 | } 99 | 50% { 100 | clip-path: polygon( 101 | 0% 4%, 102 | 6% 9%, 103 | 13% 13%, 104 | 23% 15%, 105 | 31% 16%, 106 | 42% 15%, 107 | 49% 13%, 108 | 61% 10%, 109 | 71% 5%, 110 | 81% 3%, 111 | 90% 2%, 112 | 100% 5%, 113 | 100% 100%, 114 | 0% 100% 115 | ); 116 | } 117 | to { 118 | clip-path: polygon( 119 | 0% 17%, 120 | 9% 10%, 121 | 18% 4%, 122 | 30% 0%, 123 | 43% 1%, 124 | 49% 4%, 125 | 57% 7%, 126 | 66% 10%, 127 | 78% 11%, 128 | 89% 11%, 129 | 96% 9%, 130 | 100% 7%, 131 | 100% 100%, 132 | 0% 100% 133 | ); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /11-canvas-bar-chart/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 25 | Canvs 实现柱状图 26 | 27 | 28 |
29 | 30 |
31 | 32 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /12-skill-progress-bar/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 技能条 9 | 10 | 11 |
12 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /12-skill-progress-bar/style.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | padding: 0; 4 | margin: 0; 5 | font-family: sans-serif; 6 | } 7 | 8 | * { 9 | box-sizing: border-box; 10 | } 11 | 12 | ul, 13 | li { 14 | margin: 0; 15 | padding: 0; 16 | } 17 | 18 | main { 19 | display: flex; 20 | align-items: center; 21 | justify-content: center; 22 | height: 100vh; 23 | background-color: #1e272e; 24 | } 25 | 26 | ul { 27 | width: 500px; 28 | } 29 | 30 | li { 31 | list-style: none; 32 | color: #d2dae2; 33 | font-size: 18px; 34 | margin: 48px 0; 35 | position: relative; 36 | } 37 | 38 | li::before, 39 | li::after { 40 | content: ""; 41 | display: block; 42 | height: 16px; 43 | width: 100%; 44 | background-color: #1f4a59; 45 | position: absolute; 46 | bottom: -28px; 47 | border-radius: 6px; 48 | } 49 | 50 | li::before { 51 | box-shadow: 0 0 6px rgba(75, 207, 250, 0.2); 52 | } 53 | 54 | li::after { 55 | background-image: linear-gradient(90deg, #0fbcf9, #34e7e4); 56 | } 57 | 58 | li::after { 59 | animation-duration: 1.2s; 60 | animation-fill-mode: forwards; 61 | animation-timing-function: ease-in-out; 62 | } 63 | 64 | .js::after { 65 | animation-name: js; 66 | } 67 | 68 | .react::after { 69 | animation-name: react; 70 | } 71 | 72 | .html5::after { 73 | animation-name: html5; 74 | } 75 | 76 | .css3::after { 77 | animation-name: css3; 78 | } 79 | 80 | .sketch::after { 81 | animation-name: sketch; 82 | } 83 | 84 | @keyframes js { 85 | from { 86 | width: 0; 87 | } 88 | to { 89 | width: 90%; 90 | } 91 | } 92 | 93 | @keyframes react { 94 | from { 95 | width: 0; 96 | } 97 | to { 98 | width: 80%; 99 | } 100 | } 101 | 102 | @keyframes html5 { 103 | from { 104 | width: 0; 105 | } 106 | to { 107 | width: 70%; 108 | } 109 | } 110 | 111 | @keyframes css3 { 112 | from { 113 | width: 0; 114 | } 115 | to { 116 | width: 60%; 117 | } 118 | } 119 | 120 | @keyframes sketch { 121 | from { 122 | width: 0; 123 | } 124 | to { 125 | width: 50%; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /13-css-3d-tutorial/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 |
12 |
13 |
14 |
15 |
16 |
17 |

18 | 《洛神赋》是中国三国时期曹魏文学家曹植创作的辞赋名篇。此赋虚构了作者自己与洛神的邂逅和彼此间的思慕爱恋,洛神形象美丽绝伦,人神之恋飘渺迷离,但由于人神道殊而不能结合,最后抒发了无限的悲伤怅惘之情。全篇大致可分为六段:第一段写作者从洛阳回封地时,在恍惚之际看到洛神伫立山崖;第二段写洛神容仪服饰之美;第三段写作者爱慕洛神既识礼仪又善言辞,虽相互赠答,但担心遇合受阻;第四段写洛神为“君王”之诚所感后将来而未至的情状和举动;第五段写洛神来临扈从之多,终以人神道殊,含恨离去;第六段写洛神去后作者对顾望思慕不忍离去的深情。全赋辞采华美,描写细腻,想象丰富,情思绻缱,若有寄托。 19 |

20 |

21 | 黄初三年,余朝京师,还济洛川。古人有言,斯水之神,名曰宓妃。感宋玉对楚王神女之事,遂作斯赋。其辞曰:余从京域,言归东藩。背伊阙,越轘辕,经通谷,陵景山。日既西倾,车殆马烦。尔乃税驾乎蘅皋,秣驷乎芝田,容与乎阳林,流眄乎洛川。于是精移神骇,忽焉思散。俯则末察,仰以殊观,睹一丽人,于岩之畔。乃援御者而告之曰:“尔有觌于彼者乎?彼何人斯?若此之艳也!”御者对曰:“臣闻河洛之神,名曰宓妃。然则君王所见,无乃日乎?其状若何?臣愿闻之。”余告之曰:“其形也,翩若惊鸿,婉若游龙。荣曜秋菊,华茂春松。仿佛兮若轻云之蔽月,飘摇兮若流风之回雪。远而望之,皎若太阳升朝霞;迫而察之,灼若芙蕖出渌波。秾纤得衷,修短合度。肩若削成,腰如约素。延颈秀项,皓质呈露。芳泽无加,铅华弗御。云髻峨峨,修眉联娟。丹唇外朗,皓齿内鲜,明眸善睐,靥辅承权。瑰姿艳逸,仪静体闲。柔情绰态,媚于语言。奇服旷世,骨像应图。披罗衣之璀粲兮,珥瑶碧之华琚。戴金翠之首饰,缀明珠以耀躯。践远游之文履,曳雾绡之轻裾。微幽兰之芳蔼兮,步踟蹰于山隅。于是忽焉纵体,以遨以嬉。左倚采旄,右荫桂旗。壤皓腕于神浒兮,采湍濑之玄芝。余情悦其淑美兮,心振荡而不怡。无良媒以接欢兮,托微波而通辞。愿诚素之先达兮,解玉佩以要之。嗟佳人之信修,羌习礼而明诗。抗琼[王弟]以和予兮,指潜渊而为期。执眷眷之款实兮,惧斯灵之我欺。感交甫之弃言兮,怅犹豫而狐疑。收和颜而静志兮,申礼防以自持。于是洛灵感焉,徙倚彷徨,神光离合,乍阴乍阳。竦轻躯以鹤立,若将飞而未翔。践椒涂之郁烈,步蘅薄而流芳。超长吟以永慕兮,声哀厉而弥长。尔乃众灵杂遢,命俦啸侣,或戏清流,或翔神渚,或采明珠,或拾翠羽。从南湘之二妃,携汉滨之游女。叹匏瓜之无匹兮,咏牵牛之独处。扬轻袿之猗靡兮,翳修袖以延伫。休迅飞凫,飘忽若神,陵波微步,罗袜生尘。动无常则,若危若安。进止难期,若往若还。转眄流精,光润玉颜。含辞未吐,气若幽兰。华容婀娜,令我忘餐。于是屏翳收风,川后静波。冯夷鸣鼓,女娲清歌。腾文鱼以警乘,鸣玉鸾以偕逝。六龙俨其齐首,载云车之容裔,鲸鲵踊而夹毂,水禽翔而为卫。于是越北沚。过南冈,纡素领,回清阳,动朱唇以徐言,陈交接之大纲。恨人神之道殊兮,怨盛年之莫当。抗罗袂以掩涕兮,泪流襟之浪浪。悼良会之永绝兮。哀一逝而异乡。无微情以效爱兮,献江南之明。虽潜处于太阳,长寄心于君王。忽不悟其所舍,怅神宵而蔽光。于是背下陵高,足往神留,遗情想像,顾望怀愁。冀灵体之复形,御轻舟而上溯。浮长川而忘返,思绵绵督。夜耿耿而不寐,沾繁霜而至曙。命仆夫而就驾,吾将归乎东路。揽騑辔以抗策,怅盘桓而不能去。 22 |

23 |
24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /13-css-3d-tutorial/style.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | * { 8 | box-sizing: border-box; 9 | } 10 | 11 | main { 12 | display: flex; 13 | align-items: center; 14 | justify-content: center; 15 | height: 100vh; 16 | overflow-y: auto; 17 | /* https://drafts.csswg.org/css-transforms-2/#perspective-matrix-computation */ 18 | perspective: 50px; 19 | /* background-color: rgba(200, 200, 200, 0.3); */ 20 | transform-style: preserve-3d; 21 | /* transform: rotateX(-75deg); */ 22 | } 23 | 24 | .wrapper { 25 | position: absolute; 26 | width: 600px; 27 | height: 600px; 28 | background-color: rgba(200, 200, 200, 0.3); 29 | } 30 | 31 | .front, 32 | .back { 33 | width: 300px; 34 | height: 300px; 35 | position: absolute; 36 | } 37 | 38 | .front { 39 | background-color: rgba(7, 223, 184, 0.4); 40 | transform: translateZ(-50px) translateX(-500px) scale(2); 41 | } 42 | 43 | .back { 44 | background-color: rgba(255, 163, 83, 0.4); 45 | transform: translateZ(-350px) translateX(3000px) scale(8); 46 | /* transform-origin: center center -300px; */ 47 | /* animation: 5s linear rotate infinite; */ 48 | /* animation: 5s linear translateBack infinite; */ 49 | } 50 | 51 | @keyframes translateBack { 52 | from { 53 | transform: rotateY(0deg) translateZ(-1px); 54 | } 55 | to { 56 | transform: rotateY(80deg) translateZ(-1px); 57 | } 58 | } 59 | 60 | @keyframes rotate { 61 | from { 62 | transform: rotateY(0); 63 | } 64 | to { 65 | transform: rotateY(360deg); 66 | } 67 | } 68 | 69 | .text { 70 | background-color: #448cb8; 71 | padding: 2em; 72 | font-family: "PingFang SC"; 73 | } 74 | p { 75 | width: 200px; 76 | color: white; 77 | } 78 | -------------------------------------------------------------------------------- /14-image-slider/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 图片轮播组件 15 | 16 | 17 |
18 | 19 |
20 | 21 |
22 | 23 | 北京 28 | 29 |
30 |

北京

31 |

32 | 北京市,简称“京”,是中华人民共和国首都、也是中国4个直辖市之一;北京是国家中心城市、超大城市,全国政治中心、文化中心、国际交往中心、科技创新中心,是世界著名古都和现代化国际城市,也是中国共产党中央委员会、中华人民共和国中央人民政府和全国人民代表大会常务委员会的办公所在地。 33 |

34 |
35 |
36 | 37 |
38 | 39 | 东京 44 | 45 |
46 |

东京

47 |

48 | 东京(とうきょう、Tōkyō),日本首都,位于日本关东平原中部,是面向东京湾的国际大都市,日本三大都市圈之一东京都市圈的中心城市。“东京”狭义上指东京都、旧东京府或东京都区部(旧东京市),亦可泛指东京都市圈 49 | 。东京是江户幕府的所在地,江户在庆应4年7月(1868年9月)改名为东京。 50 |

51 |
52 |
53 | 54 |
55 | 56 | 纽约 61 | 62 |
63 |

纽约

64 |

65 | 纽约市(New York 66 | City,简称NYC),位于美国纽约州东南部大西洋沿岸,是美国第一大城市及第一大港口,纽约都市圈为世界上最大的城市圈之一,与英国伦敦、中国香港并称为“纽伦港”(Nylonkong)。纽约与伦敦并列为全世界最顶级的国际大都市。2018年11月,纽约被GaWC评为Alpha++级世界一线城市。 67 |

68 |
69 |
70 | 71 | 72 | 73 |
74 |
75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /14-image-slider/index.js: -------------------------------------------------------------------------------- 1 | //后退按钮 2 | const prev = document.querySelector("#prev"); 3 | //前进按钮 4 | const next = document.querySelector("#next"); 5 | 6 | // 所有幻灯片 7 | const slides = document.querySelectorAll(".slide"); 8 | 9 | // 当前正在播放的幻灯片 10 | var currentIndex = 0; 11 | 12 | // 是否自动播放 13 | var autoPlay = true; 14 | 15 | // 播放方向,前进或后退 16 | var forward = false; 17 | 18 | // 自动播放间隔,5秒 19 | var interval = 5000; 20 | 21 | // 添加前进按钮事件处理函数 22 | next.addEventListener("click", handleNextClicked); 23 | 24 | // 添加后退按钮事件处理函数 25 | prev.addEventListener("click", handlePrevClicked); 26 | 27 | // 是否自动播放 28 | if (autoPlay) { 29 | setInterval(forward ? handleNextClicked : handlePrevClicked, interval); 30 | } 31 | 32 | function handleNextClicked() { 33 | //当前幻灯片 34 | let current = slides[currentIndex]; 35 | // 去掉当前幻灯片的current属性 36 | current.classList.remove("current"); 37 | 38 | //移动到下一张幻灯片,如果没有,则从第一张开始 39 | currentIndex++; 40 | if (currentIndex >= slides.length) { 41 | currentIndex = 0; 42 | } 43 | // 给下一张幻灯片加上current class 44 | slides[currentIndex].classList.add("current"); 45 | } 46 | 47 | function handlePrevClicked() { 48 | //当前幻灯片 49 | let current = slides[currentIndex]; 50 | // 去掉当前幻灯片的current属性 51 | current.classList.remove("current"); 52 | 53 | //移动到上一张幻灯片,如果没有,则从最后一张开始 54 | currentIndex--; 55 | if (currentIndex < 0) { 56 | currentIndex = slides.length - 1; 57 | } 58 | // 给下一张幻灯片加上current class 59 | slides[currentIndex].classList.add("current"); 60 | } 61 | -------------------------------------------------------------------------------- /14-image-slider/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | font-family: "PingFang SC", "Microsoft Yahei", sans-serif; 6 | } 7 | 8 | /* 设置轮播组件占满整个屏幕 */ 9 | .image-slider { 10 | width: 100vw; 11 | height: 100vh; 12 | } 13 | 14 | /* 设置每个幻灯片占满父容器 */ 15 | .image-slider .slide { 16 | width: 100%; 17 | height: 100%; 18 | position: absolute; 19 | transition: all linear 0.8s; 20 | overflow: hidden; 21 | } 22 | 23 | /* 设置图片样式 */ 24 | .image-slider .image { 25 | /* 设置图片大小 */ 26 | width: 100%; 27 | height: 100%; 28 | /* 图片自适应,保持比例占满屏幕 */ 29 | object-fit: cover; 30 | /* 绝对布局,z-index 50放到文字下方 */ 31 | position: absolute; 32 | z-index: 50; 33 | } 34 | 35 | /* 设置文本样式 */ 36 | .image-slider .slide .content { 37 | position: absolute; 38 | /* 放在图片上方 */ 39 | z-index: 100; 40 | color: white; 41 | background-color: rgba(0, 0, 0, 0.6); 42 | padding: 48px; 43 | bottom: 0; 44 | width: 50%; 45 | } 46 | 47 | /* 标题距下方24px */ 48 | .image-slider .slide .content h1 { 49 | margin-bottom: 24px; 50 | } 51 | 52 | /* 控制按钮 */ 53 | #prev, 54 | #next { 55 | position: absolute; 56 | z-index: 150; 57 | width: 80px; 58 | height: 80px; 59 | font-size: 48px; 60 | color: white; 61 | /* 居中 */ 62 | text-align: center; 63 | line-height: 80px; 64 | 65 | /* 圆角 */ 66 | border-radius: 50%; 67 | /* 背景 */ 68 | background-color: rgba(0, 0, 0, 0.6); 69 | 70 | /* 在组件中的位置 */ 71 | top: calc(50% - 24px); 72 | left: 50px; 73 | transition: all 0.2s; 74 | cursor: pointer; 75 | } 76 | 77 | /* 下一张按钮的位置,靠右 */ 78 | #next { 79 | left: unset; 80 | right: 50px; 81 | } 82 | 83 | /* 鼠标移到按钮上时改变背景和字体颜色 */ 84 | #prev:hover, 85 | #next:hover { 86 | background-color: rgba(255, 255, 255, 0.6); 87 | color: black; 88 | } 89 | 90 | /* 隐藏其他幻灯片 */ 91 | .image-slider .slide { 92 | opacity: 0; 93 | } 94 | 95 | /* 设置当前正在播放的幻灯片的透明度为1 */ 96 | .image-slider .slide.current { 97 | opacity: 1; 98 | } 99 | 100 | /* 图片文字描述动画属性,向下移动500px */ 101 | .image-slider .slide .content { 102 | opacity: 0; 103 | transform: translateY(500px); 104 | } 105 | 106 | /* 当前正在播放的幻灯片的文字描述位置移动到原位 */ 107 | .image-slider .slide.current .content { 108 | opacity: 1; 109 | transform: translateY(0); 110 | transition: all 1s ease-in-out 0.4s; 111 | } 112 | 113 | /* 适配屏幕 */ 114 | @media screen and (max-width: 960px) { 115 | /* 文字占满屏幕 */ 116 | .image-slider .slide .content { 117 | width: 100%; 118 | } 119 | 120 | /* 控制按钮大小和间距缩小 */ 121 | #prev, 122 | #next { 123 | font-size: 24px; 124 | left: 24px; 125 | width: 48px; 126 | height: 48px; 127 | line-height: 48px; 128 | top: 40%; 129 | } 130 | 131 | /* 移动下一张按钮,使间距变小 */ 132 | #next { 133 | left: unset; 134 | right: 24px; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /15-responsive-navbar/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/15-responsive-navbar/background.jpg -------------------------------------------------------------------------------- /15-responsive-navbar/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 响应式导航菜单 9 | 10 | 11 | 26 | 27 |
28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /15-responsive-navbar/index.js: -------------------------------------------------------------------------------- 1 | // 获取汉堡按钮 2 | const burger = document.querySelector(".burger"); 3 | // 获取导航菜单 4 | const navMenu = document.querySelector(".nav-menu"); 5 | 6 | //获取菜单项 7 | const navMenuItems = document.querySelectorAll(".nav-menu li"); 8 | 9 | //注册监听 10 | burger.addEventListener("click", () => { 11 | // 汉堡按钮 12 | burger.classList.toggle("active"); 13 | // 导航菜单开关 14 | navMenu.classList.toggle("open"); 15 | 16 | // 菜单项动画 17 | navMenuItems.forEach((item, index) => { 18 | // 如果已添加animation,先取消 19 | if (item.style.animation) { 20 | item.style.animation = ""; 21 | } else { 22 | item.style.animation = `0.3s ease-in slideIn forwards ${index * 0.1 + 23 | 0.3}s`; 24 | } 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /15-responsive-navbar/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | font-family: "PingFang SC", "Microsoft Yahei", sans-serif; 6 | } 7 | 8 | header { 9 | width: 100vw; 10 | height: 100vh; 11 | background-image: url(./background.jpg); 12 | background-size: cover; 13 | } 14 | 15 | nav { 16 | position: absolute; 17 | top: 0; 18 | left: 0; 19 | right: 0; 20 | display: flex; 21 | align-items: center; 22 | justify-content: space-between; 23 | /* 左右padding */ 24 | padding: 0 5vw; 25 | height: 80px; 26 | background-color: rgba(65, 81, 101, 0.9); 27 | } 28 | 29 | .logo { 30 | font-size: 24px; 31 | font-weight: 600; 32 | color: #dadbdd; 33 | /* 占一半宽度 */ 34 | flex: 1; 35 | } 36 | 37 | .nav-menu { 38 | /* 占令一半宽度 */ 39 | flex: 1; 40 | display: flex; 41 | justify-content: space-between; 42 | 43 | /* 最宽550px */ 44 | max-width: 550px; 45 | } 46 | 47 | .nav-menu li { 48 | list-style: none; 49 | color: #dadbdd; 50 | font-weight: 600; 51 | } 52 | 53 | .burger div { 54 | /* 设置汉堡按钮三层条 */ 55 | width: 25px; 56 | height: 3px; 57 | background-color: #dadbdd; 58 | margin: 4px; 59 | } 60 | 61 | .burger { 62 | display: none; 63 | } 64 | 65 | /* 屏幕适配 */ 66 | @media screen and (max-width: 768px) { 67 | .burger { 68 | display: block; 69 | } 70 | 71 | /* 小屏幕菜单显示位置为右侧抽屉形式 */ 72 | .nav-menu { 73 | position: absolute; 74 | top: 80px; 75 | right: 0; 76 | bottom: 0; 77 | width: 50vw; 78 | height: calc(100vh - 80px); 79 | 80 | background-color: rgb(65, 81, 101, 0.9); 81 | flex-direction: column; 82 | justify-content: flex-start; 83 | align-items: center; 84 | 85 | /* 动画 */ 86 | transform: translateX(100%); 87 | } 88 | 89 | /* 菜单打开时,滑到初始位置 */ 90 | .nav-menu.open { 91 | transform: translateX(0); 92 | transition: 0.4s ease-in-out; 93 | } 94 | 95 | /* 每个菜单项默认看不到,向右移动20象素 */ 96 | .nav-menu li { 97 | /* 上下间距 */ 98 | margin: 3vh; 99 | transform: translateX(20px); 100 | opacity: 0; 101 | } 102 | 103 | /* 汉堡按钮被点开时,设置按钮过渡 */ 104 | .burger.active div { 105 | transition: 0.3s ease-in-out 0.3s; 106 | } 107 | 108 | /* 第一条线旋转45度 */ 109 | .burger.active .top-line { 110 | transform: rotate(45deg) translate(4px, 6px); 111 | } 112 | 113 | /* 第三条线旋转-45度 */ 114 | .burger.active .bottom-line { 115 | transform: rotate(-45deg) translate(4px, -6px); 116 | } 117 | 118 | /* 中间线向右移动并变为透明 */ 119 | .burger.active .middle-line { 120 | opacity: 0; 121 | transform: translateX(10px); 122 | transition: 0.3s ease-in-out; 123 | } 124 | 125 | /* 菜单项滑入动画 */ 126 | @keyframes slideIn { 127 | from { 128 | transform: translateX(20px); 129 | opacity: 0; 130 | } 131 | to { 132 | transform: translateX(0); 133 | opacity: 1; 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /16-svg-animation-truck/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | padding: 0; 3 | margin: 0; 4 | box-sizing: border-box; 5 | } 6 | 7 | main { 8 | display: flex; 9 | justify-content: center; 10 | align-items: center; 11 | height: 100vh; 12 | } 13 | 14 | #boards { 15 | transform-box: fill-box; 16 | transform-origin: center; 17 | animation: 2s linear swing alternate infinite; 18 | } 19 | 20 | #string { 21 | transform-box: fill-box; 22 | transform-origin: 0 10px; 23 | animation: 2s linear swing2 alternate infinite; 24 | } 25 | 26 | #truck { 27 | transform-box: fill-box; 28 | transform-origin: center; 29 | animation: 1s linear bounce alternate infinite; 30 | } 31 | 32 | .smoke { 33 | transform-box: fill-box; 34 | transform-origin: 40% bottom; 35 | animation: 10s linear smoke infinite; 36 | } 37 | 38 | .smoke2 { 39 | animation: 12s linear 2s smoke infinite; 40 | } 41 | 42 | #building-smoke { 43 | animation: 2s linear 1s building-smoke alternate infinite; 44 | } 45 | 46 | #cloud { 47 | animation: 60s linear cloud infinite; 48 | } 49 | 50 | @keyframes swing { 51 | from { 52 | transform: rotate(-10deg) translateX(9px); 53 | } 54 | to { 55 | transform: rotate(10deg) translateX(-9px); 56 | } 57 | } 58 | 59 | @keyframes swing2 { 60 | from { 61 | transform: rotate(-10deg); 62 | } 63 | to { 64 | transform: rotate(10deg); 65 | } 66 | } 67 | 68 | @keyframes bounce { 69 | from { 70 | transform: translateY(-2px); 71 | } 72 | to { 73 | transform: translateY(0px); 74 | } 75 | } 76 | 77 | @keyframes smoke { 78 | from { 79 | transform: scale(0); 80 | opacity: 1; 81 | } 82 | 83 | 30% { 84 | transform: scale(0.7) translateY(-10px); 85 | } 86 | 87 | 60% { 88 | opacity: 1; 89 | } 90 | 91 | to { 92 | transform: scale(2) translateY(-100px); 93 | opacity: 0; 94 | } 95 | } 96 | 97 | @keyframes building-smoke { 98 | from { 99 | opacity: 1; 100 | } 101 | to { 102 | opacity: 0.5; 103 | } 104 | } 105 | 106 | @keyframes cloud { 107 | from { 108 | transform: translateX(-400px); 109 | } 110 | to { 111 | transform: translateX(800px); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /17-upload-button/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 上传按钮-动画 9 | 10 | 11 |
12 |
13 | 14 | 15 | 23 | 24 | 25 | 26 | 27 | 34 | 41 | 42 | 51 | 52 |
53 |
54 |
55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /17-upload-button/index.js: -------------------------------------------------------------------------------- 1 | // 获取上传按钮和进度条 2 | var uploadButton = document.querySelector(".upload-button"); 3 | var progressBar = document.querySelector(".upload-button .progress-bar"); 4 | 5 | // 进度条完成时的宽度 6 | let width = uploadButton.getBoundingClientRect().width; 7 | // 假定上传时间为5s 8 | let uploadTime = 5000; 9 | 10 | uploadButton.addEventListener("click", () => { 11 | // 先移除之前的完成样式 12 | uploadButton.classList.remove("uploaded"); 13 | 14 | //设置正在上传.uploading样式 15 | uploadButton.classList.add("uploading"); 16 | 17 | //假设5秒后上传完成 18 | setTimeout(() => { 19 | uploadButton.classList.replace("uploading", "uploaded"); 20 | }, uploadTime); 21 | 22 | let start = null; 23 | function grow(timestamp) { 24 | // 动画开始时的时间戳 25 | if (!start) start = timestamp; 26 | // 距离开始时已经过的时间戳 27 | let progress = timestamp - start; 28 | 29 | //按比例增加进度条宽度 30 | progressBar.style.width = `${Math.min( 31 | width * (progress / uploadTime), 32 | width 33 | )}px`; 34 | 35 | // 如果上传未完成,继续执行此函数,递归循环 36 | if (progress < uploadTime) { 37 | window.requestAnimationFrame(grow); 38 | } 39 | } 40 | 41 | // 开始执行grow函数 42 | window.requestAnimationFrame(grow); 43 | }); 44 | -------------------------------------------------------------------------------- /17-upload-button/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | padding: 0; 3 | margin: 0; 4 | box-sizing: border-box; 5 | font-family: "PingFang SC", "Microsoft Yahei", sans-serif; 6 | } 7 | 8 | /* 把按钮居中 */ 9 | main { 10 | display: flex; 11 | align-items: center; 12 | justify-content: center; 13 | background: #222f3e; 14 | height: 100vh; 15 | } 16 | 17 | /* 设置上传按钮样式 */ 18 | .upload-button { 19 | /* 样式 */ 20 | width: 180px; 21 | height: 60px; 22 | background-image: linear-gradient(160deg, #0093e9, #80d0c7); 23 | 24 | border-radius: 8px; 25 | cursor: pointer; 26 | box-shadow: 0 2px 10px rgba(0, 147, 233, 0.28); 27 | 28 | /* 子元素对齐 */ 29 | position: relative; 30 | display: flex; 31 | align-items: center; 32 | justify-content: center; 33 | overflow: hidden; 34 | } 35 | 36 | /* 对勾,默认隐藏 */ 37 | .upload-button .checkmark { 38 | opacity: 0; 39 | } 40 | 41 | /* 进度条样式 */ 42 | .upload-button .progress-bar { 43 | position: absolute; 44 | height: 2px; 45 | bottom: 0; 46 | left: 0; 47 | border-radius: 4px; 48 | background-image: linear-gradient(45deg, #85ffbd, #fffb7d); 49 | } 50 | 51 | /* 上传时,箭头中间线的动画,虚线上行 */ 52 | .upload-button.uploading .middle-line { 53 | stroke-dasharray: 4 3; 54 | animation: 0.8s linear dashLoop infinite; 55 | } 56 | 57 | /* 上传图标圆形闪烁 */ 58 | .upload-button.uploading circle { 59 | animation: 1.5s linear blink infinite; 60 | } 61 | 62 | /* 上传完成后箭头上半部分动画, 画线擦除动画, 最后透明度设置为0 */ 63 | .upload-button.uploaded .arrow-top { 64 | animation: 1s linear arrowTransform forwards; 65 | } 66 | 67 | /* 上传完成后对勾动画,画线效果 */ 68 | .upload-button.uploaded .checkmark { 69 | opacity: 1; 70 | stroke-dasharray: 100 100; 71 | stroke-dashoffset: 100; 72 | animation: 1s linear checkmarkTransform forwards 0.5s; 73 | } 74 | 75 | /* 上传完成后,隐藏箭头中间的线 */ 76 | .upload-button.uploaded .middle-line { 77 | transition: 0.3s linear; 78 | opacity: 0; 79 | } 80 | 81 | /* 箭头中间线虚线上行动画 */ 82 | @keyframes dashLoop { 83 | from { 84 | stroke-dashoffset: 0; 85 | } 86 | to { 87 | stroke-dashoffset: 7; 88 | } 89 | } 90 | 91 | /* 圆形闪烁动画 */ 92 | @keyframes blink { 93 | from { 94 | opacity: 1; 95 | } 96 | 50% { 97 | opacity: 0.5; 98 | } 99 | to { 100 | opacity: 1; 101 | } 102 | } 103 | 104 | /* 箭头变形动画 */ 105 | @keyframes arrowTransform { 106 | from { 107 | stroke-dasharray: 100 100; 108 | stroke-dashoffset: 0; 109 | } 110 | 111 | to { 112 | stroke-dasharray: 100 100; 113 | stroke-dashoffset: -100; 114 | } 115 | } 116 | 117 | /* 对勾动画 */ 118 | @keyframes checkmarkTransform { 119 | from { 120 | stroke-dasharray: 100 100; 121 | stroke-dashoffset: 100; 122 | } 123 | to { 124 | stroke-dasharray: 100 100; 125 | stroke-dashoffset: 0; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /18-elsa-magic-effect/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 16 | Document 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /19-profile-card/index.js: -------------------------------------------------------------------------------- 1 | // 获取导航菜单项 2 | const navMenuItems = document.querySelectorAll("#nav-menu a"); 3 | // 获取指示条实例,用来做动画 4 | const indicator = document.querySelector(".indicator"); 5 | 6 | // 点击菜单项时的事件处理函数 7 | function handleMenuItemClick(target) { 8 | // 取消所有active状态和style样式,为了重新触发动画 9 | navMenuItems.forEach(item => { 10 | item.classList.remove("active"); 11 | item.style = ""; 12 | }); 13 | target.classList.add("active"); 14 | // 设置指示条为菜单项的宽度 15 | indicator.style.width = `${target.offsetWidth}px`; 16 | // 设置指示条位置为菜单项的起始位置 17 | indicator.style.left = `${target.offsetLeft}px`; 18 | 19 | // 改变section,旧的active的section移除active状态,并且淡出 20 | const currentSection = document.querySelector(".active-section"); 21 | currentSection.classList.remove("active-section"); 22 | 23 | // 获取点击的菜单项对应的分区实例,如个人简介或工作经历 24 | const newCurrentSection = document.querySelector( 25 | `.${target.getAttribute("data-rel")}` 26 | ); 27 | newCurrentSection.classList.add("active-section"); 28 | } 29 | 30 | navMenuItems.forEach(item => { 31 | // 每个菜单项点击时调用事件处理函数 32 | item.addEventListener("click", e => handleMenuItemClick(e.target)); 33 | 34 | // 首次页面展示时,工作简介菜单是active的,先触发一次点击处理 35 | item.classList.contains("active") && handleMenuItemClick(item); 36 | }); 37 | -------------------------------------------------------------------------------- /19-profile-card/me.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/19-profile-card/me.jpeg -------------------------------------------------------------------------------- /20-typewritter-effect/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | Document 14 | 15 | 16 | 17 |
18 | 19 |

20 | 21 | 25 | 26 | 27 |

28 |
29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /20-typewritter-effect/index.js: -------------------------------------------------------------------------------- 1 | // 获取显示文字的span元素 2 | const textEl = document.querySelector("#text"); 3 | // 获取并解析要展示的文本数组 4 | const texts = JSON.parse(textEl.getAttribute("data-text")); 5 | 6 | // 当前显示文本数组中的第几个 7 | let index = 0; 8 | // 当前显示第几个字 9 | let charIndex = 0; 10 | // 每个字显示间隔默认是500毫秒 11 | let delta = 500; 12 | 13 | // 记录动画执行开始时间 14 | let start = null; 15 | // 是否为删除动画 16 | let isDeleting = false; 17 | 18 | // 动画回调函数 19 | function type(time) { 20 | window.requestAnimationFrame(type); 21 | // 初始化开始时间 22 | if (!start) start = time; 23 | // 获取时间间隔 24 | let progress = time - start; 25 | // 每隔一定的时间,打印出一个新的字符 26 | if (progress > delta) { 27 | // 获取完整的字符 28 | let text = texts[index]; 29 | // 如果是打字效果 30 | if (!isDeleting) { 31 | // 给展示文字的span新增一个字符,使用innerHTML来替换,charIndex自增1,然后返回新的字符串子串 32 | textEl.innerHTML = text.slice(0, ++charIndex); 33 | // 每个字符打印出来的速度不一样,模仿人工打字的速度 34 | delta = 500 - Math.random() * 400; 35 | } else { 36 | // 如果是删除效果,则把文字一个一个减掉 37 | textEl.innerHTML = text.slice(0, charIndex--); 38 | } 39 | // 把star更新为当前时间,进行下一个周期 40 | start = time; 41 | 42 | // 如果文字已经全部打印完毕 43 | if (charIndex === text.length) { 44 | // 下次开始删除文字 45 | isDeleting = true; 46 | // 删除文字的间隔为200毫秒 47 | delta = 200; 48 | // 额外等待1.2秒后再删除 49 | start = time + 1200; 50 | } 51 | 52 | // 如果文字删除完毕 53 | if (charIndex < 0) { 54 | isDeleting = false; 55 | // 额外增加200毫秒延迟 56 | start = time + 200; 57 | // 把index移动到下一个文本,并且在文本数组元素个数中循环 58 | index = ++index % texts.length; 59 | } 60 | } 61 | } 62 | 63 | window.requestAnimationFrame(type); 64 | -------------------------------------------------------------------------------- /20-typewritter-effect/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | font-family: "huxiaobo-gdh1e91397a5f211c5", "PingFang SC", "Microsoft Yahei", 6 | sans-serif; 7 | } 8 | 9 | main { 10 | background: #2f3542; 11 | display: flex; 12 | align-items: center; 13 | justify-content: center; 14 | height: 100vh; 15 | } 16 | 17 | h1 { 18 | color: #f1f2f6; 19 | font-size: 5em; 20 | font-weight: 300; 21 | } 22 | 23 | span.mark { 24 | border-right: 2px solid white; 25 | animation: blink 0.6s step-end infinite; 26 | } 27 | 28 | @keyframes blink { 29 | from, 30 | to { 31 | border-color: transparent; 32 | } 33 | 50% { 34 | border-color: white; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /21-range-slider/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |
11 |
12 | 13 | 14 | 50 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /21-range-slider/index.js: -------------------------------------------------------------------------------- 1 | // 获取滑动选择器实例 2 | const sliderEl = document.querySelector("#slider-input"); 3 | // 获取数值显示容器实例 4 | const selectedEl = document.querySelector(".selected"); 5 | 6 | // 监听滑动事件 7 | sliderEl.addEventListener("input", () => { 8 | selectedEl.innerHTML = sliderEl.value; 9 | }); 10 | -------------------------------------------------------------------------------- /21-range-slider/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | font-family: Helvetica, "PingFang SC", "Microsoft Yahei", sans-serif; 6 | } 7 | 8 | main { 9 | display: flex; 10 | align-items: center; 11 | justify-content: center; 12 | height: 100vh; 13 | background-color: #1e272e; 14 | } 15 | 16 | /* 选择器容器 */ 17 | .slider { 18 | width: 50%; 19 | display: flex; 20 | align-items: center; 21 | } 22 | 23 | input[type="range"] { 24 | /* 禁用浏览器默认外观 */ 25 | -webkit-appearance: none; 26 | background: linear-gradient(75deg, #3c40c6 0%, #575fcf 100%); 27 | border-radius: 4px; 28 | width: 100%; 29 | height: 12px; 30 | outline: none; 31 | box-shadow: 0 0 6px rgb(28, 32, 148); 32 | } 33 | 34 | /* 滑动选择器上的滑动按钮 */ 35 | input[type="range"]::-webkit-slider-thumb { 36 | -webkit-appearance: none; 37 | width: 20px; 38 | height: 20px; 39 | border-radius: 50%; 40 | background-color: #f53b57; 41 | transition: 0.3s; 42 | } 43 | 44 | /* 当滑动选择器上的滑动按钮滑动时 */ 45 | input[type="range"]:active::-webkit-slider-thumb { 46 | background-color: #ef5777; 47 | box-shadow: 0 0 0 6px rgba(155, 73, 146, 0.4); 48 | } 49 | 50 | /* 显示数值的容器 */ 51 | .selected { 52 | margin-right: 16px; 53 | background-color: #f53b57; 54 | width: 80px; 55 | line-height: 40px; 56 | text-align: center; 57 | color: white; 58 | border-radius: 4px; 59 | position: relative; 60 | } 61 | 62 | /* 三角 */ 63 | .selected::after { 64 | content: ""; 65 | display: block; 66 | border-top: 8px solid transparent; 67 | border-left: 8px solid #f53b57; 68 | border-bottom: 8px solid transparent; 69 | position: absolute; 70 | top: calc(50% - 8px); 71 | right: -6px; 72 | } 73 | -------------------------------------------------------------------------------- /22-face-reco-mask/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
识别中...
16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /22-face-reco-mask/index.js: -------------------------------------------------------------------------------- 1 | async function faceDetection() { 2 | // 获取加载实例 3 | const loading = document.querySelector(".loading"); 4 | loading.style.display = "flex"; 5 | 6 | // 加载模型 7 | // 人脸检测模型 8 | await faceapi.nets.ssdMobilenetv1.loadFromUri("models"); 9 | // 人脸地标模型 10 | await faceapi.nets.faceLandmark68Net.loadFromUri("models"); 11 | // 人脸识别模型 12 | // await faceapi.nets.faceRecognitionNet.loadFromUri("models"); 13 | 14 | // 获取图片实例 15 | const input = document.getElementById("image"); 16 | 17 | // 开始人脸识别,先识别脸,只返回一个最接近的人脸数据 18 | // 再识别眼、嘴、鼻的位置,使用68个点坐标模型 19 | // 最后获取脸部描述 20 | const detection = await faceapi.detectSingleFace(input).withFaceLandmarks(); 21 | // .withFaceDescriptors(); 22 | 23 | // const canvas = document.getElementById("overlay"); 24 | const displaySize = { width: input.width, height: input.height }; 25 | // faceapi.matchDimensions(canvas, displaySize); 26 | const resizedDetection = faceapi.resizeResults(detection, displaySize); 27 | 28 | // faceapi.draw.drawDetections(canvas, resizedDetection); 29 | // faceapi.draw.drawFaceLandmarks(canvas, resizedDetection); 30 | 31 | // const ctx = canvas.getContext("2d"); 32 | 33 | // 获取口罩实例 34 | const mask = document.getElementById("mask"); 35 | // 获取识别的脸部 36 | const { landmarks } = resizedDetection; 37 | const { imageWidth, positions } = landmarks; 38 | // 左耳附近 39 | const { _x: x, _y: y } = positions[1]; 40 | // 获取鼻子上部到下巴的长度 41 | const height = Math.sqrt( 42 | Math.pow(positions[1]._x - positions[8]._x, 2) + 43 | Math.pow(positions[1]._y - positions[8]._y, 2) 44 | ); 45 | // console.log(height); 46 | 47 | mask.width = imageWidth; 48 | mask.height = height * 0.9; 49 | mask.style.transform = `translate(${x + imageWidth * 0.03}px, ${y - 50 | height * 0.05}px)`; 51 | 52 | loading.style.display = "none"; 53 | 54 | mask.style.opacity = 1; 55 | 56 | // positions.forEach((position, index) => { 57 | // const { _x, _y } = position; 58 | // ctx.fillStyle = "#ffffff"; 59 | // ctx.font = "300 6px sans-serif"; 60 | // ctx.fillText(index, _x, _y); 61 | // }); 62 | 63 | console.log(resizedDetection); 64 | 65 | console.log("done"); 66 | } 67 | 68 | faceDetection(); 69 | -------------------------------------------------------------------------------- /22-face-reco-mask/mask.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Artboard 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /22-face-reco-mask/models/face_landmark_68_model-shard1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/22-face-reco-mask/models/face_landmark_68_model-shard1 -------------------------------------------------------------------------------- /22-face-reco-mask/models/face_recognition_model-shard1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/22-face-reco-mask/models/face_recognition_model-shard1 -------------------------------------------------------------------------------- /22-face-reco-mask/models/face_recognition_model-shard2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/22-face-reco-mask/models/face_recognition_model-shard2 -------------------------------------------------------------------------------- /22-face-reco-mask/models/ssd_mobilenetv1_model-shard1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/22-face-reco-mask/models/ssd_mobilenetv1_model-shard1 -------------------------------------------------------------------------------- /22-face-reco-mask/models/ssd_mobilenetv1_model-shard2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/22-face-reco-mask/models/ssd_mobilenetv1_model-shard2 -------------------------------------------------------------------------------- /22-face-reco-mask/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | font-family: "PingFang SC", "Microsoft Yahei", sans-serif; 6 | } 7 | 8 | /* canvas { 9 | position: absolute; 10 | } */ 11 | 12 | #image { 13 | width: 100vw; 14 | height: 100vh; 15 | object-fit: cover; 16 | } 17 | 18 | #mask { 19 | position: absolute; 20 | left: 0; 21 | top: 0; 22 | opacity: 0; 23 | } 24 | 25 | div.loading { 26 | position: absolute; 27 | top: 0; 28 | bottom: 0; 29 | width: 100%; 30 | height: 100%; 31 | display: flex; 32 | align-items: center; 33 | justify-content: center; 34 | flex-direction: column; 35 | background: rgba(0, 0, 0, 0.5); 36 | font-size: 2em; 37 | color: white; 38 | display: none; 39 | } 40 | 41 | div.loading img { 42 | margin-bottom: 1em; 43 | animation: rotate 2s linear infinite; 44 | } 45 | 46 | @keyframes rotate { 47 | from { 48 | transform: rotate(0); 49 | } 50 | to { 51 | transform: rotate(360deg); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /22-face-reco-mask/woman.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/22-face-reco-mask/woman.jpg -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/images/activity01-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/23-fullwebsite-design-agency/images/activity01-image.jpg -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/images/adult-business-computer-contemporary-380769.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/23-fullwebsite-design-agency/images/adult-business-computer-contemporary-380769.jpg -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/images/apple-apple-device-design-desk-285814.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/23-fullwebsite-design-agency/images/apple-apple-device-design-desk-285814.jpg -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/images/apple-laptop-notebook-office-39284.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/23-fullwebsite-design-agency/images/apple-laptop-notebook-office-39284.jpg -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/images/blur-close-up-code-computer-546819.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/23-fullwebsite-design-agency/images/blur-close-up-code-computer-546819.jpg -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/images/bokeh-photography-of-person-holding-turned-on-iphone-1440727.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/23-fullwebsite-design-agency/images/bokeh-photography-of-person-holding-turned-on-iphone-1440727.jpg -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/images/business-woman-2697954_1920.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/23-fullwebsite-design-agency/images/business-woman-2697954_1920.jpg -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/images/gray-laptop-computer-showing-html-codes-in-shallow-focus-160107.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/23-fullwebsite-design-agency/images/gray-laptop-computer-showing-html-codes-in-shallow-focus-160107.jpg -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/images/man-wearing-black-suit-2955376.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/23-fullwebsite-design-agency/images/man-wearing-black-suit-2955376.jpg -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/images/people-in-couch-1024248.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/23-fullwebsite-design-agency/images/people-in-couch-1024248.jpg -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/images/person-holding-a-smartphone-892757.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/23-fullwebsite-design-agency/images/person-holding-a-smartphone-892757.jpg -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/images/person-using-black-and-white-smartphone-and-holding-blue-230544.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/23-fullwebsite-design-agency/images/person-using-black-and-white-smartphone-and-holding-blue-230544.jpg -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/images/photo-of-imac-near-macbook-1029757.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/23-fullwebsite-design-agency/images/photo-of-imac-near-macbook-1029757.jpg -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/images/red-suspension-bridge-3493772.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/23-fullwebsite-design-agency/images/red-suspension-bridge-3493772.jpg -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/images/selective-focus-photograph-of-man-wearing-gray-suit-jacket-1138903.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/23-fullwebsite-design-agency/images/selective-focus-photograph-of-man-wearing-gray-suit-jacket-1138903.jpg -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/images/smiling-woman-wearing-black-sweater-1587009.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/23-fullwebsite-design-agency/images/smiling-woman-wearing-black-sweater-1587009.jpg -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/images/watercrafts-on-river-3464632.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/23-fullwebsite-design-agency/images/watercrafts-on-river-3464632.jpg -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/libs/glide/glide.core.min.css: -------------------------------------------------------------------------------- 1 | .glide{position:relative;width:100%;box-sizing:border-box}.glide *{box-sizing:inherit}.glide__track{overflow:hidden}.glide__slides{position:relative;width:100%;list-style:none;backface-visibility:hidden;transform-style:preserve-3d;touch-action:pan-Y;overflow:hidden;padding:0;white-space:nowrap;display:flex;flex-wrap:nowrap;will-change:transform}.glide__slides--dragging{user-select:none}.glide__slide{width:100%;height:100%;flex-shrink:0;white-space:normal;user-select:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent}.glide__slide a{user-select:none;-webkit-user-drag:none;-moz-user-select:none;-ms-user-select:none}.glide__arrows{-webkit-touch-callout:none;user-select:none}.glide__bullets{-webkit-touch-callout:none;user-select:none}.glide--rtl{direction:rtl} 2 | -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/libs/glide/glide.theme.min.css: -------------------------------------------------------------------------------- 1 | .glide__arrow{position:absolute;display:block;top:50%;z-index:2;color:white;text-transform:uppercase;padding:9px 12px;background-color:transparent;border:2px solid rgba(255,255,255,0.5);border-radius:4px;box-shadow:0 0.25em 0.5em 0 rgba(0,0,0,0.1);text-shadow:0 0.25em 0.5em rgba(0,0,0,0.1);opacity:1;cursor:pointer;transition:opacity 150ms ease, border 300ms ease-in-out;transform:translateY(-50%);line-height:1}.glide__arrow:focus{outline:none}.glide__arrow:hover{border-color:white}.glide__arrow--left{left:2em}.glide__arrow--right{right:2em}.glide__arrow--disabled{opacity:0.33}.glide__bullets{position:absolute;z-index:2;bottom:2em;left:50%;display:inline-flex;list-style:none;transform:translateX(-50%)}.glide__bullet{background-color:rgba(255,255,255,0.5);width:9px;height:9px;padding:0;border-radius:50%;border:2px solid transparent;transition:all 300ms ease-in-out;cursor:pointer;line-height:0;box-shadow:0 0.25em 0.5em 0 rgba(0,0,0,0.1);margin:0 0.25em}.glide__bullet:focus{outline:none}.glide__bullet:hover,.glide__bullet:focus{border:2px solid white;background-color:rgba(255,255,255,0.5)}.glide__bullet--active{background-color:white}.glide--swipeable{cursor:grab;cursor:-moz-grab;cursor:-webkit-grab}.glide--dragging{cursor:grabbing;cursor:-moz-grabbing;cursor:-webkit-grabbing} 2 | -------------------------------------------------------------------------------- /23-fullwebsite-design-agency/videos/working-man.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/23-fullwebsite-design-agency/videos/working-man.mp4 -------------------------------------------------------------------------------- /24-fetch-get-data/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /24-fetch-get-data/index.js: -------------------------------------------------------------------------------- 1 | async function getData() { 2 | // 获取 response 3 | const response = await fetch("https://jsonplaceholder.typicode.com/posts"); 4 | // 获取结果 JSON 5 | const posts = await response.json(); 6 | 7 | // 打印结果 8 | console.log(posts); 9 | 10 | // 获取 root element 11 | const root = document.querySelector("#root"); 12 | 13 | // 创建 ul 14 | const ul = document.createElement("ul"); 15 | 16 | // 对于每篇文章,创建一个 li,再在里边创建一个 a,然后把结果追加到 ul 里 17 | posts.forEach(post => { 18 | const li = document.createElement("li"); 19 | const anchor = document.createElement("a"); 20 | anchor.appendChild(document.createTextNode(post.title)); 21 | anchor.setAttribute( 22 | "href", 23 | `https://jsonplaceholder.typicode.com/posts/${post.id}` 24 | ); 25 | 26 | li.appendChild(anchor); 27 | 28 | ul.appendChild(li); 29 | }); 30 | // 把 root 追加到 ul 里 31 | root.appendChild(ul); 32 | } 33 | 34 | // 调用函数 35 | getData(); 36 | -------------------------------------------------------------------------------- /24-fetch-get-data/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | font-family: Helvetica, "PingFang SC", "Microsoft Yahei", sans-serif; 6 | } 7 | 8 | body { 9 | background-color: #f1f2f6; 10 | } 11 | 12 | #root { 13 | padding: 24px 8vw; 14 | } 15 | 16 | li { 17 | list-style: none; 18 | margin: 16px 0; 19 | } 20 | 21 | a { 22 | display: block; 23 | text-decoration: none; 24 | color: #2f3542; 25 | font-size: 18px; 26 | 27 | /* 超过部分省略 */ 28 | text-overflow: ellipsis; 29 | white-space: nowrap; 30 | overflow: hidden; 31 | 32 | transition: 0.3s; 33 | max-width: 100vw; 34 | } 35 | 36 | a:hover { 37 | color: #1e90ff; 38 | } 39 | -------------------------------------------------------------------------------- /25-neumorphism-tabs/icons/icon1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /25-neumorphism-tabs/icons/icon2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /25-neumorphism-tabs/icons/icon3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /25-neumorphism-tabs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Tab 选项卡 9 | 10 | 11 |
12 |
13 |
14 |
选项一
15 |
选项二
16 |
选项三
17 |
18 |
19 |
20 |

选项 1 内容

21 | 图标 1 22 |
23 |
24 |

选项 2 内容

25 | 图标 2 26 |
27 |
28 |

选项 3 内容

29 | 图标 3 30 |
31 |
32 |
33 |
34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /25-neumorphism-tabs/index.js: -------------------------------------------------------------------------------- 1 | const tabContainer = document.querySelector(".tabs"); 2 | const tabs = document.querySelectorAll(".tab"); 3 | const tabContents = document.querySelectorAll(".tab-content > *"); 4 | 5 | // tab 点击事件 6 | tabContainer.addEventListener("click", ({ target: currentTab }) => { 7 | tabs.forEach((tab) => { 8 | tab.classList.remove("active"); 9 | }); 10 | 11 | currentTab.classList.add("active"); 12 | changeTab(currentTab.id); 13 | }); 14 | 15 | // 处理选项卡内容切换 16 | const changeTab = (tabId) => { 17 | const newTab = document.querySelector(`div[data-tab=${tabId}]`); 18 | tabContents.forEach((content) => { 19 | content.style.display = "none"; 20 | }); 21 | newTab.style.display = "block"; 22 | }; 23 | -------------------------------------------------------------------------------- /25-neumorphism-tabs/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | margin: 0; 4 | padding: 0; 5 | font-family: Helvetica, "PingFang SC", "Microsoft Yahei", sans-serif; 6 | } 7 | 8 | body { 9 | background: #f0f0f3; 10 | color: #808b9f; 11 | } 12 | 13 | .container { 14 | display: flex; 15 | align-items: center; 16 | justify-content: center; 17 | width: 100vw; 18 | height: 100vh; 19 | min-width: 375px; 20 | overflow: auto; 21 | } 22 | 23 | .tab-container { 24 | padding: 24px; 25 | width: 50%; 26 | } 27 | 28 | .tabs { 29 | padding: 4px; 30 | /* border-radius: 12px 12px 0 0; */ 31 | border-radius: 5px; 32 | background: #f0f0f3; 33 | box-shadow: -1px -1px 3px #ffffff, 1.5px 1.5px 3px rgba(174, 174, 192, 0.4); 34 | display: flex; 35 | } 36 | .tab { 37 | padding: 12px 36px; 38 | cursor: pointer; 39 | transition: 0.3s; 40 | } 41 | 42 | .tab.active { 43 | border-radius: 5px; 44 | background: #eeeeee; 45 | box-shadow: inset -1px -1px 1px rgba(255, 255, 255, 0.7), 46 | inset 1px 1px 2px rgba(174, 174, 192, 0.2); 47 | color: #a7b4cc; 48 | } 49 | 50 | .tab-content { 51 | margin-top: 36px; 52 | padding: 36px; 53 | border-radius: 16px; 54 | background: #f0f0f3; 55 | box-shadow: -10px -10px 30px #ffffff, 10px 10px 30px rgba(174, 174, 192, 0.4); 56 | } 57 | 58 | .tab-content > div > img { 59 | height: 100px; 60 | } 61 | 62 | .tab-content > div { 63 | animation: fadeIn 1.3s; 64 | } 65 | 66 | .tab-content h2 { 67 | margin-bottom: 24px; 68 | font-weight: 400; 69 | } 70 | 71 | @keyframes fadeIn { 72 | from { 73 | opacity: 0; 74 | } 75 | to { 76 | opacity: 1; 77 | } 78 | } 79 | 80 | @media (max-width: 838px) { 81 | .tab-container { 82 | width: 100%; 83 | } 84 | } 85 | 86 | @media (min-width: 375px) and (max-width: 418px) { 87 | .tab { 88 | padding: 12px 24px; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /26-glassmorphism/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/26-glassmorphism/background.jpg -------------------------------------------------------------------------------- /26-glassmorphism/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CSS 玻璃特效 7 | 49 | 50 | 51 |
52 |

CSS Glassmporphsim

53 |
54 |

Hello!

55 |
56 |
57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /30-gradient-background-animation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /31-05-wechat-emoji-effect/emoji.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /31-05-wechat-emoji-effect/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 |
12 |
13 |
与 XXX 聊天
14 |
15 |
16 | 17 |

你好

18 |
19 |
20 | 21 |

Hi

22 |
23 |
24 | 25 |

在干什么

26 |
27 |
28 | 29 |

30 |
31 |
32 | 33 |

出来玩呀

34 |
35 |
36 | 37 |

好的

38 |
39 |
40 | 54 |
55 |
56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /31-05-wechat-emoji-effect/me.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/31-05-wechat-emoji-effect/me.png -------------------------------------------------------------------------------- /31-05-wechat-emoji-effect/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --primary-color: hsl(200, 100%, 48%); 3 | --inverse-color: hsl(310, 90%, 60%); 4 | --shadow-large: 0 0px 24px hsl(0, 0%, 0%, 0.2); 5 | --shadow-medium: 0 0 12px hsl(0, 0%, 0%, 0.1); 6 | } 7 | 8 | * { 9 | box-sizing: border-box; 10 | padding: 0; 11 | margin: 0; 12 | font-family: Helvetica, "PingFang SC", "Microsoft Yahei", sans-serif; 13 | } 14 | 15 | main { 16 | display: grid; 17 | place-items: center; 18 | width: 100vw; 19 | height: 100vh; 20 | background-color: hsl(0, 0%, 10%); 21 | } 22 | 23 | .chat { 24 | width: 375px; 25 | height: 700px; 26 | background: hsl(0, 0%, 100%); 27 | border-radius: 8px; 28 | display: grid; 29 | grid-template-rows: max-content 1fr max-content; 30 | } 31 | 32 | .titleBar { 33 | padding: 24px 0; 34 | text-align: center; 35 | box-shadow: var(--shadow-large); 36 | } 37 | 38 | .panel { 39 | display: flex; 40 | flex-direction: column; 41 | padding: 24px 12px; 42 | overflow: auto; 43 | } 44 | 45 | .message { 46 | display: flex; 47 | max-width: 80%; 48 | font-size: 14px; 49 | margin: 8px 0; 50 | position: relative; 51 | } 52 | 53 | .message img { 54 | width: 40px; 55 | height: 40px; 56 | border-radius: 12px; 57 | margin-right: 12px; 58 | } 59 | 60 | .message p { 61 | padding: 8px 12px; 62 | border-radius: 12px; 63 | box-shadow: var(--shadow-large); 64 | display: flex; 65 | align-items: center; 66 | } 67 | 68 | .message.mine { 69 | flex-flow: row-reverse; 70 | align-self: flex-end; 71 | } 72 | 73 | .message.mine img { 74 | margin-right: 0; 75 | margin-left: 12px; 76 | } 77 | 78 | .message.mine p { 79 | background-color: var(--primary-color); 80 | color: white; 81 | } 82 | 83 | button, 84 | input { 85 | border: none; 86 | background: transparent; 87 | outline: none; 88 | } 89 | 90 | footer { 91 | display: grid; 92 | grid-template-columns: 48px 1fr 75px; 93 | justify-items: center; 94 | padding: 12px; 95 | box-shadow: var(--shadow-large); 96 | } 97 | 98 | .chooseSticker { 99 | justify-self: start; 100 | position: relative; 101 | } 102 | 103 | .chooseSticker img { 104 | width: 36px; 105 | height: 36px; 106 | } 107 | 108 | .stickers { 109 | display: grid; 110 | grid-template-columns: repeat(auto-fill, 24px); 111 | column-gap: 18px; 112 | 113 | border-radius: 8px; 114 | background-color: white; 115 | box-shadow: var(--shadow-medium); 116 | 117 | padding: 6px 12px; 118 | font-size: 24px; 119 | position: absolute; 120 | top: calc(-100% - 18px); 121 | width: 300px; 122 | opacity: 0; 123 | } 124 | 125 | .stickers > span { 126 | width: 40px; 127 | height: 40px; 128 | } 129 | 130 | .messageInput { 131 | box-shadow: var(--shadow-medium); 132 | padding: 0px 12px; 133 | border-radius: 8px; 134 | width: 100%; 135 | } 136 | 137 | .send { 138 | height: 100%; 139 | width: 90%; 140 | border-radius: 8px; 141 | justify-self: end; 142 | color: white; 143 | background-color: var(--inverse-color); 144 | } 145 | 146 | .show { 147 | opacity: 1; 148 | } 149 | 150 | /* .hide { 151 | opacity: 0; 152 | } */ 153 | 154 | .message p { 155 | transform-origin: left bottom; 156 | } 157 | 158 | .message.mine p { 159 | transform-origin: right bottom; 160 | } 161 | 162 | .shake { 163 | animation: shake 0.8s ease-in-out; 164 | } 165 | 166 | /* 晃动动画 */ 167 | @keyframes shake { 168 | from { 169 | transform: translate3d(0, 0px, 0px); 170 | } 171 | 10% { 172 | transform: translate3d(6px, -6px, 0px); 173 | } 174 | 20% { 175 | transform: translate3d(-5px, 5px, 0px); 176 | } 177 | 30% { 178 | transform: translate3d(4px, -4px, 0px); 179 | } 180 | 35% { 181 | transform: translate3d(-3px, 3px, 0px); 182 | } 183 | 39% { 184 | transform: translate3d(2px, -2px, 0px); 185 | } 186 | 41% { 187 | transform: translate3d(-1px, 1px, 0px); 188 | } 189 | 42% { 190 | transform: translate3d(0px, 0px, 0px) rotate(20deg); 191 | } 192 | 193 | 52% { 194 | transform: rotate(-15deg); 195 | } 196 | 197 | 60% { 198 | transform: rotate(8deg); 199 | } 200 | 201 | 65% { 202 | transform: rotate(-3deg); 203 | } 204 | 205 | 67% { 206 | transform: rotate(1deg); 207 | } 208 | 209 | 70% { 210 | transform: rotate(0deg); 211 | } 212 | 213 | to { 214 | transform: translate3d(0px, 0px, 0px) rotate(0); 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /31-05-wechat-emoji-effect/you.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/31-05-wechat-emoji-effect/you.png -------------------------------------------------------------------------------- /31-webcomponent-get-started/BlogPost.js: -------------------------------------------------------------------------------- 1 | const template = document.createElement("template"); 2 | template.innerHTML = ` 3 | 33 |
34 |

35 | 36 | 37 |
38 | `; 39 | 40 | class BlogPost extends HTMLElement { 41 | constructor() { 42 | super(); 43 | this.attachShadow({ mode: "open" }).appendChild( 44 | template.content.cloneNode(true) 45 | ); 46 | 47 | this.titleEle = this.shadowRoot.querySelector("h1"); 48 | this.buttonEle = this.shadowRoot.querySelector("button"); 49 | this.articleSlot = this.shadowRoot.querySelector("slot"); 50 | this.showFullArticle = false; 51 | this.content = ""; 52 | this.article = null; 53 | // 如果是在 js 中传递的 title 属性则不能在构造函数中直接获取,因为初始化时属性可能还没添加到组件中,需要监听它的变化, 54 | // 使用 attributeChangedCallback 生命周期方法 55 | // this.titleEle.textContent = this.getAttribute("title"); 56 | } 57 | 58 | /** 59 | * 按钮点击事件,控制是否显示全文。 60 | */ 61 | toggleFull() { 62 | this.showFullArticle = !this.showFullArticle; 63 | if (this.showFullArticle) { 64 | this.article.innerHTML = this.content; 65 | this.buttonEle.textContent = "隐藏全文"; 66 | } else { 67 | this.article.innerHTML = this.getExcept(); 68 | this.buttonEle.textContent = "查看全文"; 69 | } 70 | } 71 | 72 | /** 73 | * 当 slot 被替换为实际的 article 元素时,保存 article 元素实例 74 | * 和全文内容,再把原文改成摘要形式。 75 | */ 76 | slotChange() { 77 | const elements = this.articleSlot.assignedElements(); 78 | const article = elements[0]; 79 | this.article = article; 80 | this.content = this.article.innerHTML; 81 | this.article.innerHTML = this.getExcept(); 82 | } 83 | 84 | getExcept() { 85 | return this.content.slice(0, 60) + "..."; 86 | } 87 | 88 | connectedCallback() { 89 | this.buttonEle.addEventListener("click", this.toggleFull.bind(this)); 90 | this.articleSlot.addEventListener("slotchange", this.slotChange.bind(this)); 91 | } 92 | 93 | disconnectedCallback() { 94 | this.buttonEle.removeEventListener("click", this.toggleFull()); 95 | this.articleSlot.removeEventListener("slotchange", this.slotChange); 96 | } 97 | 98 | static get observedAttributes() { 99 | return ["title"]; 100 | } 101 | 102 | attributeChangedCallback(name, oldValue, newValue) { 103 | if (name === "title") { 104 | this.titleEle.textContent = newValue; 105 | } 106 | } 107 | } 108 | 109 | customElements.define("blog-post", BlogPost); 110 | -------------------------------------------------------------------------------- /31-webcomponent-get-started/PostList.js: -------------------------------------------------------------------------------- 1 | const template = document.createElement("template"); 2 | template.innerHTML = ` 3 | 19 |
20 | `; 21 | 22 | class PostList extends HTMLElement { 23 | constructor() { 24 | super(); 25 | this.attachShadow({ mode: "open" }).appendChild( 26 | template.content.cloneNode(true) 27 | ); 28 | } 29 | 30 | async connectedCallback() { 31 | const res = await fetch("https://jsonplaceholder.typicode.com/posts"); 32 | const posts = await res.json(); 33 | this.initPosts(posts); 34 | } 35 | 36 | initPosts(posts) { 37 | const div = this.shadowRoot.querySelector("div"); 38 | posts.forEach((post) => { 39 | const blogPostEle = div.appendChild(document.createElement("blog-post")); 40 | 41 | // 博客标题 42 | blogPostEle.setAttribute("title", post.title); 43 | 44 | // 博客文章 45 | const article = blogPostEle.appendChild( 46 | document.createElement("article") 47 | ); 48 | article.slot = "content"; 49 | article.innerHTML = post.body; 50 | }); 51 | } 52 | } 53 | 54 | customElements.define("post-list", PostList); 55 | -------------------------------------------------------------------------------- /31-webcomponent-get-started/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /32-place-item-center/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 80 | 81 | Grid 布局简化居中方式 82 | 83 | 84 |
85 |
😊
86 |
place-items: center
87 |
88 | 89 | 90 | -------------------------------------------------------------------------------- /33-text-image-layout/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 38 | 图片文字环绕 39 | 40 | 41 |
42 |

百度百科 JavaScript

43 |
44 | javascript css html 49 |

50 | JavaScript(简称“JS”) 51 | 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。虽然它是作为开发Web页面的脚本语言而出名,但是它也被用到了很多非浏览器环境中,JavaScript 52 | 基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式和声明式(如函数式编程)风格。JavaScript在1995年由Netscape公司的Brendan 53 | Eich,在网景导航者浏览器上首次设计实现而成。因为Netscape与Sun合作,Netscape管理层希望它外观看起来像Java,因此取名为JavaScript。但实际上它的语法风格与Self及Scheme较为接近。JavaScript的标准是ECMAScript 54 | 。截至 55 | 2012年,所有浏览器都完整的支持ECMAScript5.1,旧版本的浏览器至少支持ECMAScript 56 | 3标准。2015年6月17日,ECMA国际组织发布了ECMAScript的第六版,该版本正式名称为ECMAScript 57 | 2015,但通常被称为ECMAScript 6 或者ES6。 58 |

59 |
60 |
61 | 62 | 63 | -------------------------------------------------------------------------------- /34-drag-drop-api/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 77 | 原生拖拽 78 | 79 | 80 |
81 |
82 |
83 |
84 |
85 |
86 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /35-collision-physics/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 |
12 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /35-collision-physics/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | padding: 0; 4 | margin: 0; 5 | font-family: sans-serif; 6 | } 7 | 8 | main { 9 | width: 100vw; 10 | height: 100vh; 11 | background: hsl(0deg, 0%, 10%); 12 | } 13 | -------------------------------------------------------------------------------- /36-tech-website/assets/images/bilibili.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /36-tech-website/assets/images/email.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /36-tech-website/assets/images/github.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /36-tech-website/assets/images/wechat.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /36-tech-website/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 未来信息 9 | 10 | 11 |
12 |
13 | 14 | 20 |
21 |
22 |
23 |

对未来世界信息的展望

24 |

25 | 现今的信息技术水平极速发展,极大的影响了人们生活的方方面面,手机似乎已经成为了人们的“伴侣”,我们用手机查看地图出行,提醒日常任务,与世界各地的人联络... 26 |

27 | 28 |
29 |
30 | 31 |
32 |
33 |
34 | 40 |
41 |
42 | 43 | 44 | -------------------------------------------------------------------------------- /36-tech-website/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | margin: 0; 4 | padding: 0; 5 | font-family: Helvetica, "PingFang SC", sans-serif; 6 | } 7 | 8 | .container { 9 | width: 100vw; 10 | max-width: 100%; 11 | height: 100vh; 12 | display: grid; 13 | grid-template-rows: 120px 1fr 120px; 14 | } 15 | 16 | header, 17 | main, 18 | footer { 19 | padding: 24px 10vw; 20 | } 21 | 22 | header { 23 | display: grid; 24 | grid-template-columns: max-content 1fr; 25 | align-items: center; 26 | } 27 | 28 | nav { 29 | display: flex; 30 | gap: 88px; 31 | align-items: center; 32 | justify-content: flex-end; 33 | font-size: 18px; 34 | } 35 | 36 | nav a { 37 | text-decoration: none; 38 | color: #000000; 39 | } 40 | 41 | .btn { 42 | width: 120px; 43 | height: 48px; 44 | background: #ffffff; 45 | border: 2px solid #261c35; 46 | border-radius: 0; 47 | box-shadow: -4px 6px #fcb671; 48 | font-weight: 500; 49 | font-size: 18px; 50 | } 51 | 52 | .mainLeft { 53 | display: grid; 54 | width: 36%; 55 | height: 100%; 56 | align-content: center; 57 | row-gap: 36px; 58 | transform: translateY(-10%); 59 | } 60 | 61 | .mainLeft h1 { 62 | font-size: 64px; 63 | text-shadow: -6px 6px #fcb671; 64 | } 65 | 66 | .mainLeft p { 67 | font-weight: 300; 68 | text-align: justify; 69 | } 70 | 71 | .mainLeft button { 72 | background: #fcb671; 73 | box-shadow: -4px 6px #000000; 74 | } 75 | 76 | .mainRight { 77 | position: absolute; 78 | top: 0; 79 | left: 0; 80 | width: 100%; 81 | height: 100%; 82 | z-index: -1; 83 | } 84 | 85 | .mainRight img { 86 | width: 100%; 87 | height: 100%; 88 | object-fit: cover; 89 | object-position: bottom; 90 | } 91 | 92 | footer { 93 | padding-top: 32px; 94 | } 95 | 96 | .socialMedia { 97 | display: flex; 98 | align-items: center; 99 | gap: 64px; 100 | } 101 | -------------------------------------------------------------------------------- /37-container-queries/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | CSS Container Queries 8 | 60 | 61 | 62 |
63 |
64 | 68 |
卡片标题
69 |
70 | 卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容 71 |
72 |
73 |
74 |
75 |
76 | 80 |
卡片标题
81 |
82 | 卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容 83 |
84 |
85 |
86 | 87 | 88 | -------------------------------------------------------------------------------- /38-horizontal-scrolling/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | JS 实现鼠标滚轮横向滚动特效 8 | 38 | 39 | 40 |
41 |
42 |
Page1
43 |
Page2
44 |
Page3
45 |
46 |
47 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /39-web-animations/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Web Animations 8 | 39 | 40 | 41 |
42 |
43 |

Welcome

44 |

JavaScript Web Animations API

45 |
46 |
47 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /40-multi-column-layout/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | CSS Multi-column Layout 8 | 27 | 28 | 29 |
30 |
31 |

32 | 是不是每次面试没通过都会有这样的感觉?作为一名程序员,每次面试的时候都觉得准备不充分,面试资料多的看不完,实战经验也不够,即使自认为准备的很充分了,最后还是栽了,到底是因为自己菜,还是自己菜,还是自己菜呢?要回答这个问题,我们得先知道面试到底在面什么。 33 |

34 |

面试在面什么

35 |

36 | 我们好多小伙伴总觉得面试就跟高考一样,有着严格的评分标准和分数线,谁的分高谁就能进去,但事实上,面试是通过交谈来互相了解对方的一种形式,更多的时候是考验的一个人的沟通能力,如果你能让面试官感觉聊的很投机,那么会有相当大的概率通过面试。 37 | 对于技术方面,不同的公司有不同的侧重点,大厂看重原理和算法,其它公司看中技术的熟悉程度,也就是项目经验。 38 |

39 |

40 | 技术方面的问题是最棘手的,你可能认为面试通过的人,技术一定很牛,这个我以身边进谷歌、Facebook、亚马逊等国外大厂的朋友的经验证明,这是绝对错误的。技术关是最没有技术含量的考验。通常,公司并不知道一个面试者的技术水平,所以才会通过笔试和前几轮的面试进行考察,考察的问题基本都是类似的、可以举一反三的、是能专门进行准备的。简而言之,就是谁下功夫准备面试了,谁通过的概率就大很多,例如一个刷了 41 | leetcode 500 道题 3 遍的,一定比刷了 300 道题 1 遍的通过率高。 42 |

43 |
44 |
45 | 46 | 47 | -------------------------------------------------------------------------------- /41-css-scroll-snap/base.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | font-family: sans-serif; 5 | } 6 | 7 | /* 装饰性样式 */ 8 | section { 9 | display: grid; 10 | place-items: center; 11 | font-size: 2em; 12 | } 13 | 14 | section:nth-child(1) { 15 | background: rgb(229, 213, 255); 16 | } 17 | 18 | section:nth-child(2) { 19 | background: rgb(255, 219, 206); 20 | } 21 | 22 | section:nth-child(3) { 23 | background: rgb(242, 240, 186); 24 | } 25 | 26 | section:nth-child(4) { 27 | background: rgb(196, 244, 175); 28 | } 29 | 30 | h1 { 31 | box-shadow: 0 0 24px hsl(0, 0%, 0%, 0.2); 32 | display: grid; 33 | place-items: center; 34 | font-size: 2em; 35 | background: white; 36 | } 37 | 38 | ul { 39 | width: 50%; 40 | list-style: none; 41 | height: 240px; 42 | overflow: scroll; 43 | } 44 | 45 | li { 46 | padding: 1em; 47 | text-align: center; 48 | font-size: 2em; 49 | } 50 | 51 | li:nth-child(2n) { 52 | background: rgb(229, 213, 255); 53 | } 54 | 55 | li:nth-child(2n + 1) { 56 | background: rgb(255, 219, 206); 57 | } 58 | -------------------------------------------------------------------------------- /41-css-scroll-snap/fullscreen-snap-proximity.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CSS Scroll Snap 近似贴合 9 | 30 | 31 | 32 |
33 |
页面内容1
34 |
页面内容2
35 |
页面内容3
36 |
页面内容4
37 |
38 | 39 | 40 | -------------------------------------------------------------------------------- /41-css-scroll-snap/fullscreen-snap-x.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CSS Scroll Snap 水平贴合 9 | 26 | 27 | 28 |
29 |
页面内容1
30 |
页面内容2
31 |
页面内容3
32 |
页面内容4
33 |
34 | 35 | 36 | -------------------------------------------------------------------------------- /41-css-scroll-snap/fullscreen-snap-y-padding.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CSS Scroll Snap 贴合间距 9 | 28 | 29 | 30 |
31 |

H1标题

32 |
页面内容1
33 |
页面内容2
34 |
页面内容3
35 |
页面内容4
36 |
37 | 38 | 39 | -------------------------------------------------------------------------------- /41-css-scroll-snap/fullscreen-snap-y.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CSS Scroll Snap 垂直 9 | 25 | 26 | 27 |
28 |
页面内容1
29 |
页面内容2
30 |
页面内容3
31 |
页面内容4
32 |
33 | 34 | 35 | -------------------------------------------------------------------------------- /41-css-scroll-snap/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 35 | CSS 滚动贴合 36 | 37 | 38 |
39 | 48 |
49 | 50 | 51 | -------------------------------------------------------------------------------- /41-css-scroll-snap/list-scroll-y.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CSS Scroll Snap Ul 列表贴合 9 | 32 | 33 | 34 |
35 | 45 |
46 | 47 | 48 | -------------------------------------------------------------------------------- /42-clipboard-api/base.css: -------------------------------------------------------------------------------- 1 | main { 2 | width: 100vw; 3 | height: 100vh; 4 | display: grid; 5 | place-items: center; 6 | } 7 | 8 | .codeBlock { 9 | display: flex; 10 | align-items: center; 11 | } 12 | 13 | code { 14 | font-size: 18px; 15 | background: hsl(0deg, 0%, 10%); 16 | color: white; 17 | padding: 8px 12px; 18 | border-radius: 4px; 19 | } 20 | 21 | button { 22 | background: linear-gradient(45deg, hsl(240, 100%, 50%), hsl(290, 100%, 50%)); 23 | border-radius: 4px; 24 | border: none; 25 | padding: 8px 10px; 26 | color: white; 27 | 28 | margin-left: 1em; 29 | cursor: pointer; 30 | } 31 | 32 | .editor { 33 | display: grid; 34 | justify-items: end; 35 | margin-top: 2em; 36 | } 37 | 38 | #paste { 39 | margin-top: 1em; 40 | } 41 | 42 | textarea { 43 | border: 1px solid hsl(0deg, 0%, 90%); 44 | border-radius: 4px; 45 | padding: 8px; 46 | } 47 | -------------------------------------------------------------------------------- /42-clipboard-api/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Clipboard API 9 | 10 | 11 |
12 |
13 |
14 | let a = 1; 15 | 16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | 24 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /43-css-gradient-shadow/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | CSS 渐变阴影 8 | 54 | 55 | 56 |
57 |
58 |
59 | 60 | 61 | -------------------------------------------------------------------------------- /44-css-pointer-events/2021-12-20-19-52-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/44-css-pointer-events/2021-12-20-19-52-11.png -------------------------------------------------------------------------------- /44-css-pointer-events/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | CSS Pointer Events 8 | 49 | 50 | 51 |
52 |
53 | 54 | 55 | 56 |
这是一段描述文案
57 |
58 |
59 | 60 | 61 | -------------------------------------------------------------------------------- /45-URLSearchParams/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | URLSearchParams 8 | 9 | 40 | 41 | 42 |
43 |
44 | 49 |
50 |
51 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /46-css-aspect-ratio/2021-12-20-20-29-28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/46-css-aspect-ratio/2021-12-20-20-29-28.png -------------------------------------------------------------------------------- /46-css-aspect-ratio/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | CSS aspect ratio 8 | 9 | 47 | 48 | 49 |
50 |
51 | 52 |
53 |
54 | 55 | 56 | -------------------------------------------------------------------------------- /48-css-clay-morphism/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | CSS Claymporphism 8 | 9 | 10 | 11 |
12 |
13 |

这是 CSS “泥陶态“ 样式

14 |

Claymorphism

15 | 16 |
17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /48-css-clay-morphism/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | padding: 0; 4 | margin: 0; 5 | font-family: Verdana, "PingFang SC", "Microsoft Yahei", sans-serif; 6 | } 7 | 8 | main { 9 | display: grid; 10 | place-items: center; 11 | width: 100vw; 12 | height: 100vh; 13 | max-width: 100%; 14 | background: #DBEEFF; 15 | } 16 | 17 | p { 18 | font-weight: 500; 19 | font-size: 16px; 20 | color: #384d6c; 21 | } 22 | 23 | .box p:nth-child(2) { 24 | font-weight: 700; 25 | } 26 | 27 | .box { 28 | display: grid; 29 | place-items: center; 30 | gap: 32px; 31 | 32 | padding: 40px 56px; 33 | 34 | /* claymporphism */ 35 | background: #deebff; 36 | box-shadow: 12px 12px 18px rgba(155, 196, 255, 0.42), 37 | inset 10px 10px 11px rgba(250, 252, 255, 0.48), 38 | inset -10px -10px 15px rgba(46, 129, 255, 0.22); 39 | border-radius: 52px; 40 | } 41 | 42 | button { 43 | padding: 8px 32px; 44 | border: none; 45 | color: white; 46 | font-weight: 900; 47 | 48 | /* claymporphism */ 49 | background: #cb5eff; 50 | box-shadow: 2px 3px 13px rgba(197, 78, 253, 0.43), 51 | inset -2px -2px 8px rgba(75, 10, 106, 0.43), 52 | inset 2px 2px 6px rgba(251, 242, 255, 0.47); 53 | border-radius: 22px; 54 | } 55 | -------------------------------------------------------------------------------- /49-html-buit-in-dialog/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | HTML Built-in Dialog Element 8 | 9 | 10 | 11 |
12 | 13 | 20 | 21 |

Register

22 |
23 | 24 | 25 | 26 |
27 | 28 | 29 |
30 |
31 |
32 | 33 |
34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /49-html-buit-in-dialog/index.js: -------------------------------------------------------------------------------- 1 | const dialog = document.getElementById("dialog"); 2 | const showDialogBtn = document.getElementById("showDialog"); 3 | 4 | showDialogBtn.addEventListener("click", () => { 5 | dialog.showModal(); 6 | }); 7 | 8 | dialog.addEventListener("close", () => { 9 | console.log(dialog.returnValue); 10 | }); 11 | -------------------------------------------------------------------------------- /49-html-buit-in-dialog/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | box-sizing: border-box; 3 | padding: 0; 4 | margin: 0; 5 | font-family: Verdana, "PingFang SC", "Microsoft Yahei", sans-serif; 6 | } 7 | 8 | main { 9 | display: grid; 10 | place-items: center; 11 | height: 100vh; 12 | background-color: hsl(0deg, 0%, 98%); 13 | } 14 | 15 | input { 16 | padding: 12px; 17 | font-size: 14px; 18 | outline: none; 19 | } 20 | 21 | /* dialog styles */ 22 | dialog { 23 | border: none; 24 | border-radius: 8px; 25 | padding: 24px 32px; 26 | box-shadow: 0 0 48px hsl(0deg, 0%, 0%, 0.1); 27 | } 28 | 29 | dialog::backdrop { 30 | background-color: hsl(0deg, 0%, 0%, 0.3); 31 | } 32 | 33 | form { 34 | display: grid; 35 | gap: 24px; 36 | justify-content: end; 37 | } 38 | 39 | button { 40 | border: none; 41 | border-radius: 4px; 42 | color: white; 43 | font-weight: bold; 44 | background: linear-gradient(45deg, hsl(218, 100%, 50%), hsl(187, 100%, 51%)); 45 | padding: 12px 24px; 46 | } 47 | -------------------------------------------------------------------------------- /50-css-grid-irregular-layout/images/travel1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/50-css-grid-irregular-layout/images/travel1.png -------------------------------------------------------------------------------- /50-css-grid-irregular-layout/images/travel2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/50-css-grid-irregular-layout/images/travel2.png -------------------------------------------------------------------------------- /50-css-grid-irregular-layout/images/travel3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/50-css-grid-irregular-layout/images/travel3.png -------------------------------------------------------------------------------- /50-css-grid-irregular-layout/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | 14 | CSS Irregular Layout 15 | 16 | 17 |
18 |
19 |

Give yourself a chance to see the world

20 |

21 | Lorem ipsum dolor sit amet consectetur. Eget amet lacus egestas amet 22 | porta sagittis pulvinar magna pretium. Lorem mauris vitae pellentesque 23 | platea velit volutpat magna sem. Elit eu sit facilisi nullam neque 24 | tincidunt sed volutpat metus. Amet sed at sed ante senectus sit 25 | bibendum tincidunt eu. 26 |

27 | travel 28 | travel 29 | travel 30 |

31 | Lorem ipsum dolor sit amet consectetur. Eget amet lacus egestas amet 32 | porta sagittis pulvinar magna pretium. Lorem mauris vitae pellentesque 33 | platea velit volutpat magna sem. Elit eu sit facilisi nullam neque 34 | tincidunt sed volutpat metus. Amet sed at sed ante senectus sit 35 | bibendum tincidunt eu. 36 |

37 |
38 |
39 | 40 | 41 | -------------------------------------------------------------------------------- /50-css-grid-irregular-layout/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | margin: 0; 4 | padding: 0; 5 | font-family: "Raleway", sans-serif; 6 | } 7 | 8 | main { 9 | width: 80vw; 10 | margin: 0 auto; 11 | } 12 | 13 | p { 14 | font-size: 16px; 15 | padding: 24px 0; 16 | line-height: 1.5em; 17 | } 18 | 19 | header { 20 | display: grid; 21 | grid-template-columns: 6fr 1fr 1fr 3fr 5fr 1fr; 22 | grid-template-rows: 40px repeat(6, auto); 23 | } 24 | 25 | h1 { 26 | grid-column: 1 / span 3; 27 | grid-row: 2 / 3; 28 | font-size: 65px; 29 | font-weight: 900; 30 | z-index: 10; 31 | } 32 | 33 | .description1 { 34 | grid-column: 1 / 2; 35 | grid-row: 3 / 4; 36 | } 37 | 38 | .image1 { 39 | grid-column: 1 / 2; 40 | grid-row: 4 / span 2; 41 | } 42 | 43 | .image2 { 44 | grid-column: 3 / span 3; 45 | grid-row: 1 / span 6; 46 | } 47 | 48 | .image3 { 49 | grid-column: 5 / span 2; 50 | grid-row: 5 / span 3; 51 | } 52 | 53 | .description2 { 54 | grid-column: 1 / span 4; 55 | grid-row: 7 / 8; 56 | padding-right: 48px; 57 | } 58 | -------------------------------------------------------------------------------- /51-css-scroll-based-animation/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.port": 5501 3 | } 4 | -------------------------------------------------------------------------------- /51-css-scroll-based-animation/images/image1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/51-css-scroll-based-animation/images/image1.jpg -------------------------------------------------------------------------------- /51-css-scroll-based-animation/images/image2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/51-css-scroll-based-animation/images/image2.jpg -------------------------------------------------------------------------------- /51-css-scroll-based-animation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 21 | 22 | 23 |
24 | Scroll Showcase 25 | View Showcase 26 |
27 | 28 | 29 | -------------------------------------------------------------------------------- /51-css-scroll-based-animation/scroll.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 47 | 48 | 49 |
50 | 51 | 52 |
53 | 54 | 55 | -------------------------------------------------------------------------------- /51-css-scroll-based-animation/view.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 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 | -------------------------------------------------------------------------------- /52-day-night-toggle-button/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CodePen - Day-night-toggle-button 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 | -------------------------------------------------------------------------------- /52-day-night-toggle-button/script.js: -------------------------------------------------------------------------------- 1 | document.body.setAttribute("data-theme", "light"); //按钮状态默认为白天 2 | const BUTTON = document.querySelector(".components"); 3 | const TOGGLE = () => { 4 | const willChangeMode = 5 | document.body.getAttribute("data-theme") === "dark" ? "light" : "dark"; // 判断是否白天黑夜; 6 | document.body.setAttribute("data-theme", willChangeMode); 7 | }; 8 | BUTTON.addEventListener("click", TOGGLE); -------------------------------------------------------------------------------- /53-screenshot-html2-canvas/cafe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/53-screenshot-html2-canvas/cafe.jpg -------------------------------------------------------------------------------- /53-screenshot-html2-canvas/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 38 | 39 | 40 |
41 |
42 |

这是一个标题

43 |

这里是一些文字内容。

44 | 咖啡厅 45 |
46 |
47 | 48 | 49 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /56-animation-button/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Colorful Glowing Button 7 | 70 | 71 | 72 |
73 | 74 |
75 | 76 | 77 | -------------------------------------------------------------------------------- /57-login-form-glass-2/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/57-login-form-glass-2/bg.jpg -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019-2020 Xuqian Zhang 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README-zh_CN.md: -------------------------------------------------------------------------------- 1 | # HTML CSS 特效示例代码库 2 | 3 | 本仓库包含我发布在 [Bilibili, 峰华前端工程师](https://space.bilibili.com/302954484) 视频的配套示例代码。你可以用来寻找灵感,或者直接使用示例中的代码。 4 | 5 | [英文版](./README.md) 6 | 7 | 在线 Demo 演示: [https://zxuqian.github.io/html-css-examples/](https://zxuqian.github.io/html-css-examples/) 8 | 9 | 仓库中的每个文件夹下即对应各个 HTML/CSS 示例的源代码,包括: 10 | 11 | - CSS/SVG 动画 12 | - 阴影/发光/玻璃特效 13 | - 响应式布局 14 | - 打字机特效 15 | - 脸部识别 16 | - 3D 变换 17 | - 原生 Canvas 18 | - 还有更多... 19 | 20 | ## 个人主页 21 | 22 | [博客](https://zxuqian.cn) 23 | 24 | [点击跳转到我的 Bibibili 个人空间首页](https://space.bilibili.com/302954484) 25 | 26 | 或者扫描下方二维码 27 | 28 | Bilibili 峰华前端工程师 29 | 30 | ## 贡献 31 | 32 | 欢迎贡献新特效示例!请按照以下步骤添加: 33 | 34 | 1. Fork 仓库。 35 | 2. 创建一个新分支,以 `feature/` 开头。 36 | 3. 参考现有的示例结构创建示例(注意最新的编号)。 37 | 4. 运行 `yarn run watch` 或 `npm run watch`。它会监控 `src/index.js` 中的更改,并编译到 `/index.js`,这个文件用于生成示例页面的 React 组件。 38 | 5. 更新 `src/index.js`。在 `uis` 数组的顶部添加示例名字和链接,并把 `newItem` 设置为 `true`,移除上一个示例的 `newItem` 属性。 39 | 6. 测试并提交 PR。 40 | 7. 请确保示例的样式符合现代设计审美。 41 | 42 | 注意:你同意所贡献的代码可能会在我的一些视频中进行教学演示。 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HTML CSS Examples 2 | 3 | [中文版](./README-zh_CN.md) 4 | 5 | This repository contains the source code for my videos at [Bilibili, 峰华前端工程师](https://space.bilibili.com/302954484) 6 | 7 | Text in videos and codes are primarily in Chinese, **But you can use this repository without knowing Chinese. Just read the critical part.** 8 | 9 | You can use this repository for inspirations and cheatsheets. 10 | 11 | Online Demo: [https://zxuqian.github.io/html-css-examples/](https://zxuqian.github.io/html-css-examples/) 12 | 13 | Each folder contains the source code of HTML and CSS examples, including: 14 | 15 | - CSS/SVG Animation 16 | - Shadows/Glowing/Glass Effects 17 | - Responsive Layout 18 | - Type-Writer Effect 19 | - Face Recognition 20 | - 3D Transformations 21 | - Native Canvas 22 | - and more... 23 | 24 | ## My Personal Homepage 25 | 26 | [Blog](https://zxuqian.cn) 27 | 28 | [Bilibili](https://space.bilibili.com/302954484) 29 | 30 | Or scan the QR code below: 31 | 32 | Bilibili 峰华前端工程师 33 | 34 | ## Contributing 35 | 36 | Contributing is welcome! Follow these steps to add your examples: 37 | 38 | 1. Fork this repository 39 | 2. Create a new branch, starting with `feature/`. 40 | 3. Structure your project according to the existing ones (note the latest numbering). 41 | 4. Run `yarn run watch` or `npm run watch`. This will monitor changes in `src/index.js` and compile it to `/index.js`, which is used to display React components for the demo page. 42 | 5. Update `src/index.js`. Add your example name and link at the top of the `uis` array, set `newItem` to `true`, and remove the `newItem` property from the previous item. 43 | 6. Test and issue a PR. 44 | 7. Please ensure examples are aethetically pleasing. 45 | 46 | Notice: By contributing, you agree that your code may be used for demonstration in some of my videos. 47 | -------------------------------------------------------------------------------- /babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-react"] 3 | } 4 | -------------------------------------------------------------------------------- /bilibili.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codetoanbug/html-css-examples/2a9fc59f44aeda092cbac07472aaf0f1ead4e1a6/bilibili.jpg -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | HTML and CSS Examples 9 | 10 | 11 |
12 |
13 |

HTML CSS 特效

14 |
    15 |
    16 |
    17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "html-css-examples", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "repository": "https://github.com/zxuqian/html-css-examples", 6 | "author": "Xuqian Zhang ", 7 | "license": "MIT", 8 | "scripts": { 9 | "watch": "babel --watch src/index.js --out-dir ." 10 | }, 11 | "devDependencies": { 12 | "@babel/cli": "^7.12.10", 13 | "@babel/core": "^7.12.10", 14 | "@babel/preset-react": "^7.12.10" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | margin: 0; 4 | font-family: "PingFang SC", "Microsoft Yahei", sans-serif; 5 | } 6 | 7 | * { 8 | box-sizing: border-box; 9 | } 10 | 11 | ul, 12 | li { 13 | padding: 0; 14 | margin: 0; 15 | } 16 | 17 | li { 18 | list-style: none; 19 | } 20 | 21 | main { 22 | display: flex; 23 | align-items: center; 24 | justify-content: center; 25 | flex-wrap: wrap; 26 | min-height: 100vh; 27 | width: 100vw; 28 | padding: 5vmin; 29 | background: #2a1c3a; /* fallback for old browsers */ 30 | background: linear-gradient(135deg, #292929, #000000); 31 | } 32 | 33 | .container { 34 | background-color: rgba(54, 54, 54, 0.4); 35 | border-radius: 8px; 36 | padding: 48px; 37 | } 38 | 39 | .container h1 { 40 | color: #ffffff; 41 | margin-bottom: 36px; 42 | } 43 | 44 | .list { 45 | width: 100%; 46 | display: grid; 47 | grid-template-columns: repeat(4, 1fr); 48 | row-gap: 36px; 49 | column-gap: 24px; 50 | } 51 | 52 | .list li { 53 | background: linear-gradient(135deg, #0061ff, #ff00f2); 54 | border-radius: 6px; 55 | } 56 | 57 | .list li a { 58 | display: block; 59 | color: #ffffff; 60 | text-shadow: 0 0 2px rgba(180, 124, 117, 0.4); 61 | text-decoration: none; 62 | text-align: left; 63 | font-size: 18px; 64 | padding: 18px 24px; 65 | text-align: center; 66 | margin: 2px; 67 | background-color: rgb(24, 24, 24); 68 | border-radius: 6px; 69 | width: 265px; 70 | text-overflow: ellipsis; 71 | overflow: hidden; 72 | white-space: nowrap; 73 | } 74 | 75 | @media screen and (max-width: 1260px) { 76 | .list { 77 | grid-template-columns: repeat(3, 1fr); 78 | } 79 | } 80 | 81 | @media screen and (max-width: 976px) { 82 | .list { 83 | grid-template-columns: repeat(2, 1fr); 84 | } 85 | } 86 | 87 | @media screen and (max-width: 670px) { 88 | .list { 89 | grid-template-columns: repeat(1, 1fr); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /yarn-error.log: -------------------------------------------------------------------------------- 1 | Arguments: 2 | /Users/zxuqian/.nvm/versions/node/v14.15.0/bin/node /usr/local/Cellar/yarn/1.22.10/libexec/bin/yarn.js add --dev @babel-cli babel-preset-react-app 3 | 4 | PATH: 5 | /Users/zxuqian/.deno/bin:/Users/zxuqian/.nvm/versions/node/v14.15.0/bin:/Users/zxuqian/.cargo/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin:/usr/local/share/dotnet:/Library/Apple/usr/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Applications/Wireshark.app/Contents/MacOS:/Users/zxuqian/.deno/bin:/Users/zxuqian/.nvm/versions/node/v14.15.0/bin:/Users/zxuqian/.cargo/bin 6 | 7 | Yarn version: 8 | 1.22.10 9 | 10 | Node version: 11 | 14.15.0 12 | 13 | Platform: 14 | darwin x64 15 | 16 | Trace: 17 | Error: https://registry.yarnpkg.com/@babel-cli: Request "https://registry.yarnpkg.com/@babel-cli" returned a 405 18 | at Request.params.callback [as _callback] (/usr/local/Cellar/yarn/1.22.10/libexec/lib/cli.js:66997:18) 19 | at Request.self.callback (/usr/local/Cellar/yarn/1.22.10/libexec/lib/cli.js:140749:22) 20 | at Request.emit (events.js:315:20) 21 | at Request. (/usr/local/Cellar/yarn/1.22.10/libexec/lib/cli.js:141721:10) 22 | at Request.emit (events.js:315:20) 23 | at IncomingMessage. (/usr/local/Cellar/yarn/1.22.10/libexec/lib/cli.js:141643:12) 24 | at Object.onceWrapper (events.js:421:28) 25 | at IncomingMessage.emit (events.js:327:22) 26 | at endReadableNT (_stream_readable.js:1327:12) 27 | at processTicksAndRejections (internal/process/task_queues.js:80:21) 28 | 29 | npm manifest: 30 | { 31 | "name": "html-css-examples", 32 | "version": "1.0.0", 33 | "main": "index.js", 34 | "repository": "https://github.com/zxuqian/html-css-examples", 35 | "author": "Xuqian Zhang ", 36 | "license": "MIT" 37 | } 38 | 39 | yarn manifest: 40 | No manifest 41 | 42 | Lockfile: 43 | No lockfile 44 | --------------------------------------------------------------------------------