整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

轻松搞定一键切换主题色?分享 1 段优质 CSS 代码片段!

内容首发于工粽号:程序员大澈,每日分享一段优质代码片段,欢迎关注和投稿!

大家好,我是大澈!

本文约 800+ 字,整篇阅读约需 1 分钟。

今天分享一段优质 CSS 代码片段,轻松实现一键切换主题颜色,在任何项目中都可用。

老规矩,先阅读代码片段并思考,再看代码解析再思考,最后评论区留下你的见解!

[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);
}


分享原因

这段代码可以轻松实现网页主题的切换,且在各种项目中通用。

先定义不同主题的 CSS 变量,再通过 JavaScript 动态更改 data-theme 属性,从而实现页面样式的动态变化。

这种方法不仅简化了主题管理,还提高了代码的可读性和维护性,是我们项目中一般且常用的实现方式之一。

代码解析

1. 定义主题变量

CSS变量:声明自定义CSS属性,它包含的值可以在整个文档中重复使用。属性名需要以两个减号(--)开始,属性值则可以是任何有效的 CSS 值。

CSS属性选择器:匹配具有特定属性或属性值的元素。例如[data-theme='black'],将选择所有 data-theme 属性值为 'black' 的元素。

使用 [data-theme='default'] 和 [data-theme='black'] 选择器,根据 data-theme 属性的值定义不同的主题样式。

定义了两个 CSS 变量 --font-primary 和 --background-main,分别表示字体颜色和背景颜色。

2. 指定默认主题

在 <html> 元素上添加 data-theme="default",指定默认主题为 default 。

后面用 js 动态切换 data-theme 属性值,然后 CSS 属性选择器将自动选择对应的 CSS 变量。

3. 应用 CSS 变量

Var函数:用于使用 CSS 变量。第一个参数为 CSS 变量名称,第二个可选参数作为默认值。

使用 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。

这里,页面转换的时候,就变成了相对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实现。

大概吧……反正我是这么解决的……

比如上面那个可以把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>

看效果,第二页的高度明明就是视窗的高度,但是它有一个滚动条,实际上那是第一个页面的滚动条。

网上找了好多方法,一一试了,全部不生效。(当然很有可能是我的方法不对。



最后没办法只有找最笨的方法啦,就是通过 v-if 把父页面不显示就好了。

当然不能直接不显示,因为动画还没结束父元素就空白了呀!setTimeout 就好了……

具体代码就不写了,这个应该很容易理解。

最后

以下是总结出来最全前端框架视频,包含: javascript/vue/react/angualrde/express/koa/webpack 等学习资料。

【领取方式】

关注头条 前端全栈架构丶第一时间获取最新前端资讯学习

手机用户可私信关键词 【前端】即可获取全栈工程师路线和学习资料!

HTML+CSS3+JS创意设计——打造炫酷滑动登录页面

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

在Web开发的世界里,优秀的用户体验往往始于一个精心设计的登录界面。HTML5、CSS3以及JavaScript的结合让我们能够创造出极具创意与个性化的滑动登录页面,让用户在首次接触应用时就能留下深刻印象。本篇文章将详细介绍如何利用基础的HTML+CSS3+JS技术,从零开始打造一款令人眼前一亮的滑动登录页面,并通过详细的代码实例解析,带领您领略前端交互设计的魅力。

---

### **一、搭建基础HTML结构**

**标题:** 构建骨骼——登录表单的基础布局

首先,我们需要构建一个简洁明了的HTML结构,包括用户名输入框、密码输入框、登录按钮以及可选的注册链接。为了实现滑动效果,我们还将引入一个容器元素来包裹整个登录区域。

```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`规则定义滑动动画效果。同时,我们还需要保证登录表单在不同设备上具有良好的响应式布局。

```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实现滑动触发与验证逻辑

现在我们要借助JavaScript来控制登录表单的滑动行为,例如当用户点击某个链接或者页面加载完成后自动触发滑动动画。同时,可以增加一些简单的表单验证功能。

```javascript

// scripts.js

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

// 页面加载完成后执行滑动动画

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;

// 实现简单验证逻辑,如为空检查

if (!username || !password) {

alert('用户名和密码不能为空!');

} else {

// 这里可以替换为真实的登录请求逻辑

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

}

});

});

```

---

### **四、创意无限——拓展与优化**

**标题:** 持续创新——更多滑动登录页面的设计思路与实践

除了上述基本的滑动登录形式,还可以进一步丰富设计,比如:

- 添加进度条指示登录滑动完成度;

- 使用CSS变量实现自定义主题切换;

- 结合SVG图标增加视觉吸引力;

- 通过IntersectionObserver API实现视口可见时自动滑动;

- 配合AJAX技术实现实时验证和无刷新登录。

---

**结语:**

通过这次对HTML+CSS3+JS组合技术的探索,我们不仅成功地制作出了一个富有创意的滑动登录页面,还展现了前端技术在交互设计中的无限可能性。学习并灵活运用这些基础知识,可以让您的Web应用更加生动有趣,从而更好地吸引和留住用户。持续关注前端技术的最新发展,不断挑战自我,用代码书写更美好的Web世界。