整合營銷服務商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          輕松搞定一鍵切換主題色?分享 1 段優(yōu)質(zhì) CSS 代碼片段!

          內(nèi)容首發(fā)于工粽號:程序員大澈,每日分享一段優(yōu)質(zhì)代碼片段,歡迎關注和投稿!

          大家好,我是大澈!

          本文約 800+ 字,整篇閱讀約需 1 分鐘。

          今天分享一段優(yōu)質(zhì) CSS 代碼片段,輕松實現(xiàn)一鍵切換主題顏色,在任何項目中都可用。

          老規(guī)矩,先閱讀代碼片段并思考,再看代碼解析再思考,最后評論區(qū)留下你的見解!

          [data-theme='default'] {
            --font-primary: #fff;
            --background-main: #0678be;
          }
          
          [data-theme='black'] {
            --font-primary: #fff;
            --background-main: #393939;
          }
          
          <html lang="en" data-theme="default"></html>
          
          body {
            color: var(--font-primary);
            background-color: var(--background-main);
          }


          分享原因

          這段代碼可以輕松實現(xiàn)網(wǎng)頁主題的切換,且在各種項目中通用。

          先定義不同主題的 CSS 變量,再通過 JavaScript 動態(tài)更改 data-theme 屬性,從而實現(xiàn)頁面樣式的動態(tài)變化。

          這種方法不僅簡化了主題管理,還提高了代碼的可讀性和維護性,是我們項目中一般且常用的實現(xiàn)方式之一。

          代碼解析

          1. 定義主題變量

          CSS變量:聲明自定義CSS屬性,它包含的值可以在整個文檔中重復使用。屬性名需要以兩個減號(--)開始,屬性值則可以是任何有效的 CSS 值。

          CSS屬性選擇器:匹配具有特定屬性或?qū)傩灾档脑?。例如[data-theme='black'],將選擇所有 data-theme 屬性值為 'black' 的元素。

          使用 [data-theme='default'] 和 [data-theme='black'] 選擇器,根據(jù) data-theme 屬性的值定義不同的主題樣式。

          定義了兩個 CSS 變量 --font-primary 和 --background-main,分別表示字體顏色和背景顏色。

          2. 指定默認主題

          在 <html> 元素上添加 data-theme="default",指定默認主題為 default 。

          后面用 js 動態(tài)切換 data-theme 屬性值,然后 CSS 屬性選擇器將自動選擇對應的 CSS 變量。

          3. 應用 CSS 變量

          Var函數(shù):用于使用 CSS 變量。第一個參數(shù)為 CSS 變量名稱,第二個可選參數(shù)作為默認值。

          使用 var(--font-primary) 和 var(--background-main) 來引用之前定義的 CSS 變量。

          這里設置 body 元素的 color 和 background-color 屬性,分別引用 --font-primary 和 --background-main 變量,在項目中按需設置對應的元素即可。

          子頁面把整個頁面做絕對定位,覆蓋整個屏幕,子父頁面將 router-view 用 transition 套起來,并加上過渡動畫就可以啦。

          代碼:

          <!DOCTYPE html>
          <html lang="en">
          <head>
           <meta charset="UTF-8">
           <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
           <title>Document</title>
           <style>
           * { padding: 0; margin: 0; }
           html, body, #app { width: 100%; height: 100%; }
           .one { height: 100%; background-color: yellow; }
           .two { background-color: tomato; position: fixed; top: 0; bottom: 0; left: 0; right: 0; }
           .three { background-color: #ffe69f; position: fixed; top: 0; bottom: 0; left: 0; right: 0; }
           .v-enter-active, .v-leave-active { transition: all 0.3s; }
           .v-enter, .v-leave-to { transform: translateX(100%); }
           </style>
          </head>
          <body>
           <div id="app">
           <div class="one">
           <p>
           <router-link to="/foo">下一層</router-link>
           </p>
           <h1>第一層</h1>
           </div>
           <transition>
           <router-view></router-view>
           </transition>
           </div>
           
           <script src="https://unpkg.com/vue/dist/vue.js"></script>
           <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
           <script>
           const Foo = {
           template: `
           <div class="whole-page two">
           <router-link to="/foo/bar">下一層</router-link>
           <router-link to="/">返回</router-link>
           <h1>第二層</h1>
           <transition>
           <router-view></router-view>
           </transition>
           </div>
           `
           }
           const Bar = {
           template: `
           <div class="whole-page three">
           <router-link to="/foo">返回</router-link>
           <h1>第三層</h1>
           <transition>
           <router-view></router-view>
           </transition>
           </div>
           `
           }
           const routes = [ 
           { path: '/foo', component: Foo, children: [ { path: 'bar', component: Bar } ] }
           ]
           const router = new VueRouter({ routes })
           const app = new Vue({ router }).$mount('#app')
           </script>
          </body>
          </html>
          

          效果:



          有一個問題需要注意一下,

          我們知道,在應用transform屬性的時候,fixed定位會變成absolute。

          這里,頁面轉(zhuǎn)換的時候,就變成了相對translation定位。所以如果子頁面中有絕對定位的話,移動的過程中頁面會變形。

          簡單舉個栗子,

          <!DOCTYPE html>
          <html lang="en">
          <head>
           <meta charset="UTF-8">
           <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
           <title>Document</title>
           <style>
          * { padding: 0; margin: 0; }
          html, body, #app { width: 100%; height: 100%; }
          #app { padding-top: 50px; }
          .one { height: 100%; background-color: yellow;}
          .two { background-color: tomato; position: fixed; top: 100px; bottom: 0; left: 0; right: 0; }.v-enter-active, .v-leave-active { transition: all 0.3s; }
          .v-enter, .v-leave-to { transform: translateX(100%); }
          header { height: 50px; background-color: #000; width: 100%; position: fixed; top: 0; color: #fff; line-height: 50px; text-align: center; }
          .two header { top: 50px; background-color: #666; }
           </style>
          </head>
          <body>
           <div id="app">
           <header>我是一個標題</header>
           <div class="one">
           <p>
           <router-link to="/foo">下一層</router-link>
           </p>
           <h1>第一層</h1>
           <transition>
           <router-view></router-view>
           </transition>
           </div>
           </div>
           
           <script src="https://unpkg.com/vue/dist/vue.js"></script>
           <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
           <script>
           const Foo = {
           template: `
           <div class="whole-page two">
           <router-link to="/">返回</router-link>
           <header>我也是一個標題</header>
           <h1>第二層</h1>
           <transition>
           <router-view></router-view>
           </transition>
           </div>
           `
           }
           const routes = [ 
           { path: '/foo', component: Foo }
           ]
           const router = new VueRouter({ routes })
           const app = new Vue({ router }).$mount('#app')
           </script>
          </body>
          </html>
          

          看下效果:



          OKOK,反正就是這種bug嘛。

          解決辦法就是,就是,盡量讓頁面fixed定位都是0 0 0 0,然后偏移用padding實現(xiàn)。

          大概吧……反正我是這么解決的……

          比如上面那個可以把CSS改成這樣解決問題。

          * { padding: 0; margin: 0; }
          html, body, #app { width: 100%; height: 100%; }
          #app { padding-top: 50px; }
          .one { height: 100%; background-color: yellow;}
          .two { background-color: tomato; position: fixed; top: 0; padding-top: 100px; bottom: 0; left: 0; right: 0; }.v-enter-active, .v-leave-active { transition: all 0.3s; }
          .v-enter, .v-leave-to { transform: translateX(100%); }
          header { height: 50px; background-color: #000; width: 100%; position: fixed; top: 0; color: #fff; line-height: 50px; text-align: center; z-index: 100; }
          .two header { top: 50px; background-color: #666; }
          

          嗯嗯 還有一個問題,還有個滑動穿透的問題,(真開心! 這么多問題!

          我再舉個栗子,

          <!DOCTYPE html>
          <html lang="en">
          <head>
           <meta charset="UTF-8">
           <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
           <title>Document</title>
           <style>
          * { padding: 0; margin: 0; }
          html, body, #app { width: 100%; height: 100%; }
          .one { min-height: 100%; background-color: yellow;}
          .two { background-color: tomato; position: fixed; top: 0; bottom: 0; left: 0; right: 0; }
          .three { background-color: #ffe69f; position: fixed; top: 50px; bottom: 0; left: 0; right: 0; }
          .v-enter-active, .v-leave-active { transition: all 0.3s; }
          .v-enter, .v-leave-to { transform: translateX(100%); }
           </style>
          </head>
          <body>
           <div id="app">
           <div class="one">
           <p>
           <router-link to="/foo">下一層</router-link>
           </p>
           <h1>第一層</h1><h1>第一層</h1><h1>第一層</h1><h1>第一層</h1><h1>第一層</h1>
           <h1>第一層</h1><h1>第一層</h1><h1>第一層</h1><h1>第一層</h1><h1>第一層</h1>
           <h1>第一層</h1><h1>第一層</h1><h1>第一層</h1><h1>第一層</h1><h1>第一層</h1>
           <transition>
           <router-view></router-view>
           </transition>
           </div>
           </div>
           
           <script src="https://unpkg.com/vue/dist/vue.js"></script>
           <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
           <script>
           const Foo = {
           template: `
           <div class="whole-page two">
           <router-link to="/">返回</router-link>
           <h1>第二層</h1>
           <transition>
           <router-view></router-view>
           </transition>
           </div>
           `
           }
           const routes = [ 
           { path: '/foo', component: Foo }
           ]
           const router = new VueRouter({ routes })
           const app = new Vue({ router }).$mount('#app')
           </script>
          </body>
          </html>
          

          看效果,第二頁的高度明明就是視窗的高度,但是它有一個滾動條,實際上那是第一個頁面的滾動條。

          網(wǎng)上找了好多方法,一一試了,全部不生效。(當然很有可能是我的方法不對。



          最后沒辦法只有找最笨的方法啦,就是通過 v-if 把父頁面不顯示就好了。

          當然不能直接不顯示,因為動畫還沒結束父元素就空白了呀!setTimeout 就好了……

          具體代碼就不寫了,這個應該很容易理解。

          最后

          以下是總結出來最全前端框架視頻,包含: javascript/vue/react/angualrde/express/koa/webpack 等學習資料。

          【領取方式】

          關注頭條 前端全棧架構丶第一時間獲取最新前端資訊學習

          手機用戶可私信關鍵詞 【前端】即可獲取全棧工程師路線和學習資料!

          HTML+CSS3+JS創(chuàng)意設計——打造炫酷滑動登錄頁面

          **引言:探索交互之美**

          在Web開發(fā)的世界里,優(yōu)秀的用戶體驗往往始于一個精心設計的登錄界面。HTML5、CSS3以及JavaScript的結合讓我們能夠創(chuàng)造出極具創(chuàng)意與個性化的滑動登錄頁面,讓用戶在首次接觸應用時就能留下深刻印象。本篇文章將詳細介紹如何利用基礎的HTML+CSS3+JS技術,從零開始打造一款令人眼前一亮的滑動登錄頁面,并通過詳細的代碼實例解析,帶領您領略前端交互設計的魅力。

          ---

          ### **一、搭建基礎HTML結構**

          **標題:** 構建骨骼——登錄表單的基礎布局

          首先,我們需要構建一個簡潔明了的HTML結構,包括用戶名輸入框、密碼輸入框、登錄按鈕以及可選的注冊鏈接。為了實現(xiàn)滑動效果,我們還將引入一個容器元素來包裹整個登錄區(qū)域。

          ```html

          <!DOCTYPE html>

          <html lang="zh">

          <head>

          <meta charset="UTF-8">

          <title>滑動登錄頁面</title>

          <!-- 引入外部CSS和JS文件 -->

          <link rel="stylesheet" href="styles.css">

          <script src="scripts.js" defer></script>

          </head>

          <body>

          <div id="login-slider">

          <form action="#" class="login-form">

          <input type="text" placeholder="用戶名" required>

          <input type="password" placeholder="密碼" required>

          <button type="submit">登錄</button>

          <a href="#">忘記密碼?</a>

          <a href="#">立即注冊</a>

          </form>

          </div>

          </body>

          </html>

          ```

          ---

          ### **二、CSS3魔法——樣式與動畫**

          **標題:** 點綴肌膚——賦予登錄表單靈動之感

          接下來,我們將使用CSS3為登錄表單添加樣式,并利用`@keyframes`規(guī)則定義滑動動畫效果。同時,我們還需要保證登錄表單在不同設備上具有良好的響應式布局。

          ```css

          /* styles.css */

          body {

          margin: 0;

          background-color: #f0f0f0;

          }

          #login-slider {

          position: absolute;

          top: 50%;

          left: 50%;

          transform: translate(-50%, -50%);

          width: 300px;

          height: auto;

          background-color: white;

          box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);

          overflow: hidden;

          }

          .login-form {

          display: flex;

          flex-direction: column;

          padding: 20px;

          animation: slideIn 1s ease-in-out forwards;

          }

          /* 定義滑動動畫 */

          @keyframes slideIn {

          0% {

          transform: translateY(100%);

          }

          100% {

          transform: translateY(0);

          }

          }

          /* 登錄表單元素樣式 */

          input[type="text"],

          input[type="password"] {

          margin-bottom: 10px;

          padding: 10px;

          border: none;

          border-radius: 5px;

          }

          button {

          cursor: pointer;

          background-color: #007bff;

          color: white;

          padding: 10px 20px;

          border: none;

          border-radius: 5px;

          text-transform: uppercase;

          font-weight: bold;

          }

          /* 響應式布局 */

          @media screen and (max-width: 768px) {

          #login-slider {

          width: 90%;

          }

          }

          ```

          ---

          ### **三、JavaScript增強交互**

          **標題:** 賦予靈魂——用JavaScript實現(xiàn)滑動觸發(fā)與驗證邏輯

          現(xiàn)在我們要借助JavaScript來控制登錄表單的滑動行為,例如當用戶點擊某個鏈接或者頁面加載完成后自動觸發(fā)滑動動畫。同時,可以增加一些簡單的表單驗證功能。

          ```javascript

          // scripts.js

          document.addEventListener('DOMContentLoaded', () => {

          // 頁面加載完成后執(zhí)行滑動動畫

          const loginSlider = document.getElementById('login-slider');

          loginSlider.classList.add('slide-active');

          // 表單提交事件處理,此處僅為示例,實際場景下需加入真實驗證邏輯

          const form = document.querySelector('.login-form');

          form.addEventListener('submit', (event) => {

          event.preventDefault(); // 阻止默認提交行為

          const username = form.querySelector('input[type="text"]').value;

          const password = form.querySelector('input[type="password"]').value;

          // 實現(xiàn)簡單驗證邏輯,如為空檢查

          if (!username || !password) {

          alert('用戶名和密碼不能為空!');

          } else {

          // 這里可以替換為真實的登錄請求邏輯

          console.log('正在登錄...', username, password);

          }

          });

          });

          ```

          ---

          ### **四、創(chuàng)意無限——拓展與優(yōu)化**

          **標題:** 持續(xù)創(chuàng)新——更多滑動登錄頁面的設計思路與實踐

          除了上述基本的滑動登錄形式,還可以進一步豐富設計,比如:

          - 添加進度條指示登錄滑動完成度;

          - 使用CSS變量實現(xiàn)自定義主題切換;

          - 結合SVG圖標增加視覺吸引力;

          - 通過IntersectionObserver API實現(xiàn)視口可見時自動滑動;

          - 配合AJAX技術實現(xiàn)實時驗證和無刷新登錄。

          ---

          **結語:**

          通過這次對HTML+CSS3+JS組合技術的探索,我們不僅成功地制作出了一個富有創(chuàng)意的滑動登錄頁面,還展現(xiàn)了前端技術在交互設計中的無限可能性。學習并靈活運用這些基礎知識,可以讓您的Web應用更加生動有趣,從而更好地吸引和留住用戶。持續(xù)關注前端技術的最新發(fā)展,不斷挑戰(zhàn)自我,用代碼書寫更美好的Web世界。


          主站蜘蛛池模板: 乱码精品一区二区三区| 国产精品无码一区二区三区免费| 亚洲国产一区二区视频网站| 亚洲宅男精品一区在线观看| 日韩精品一区二区三区大桥未久| 亚洲一区二区三区乱码A| 一区二区三区在线播放视频| 亚洲色精品VR一区区三区| 日本无卡码免费一区二区三区| 视频一区在线播放| 国产伦理一区二区| 亚洲午夜电影一区二区三区 | 日韩免费一区二区三区在线| 国内精品一区二区三区最新| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 亚洲片国产一区一级在线观看| 不卡无码人妻一区三区音频| 少妇激情一区二区三区视频| 亚洲AV香蕉一区区二区三区| 无码精品久久一区二区三区 | 精品爆乳一区二区三区无码av| 午夜AV内射一区二区三区红桃视| 国产中文字幕一区| 国产一区二区免费| 午夜视频在线观看一区二区| 日韩电影一区二区| 亚洲国产成人久久一区久久| 亚洲视频一区二区三区| 久久久精品一区二区三区| 亚洲AⅤ视频一区二区三区| 日韩精品中文字幕无码一区| 久久精品一区二区影院| 日本一区二区三区精品国产| 色婷婷亚洲一区二区三区| 日本精品视频一区二区| 中文日韩字幕一区在线观看| 成人免费av一区二区三区| 人妻无码一区二区三区四区| 日本免费一区尤物| 国产一区中文字幕| 日本精品一区二区三区视频|