如何使用 CSS 和 JavaScript 制作可变主题

Posted

技术标签:

【中文标题】如何使用 CSS 和 JavaScript 制作可变主题【英文标题】:How to make changeable themes using CSS and JavaScript 【发布时间】:2012-02-06 10:35:54 【问题描述】:

我对 CSS 和 javascript 还很陌生,我想知道您是否可以编写一个脚本来更改网站使用的样式表。

说:你有一个绿色主题,一切都是绿色的。您会怎么做才能让用户通过按一下按钮将其更改为红色?

有人知道怎么做吗?

【问题讨论】:

【参考方案1】:

你可以给链接标签设置一个Id,并在运行时切换css。

html

<link type="text/css" rel="stylesheet" media="all" href="../green.css" id="theme_css" />

JS

document.getElementById('buttonID').onclick = function ()  
    document.getElementById('theme_css').href = '../red.css';
;

快速演示:

    $( "#datepicker" ).datepicker();

$('button').button().on('click', function () 
  let linkHref = 'https://code.jquery.com/ui/1.11.4/themes/THEME/jquery-ui.css';

if ($('#swapTheme').prop('href').indexOf('pepper-grinder') >= 0) 
    $('#swapTheme').prop('href', linkHref.replace('THEME', 'black-tie'));
   else 
    $('#swapTheme').prop('href', linkHref.replace('THEME', 'pepper-grinder'));
  
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU="
              crossorigin="anonymous"></script>
<link href="https://code.jquery.com/ui/1.11.4/themes/pepper-grinder/jquery-ui.css" id="swapTheme" rel="stylesheet">
<div id="datepicker"></div>
<button style="padding: 5px 15px;"> Switch Theme </button>

【讨论】:

改变linkhref属性不会卸载已经加载的css规则,对吗? @a55 据我所知,它将卸载/删除规则并加载新规则。您可以在开发者工具中查看计算得到的 CSS 规则。【参考方案2】:

您可以使用CSS Variables(也称为自定义属性)进行此类更改,因为它们是supported by all modern browsers。


因此,假设您有一个绿色/白色主题,其中绿色是原色,白色是其补充色。该网站可能如下所示:

body 
  font-family: "Segoe UI", "Serif", "Verdana", "Arial";


.container 
  display: grid;
  grid-template-columns: 120px 1fr;
  grid-template-rows: 50px 1fr 30px;
  grid-gap: 5px;


.header 
  grid-row: 1;
  grid-column: 1 / 3;
  background-color: #ddd;


.nav 
  grid-column: 1;
  grid-row: 2;
  border-right: 1px solid green;


.content 
  grid-column: 2;
  grid-row: 2;
  padding: 10px;


.footer 
  grid-row: 3;
  grid-column: 1 / 3;
  text-align: center;



/* Child items. */

.header-logo 
  float: left;
  width: 100px;
  background-color: green;
  height: 50px;
  color: white;
  font-size: 30px;
  padding: 3px 5px;
  box-sizing: border-box;


.nav-links 
  list-style: none;
  margin: 5px 0 0 0;
  padding: 0;


.nav-links--link 
  color: green;
  background-color: white;
  width: 100%;
  height: 30px;
  margin: 0 0 5px 0;
  padding: 4px 5px;
  box-sizing: border-box;
  cursor: pointer;


.nav-links--link.active,
.nav-links--link:hover 
  background-color: green;
  color: white;


.footer-note 
  color: green;
  background-color: white;
  padding: 3px 0;
  display: block;
<div class="container">
  <div class="header">
    <div class="header-logo">
      LOGO
    </div>
  </div>

  <div class="nav">
    <ul class="nav-links">
      <li class="nav-links--link active">
        Home
      </li>
      <li class="nav-links--link">
        About
      </li>
      <li class="nav-links--link">
        Contact Us
      </li>
    </ul>
  </div>

  <div class="content">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta, ea.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Facilis id tenetur repudiandae deserunt, ipsam quisquam dicta tempora. Temporibus, vel, veritatis.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dignissimos odio id repellat quam, assumenda magnam! Beatae perferendis error exercitationem molestias explicabo earum ipsam maiores ullam natus dolorum, dolorem itaque reiciendis
      nihil placeat incidunt aperiam tempora, commodi eveniet. Minima iusto porro iste quae dignissimos neque dolor adipisci non, soluta nisi!</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates, dolorem blanditiis exercitationem excepturi, impedit iure.</p>
  </div>

  <div class="footer">
    <span class="footer-note">
          Lorem ipsum dolor sit amet.
        </span>
  </div>
</div>

因此,迁移到 CSS 变量的第一步是将主题颜色重构到变量--primary-color--secondary-color 中。以下是更改后样式表的外观。

您可以首先在:root 元素样式声明中设置默认主题颜色:

:root 
    --primary-color: green;
    --secondary-color: white;

然后,您可以通过调用主颜色变量:var(--primary-color) 来替换样式表中所有硬编码“绿色”的实例。因此,您的徽标样式可能如下所示:

.header-logo 
  ...
  background-color: var(--primary-color);
  color: var(--secondary-color);
  ...

:root 
  --primary-color: green;
  --secondary-color: white;


body 
  font-family: "Segoe UI", "Serif", "Verdana", "Arial";


.container 
  display: grid;
  grid-template-columns: 120px 1fr;
  grid-template-rows: 50px 1fr 30px;
  grid-gap: 5px;


.header 
  grid-row: 1;
  grid-column: 1 / 3;
  background-color: #ddd;


.nav 
  grid-column: 1;
  grid-row: 2;
  border-right: 1px solid var(--primary-color);


.content 
  grid-column: 2;
  grid-row: 2;
  padding: 10px;


.footer 
  grid-row: 3;
  grid-column: 1 / 3;
  text-align: center;



/* Child items. */

.header-logo 
  float: left;
  width: 100px;
  background-color: var(--primary-color);
  height: 50px;
  color: var(--secondary-color);
  font-size: 30px;
  padding: 3px 5px;
  box-sizing: border-box;


.nav-links 
  list-style: none;
  margin: 5px 0 0 0;
  padding: 0;


.nav-links--link 
  color: var(--primary-color);
  background-color: var(--secondary-color);
  width: 100%;
  height: 30px;
  margin: 0 0 5px 0;
  padding: 4px 5px;
  box-sizing: border-box;
  cursor: pointer;


.nav-links--link.active,
.nav-links--link:hover 
  background-color: var(--primary-color);
  color: var(--secondary-color);


.footer-note 
  color: var(--primary-color);
  background-color: var(--secondary-color);
  padding: 3px 0;
  display: block;
<div class="container">
  <div class="header">
    <div class="header-logo">
      LOGO
    </div>
  </div>

  <div class="nav">
    <ul class="nav-links">
      <li class="nav-links--link active">
        Home
      </li>
      <li class="nav-links--link">
        About
      </li>
      <li class="nav-links--link">
        Contact Us
      </li>
    </ul>
  </div>

  <div class="content">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta, ea.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Facilis id tenetur repudiandae deserunt, ipsam quisquam dicta tempora. Temporibus, vel, veritatis.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dignissimos odio id repellat quam, assumenda magnam! Beatae perferendis error exercitationem molestias explicabo earum ipsam maiores ullam natus dolorum, dolorem itaque reiciendis
      nihil placeat incidunt aperiam tempora, commodi eveniet. Minima iusto porro iste quae dignissimos neque dolor adipisci non, soluta nisi!</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates, dolorem blanditiis exercitationem excepturi, impedit iure.</p>
  </div>

  <div class="footer">
    <span class="footer-note">
          Lorem ipsum dolor sit amet.
        </span>
  </div>
</div>

现在,如果您打算将颜色从“绿色”更改为“红色”,只需将--primary-color 的值更改为“红色”即可。而且,您可以使用 Javascript 来做到这一点!

使用纯 JS,您可以使用以下方法将颜色设置为红色:

document.body.style.setProperty("--primary-color", "red");

或者,你可以使用 jQuery:

$(document.body).css("--primary-color", "red");

$(document.body).css("--primary-color", "red");
:root 
  --primary-color: green;
  --secondary-color: white;


body 
  font-family: "Segoe UI", "Serif", "Verdana", "Arial";


.container 
  display: grid;
  grid-template-columns: 120px 1fr;
  grid-template-rows: 50px 1fr 30px;
  grid-gap: 5px;


.header 
  grid-row: 1;
  grid-column: 1 / 3;
  background-color: #ddd;


.nav 
  grid-column: 1;
  grid-row: 2;
  border-right: 1px solid var(--primary-color);


.content 
  grid-column: 2;
  grid-row: 2;
  padding: 10px;


.footer 
  grid-row: 3;
  grid-column: 1 / 3;
  text-align: center;



/* Child items. */

.header-logo 
  float: left;
  width: 100px;
  background-color: var(--primary-color);
  height: 50px;
  color: var(--secondary-color);
  font-size: 30px;
  padding: 3px 5px;
  box-sizing: border-box;


.nav-links 
  list-style: none;
  margin: 5px 0 0 0;
  padding: 0;


.nav-links--link 
  color: var(--primary-color);
  background-color: var(--secondary-color);
  width: 100%;
  height: 30px;
  margin: 0 0 5px 0;
  padding: 4px 5px;
  box-sizing: border-box;
  cursor: pointer;


.nav-links--link.active,
.nav-links--link:hover 
  background-color: var(--primary-color);
  color: var(--secondary-color);


.footer-note 
  color: var(--primary-color);
  background-color: var(--secondary-color);
  padding: 3px 0;
  display: block;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
  <div class="header">
    <div class="header-logo">
      LOGO
    </div>
  </div>

  <div class="nav">
    <ul class="nav-links">
      <li class="nav-links--link active">
        Home
      </li>
      <li class="nav-links--link">
        About
      </li>
      <li class="nav-links--link">
        Contact Us
      </li>
    </ul>
  </div>

  <div class="content">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta, ea.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Facilis id tenetur repudiandae deserunt, ipsam quisquam dicta tempora. Temporibus, vel, veritatis.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dignissimos odio id repellat quam, assumenda magnam! Beatae perferendis error exercitationem molestias explicabo earum ipsam maiores ullam natus dolorum, dolorem itaque reiciendis
      nihil placeat incidunt aperiam tempora, commodi eveniet. Minima iusto porro iste quae dignissimos neque dolor adipisci non, soluta nisi!</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates, dolorem blanditiis exercitationem excepturi, impedit iure.</p>
  </div>

  <div class="footer">
    <span class="footer-note">
          Lorem ipsum dolor sit amet.
        </span>
  </div>
</div>

我更进一步,创建了一些按钮来展示如何允许用户选择一组主题颜色 - 并使用 jQuery 更改 CSS 变量的值。

下面是下面的 sn-p 在 Chrome 64 上的外观 - 如果您仍在使用不支持 CSS 变量的浏览器:

$(".header--theme-button").on("click", function() 
  var primaryColor = $(this).css("--theme-primary");
  var secondaryColor = $(this).css("--theme-secondary");

  $(".header--theme-button").removeClass("active");
  $(this).addClass("active");

  $(document.body).css("--primary-color", primaryColor);
  $(document.body).css("--secondary-color", secondaryColor);
);
:root 
  --primary-color: orange;
  --secondary-color: white;
  --theme-primary: black;
  --theme-secondary: white;


body 
  font-family: "Segoe UI", "Serif", "Verdana", "Arial";


.container 
  display: grid;
  grid-template-columns: 120px 1fr;
  grid-template-rows: 50px 1fr 30px;
  grid-gap: 5px;


.header 
  grid-row: 1;
  grid-column: 1 / 3;


.nav 
  grid-column: 1;
  grid-row: 2;
  border-right: 1px solid var(--primary-color);


.content 
  grid-column: 2;
  grid-row: 2;
  padding: 10px;


.footer 
  grid-row: 3;
  grid-column: 1 / 3;
  text-align: center;



/* Child items. */

.header-logo 
  float: left;
  width: 100px;
  background-color: var(--primary-color);
  height: 50px;
  color: var(--secondary-color);
  font-size: 30px;
  padding: 3px 5px;
  box-sizing: border-box;


.header-settings 
  float: right;
  height: 50px;


.nav-links 
  list-style: none;
  margin: 5px 0 0 0;
  padding: 0;


.nav-links--link 
  color: var(--primary-color);
  background-color: var(--secondary-color);
  width: 100%;
  height: 30px;
  margin: 0 0 5px 0;
  padding: 4px 5px;
  box-sizing: border-box;
  cursor: pointer;


.nav-links--link.active,
.nav-links--link:hover 
  background-color: var(--primary-color);
  color: var(--secondary-color);


.footer-note 
  color: var(--primary-color);
  background-color: var(--secondary-color);
  padding: 3px 0;
  display: block;


.header--theme-button 
  height: 30px;
  width: 30px;
  margin: 10px 5px 0 0;
  display: inline-block;
  border-top: 15px solid var(--theme-primary);
  border-bottom: 15px solid var(--theme-secondary);
  border-right: 0;
  border-left: 0;
  padding: 0;
  box-shadow: 0 0 3px gray;


.header--theme-button:hover 
  box-shadow: 2px 2px 2px gray;


.header--theme-button.active 
  box-shadow: 3px 3px 3px gray;
<div class="container">
  <div class="header">
    <div class="header-logo">
      LOGO
    </div>
    <div class="header-settings">
      <button type="button" class="header--theme-button active" style="--theme-primary:orange; --theme-secondary:white;">
          </button>
      <button type="button" class="header--theme-button" style="--theme-primary:#2196F3; --theme-secondary:#eee;">
          </button>
      <button type="button" class="header--theme-button" style="--theme-primary:purple; --theme-secondary:white;">
          </button>
      <button type="button" class="header--theme-button" style="--theme-primary:#F44336; --theme-secondary:white;">
          </button>
      <button type="button" class="header--theme-button" style="--theme-primary:green; --theme-secondary:white;">
          </button>
      <button type="button" class="header--theme-button" style="--theme-primary:#FFEB3B; --theme-secondary:#222;">
          </button>
    </div>
  </div>

  <div class="nav">
    <ul class="nav-links">
      <li class="nav-links--link active">
        Home
      </li>
      <li class="nav-links--link">
        About
      </li>
      <li class="nav-links--link">
        Contact Us
      </li>
    </ul>
  </div>

  <div class="content">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta, ea.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Facilis id tenetur repudiandae deserunt, ipsam quisquam dicta tempora. Temporibus, vel, veritatis.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dignissimos odio id repellat quam, assumenda magnam! Beatae perferendis error exercitationem molestias explicabo earum ipsam maiores ullam natus dolorum, dolorem itaque reiciendis
      nihil placeat incidunt aperiam tempora, commodi eveniet. Minima iusto porro iste quae dignissimos neque dolor adipisci non, soluta nisi!</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates, dolorem blanditiis exercitationem excepturi, impedit iure.</p>
  </div>

  <div class="footer">
    <span class="footer-note">
          Lorem ipsum dolor sit amet.
        </span>
  </div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

【讨论】:

正是我想要的。感谢您的详细回答! 似乎它在 IE 中不起作用,如果这对你很重要的话。 caniuse.com/#feat=css-variables @SeanMC 我想这会在一定程度上覆盖它npmjs.com/package/css-vars-ponyfill 我认为它不适用于有点旧的浏览器【参考方案3】:

是的,您可以使用 Javascript 更改 CSS。有关更多信息,请参阅this tutorial。它基本上像这样链接多个样式表:

<link rel="stylesheet" type="text/css" title="blue"
   href="http://example.com/css/blue.css">
<link rel="alternate stylesheet" type="text/css" title="pink"
   href="http://example.com/css/pink.css">

然后用Javascript改一下:

<form>
<input type="submit" onclick="switch_style('blue');return false;" name="theme" value="Blue Theme" id="blue">
<input type="submit" onclick="switch_style('pink');return false;" name="theme" value="Pink Theme" id="pink">
</form>

switch_style() 函数是在该教程中编写的。

【讨论】:

【参考方案4】:

你甚至不需要任何 Javascript:

input[type=radio][value=light]:checked ~ article 
    color: #222;
    background-color: #FFEEAA;


input[type=radio][value=dark]:checked ~ article 
    color: #EEE;
    background-color: grey;
<body>
  <input type="radio" name="theme" value="light" checked="checked">Light<br>
  <input type="radio" name="theme" value="dark">Dark<br>
  <article>
    <h1>My super page!</h1>
    <p>
      Quibusdam sit repudiandae consequuntur doloremque illum ut ex quo. Esse temporibus est id suscipit repellat. Distinctio voluptatem voluptates asperiores dolorem dolorem placeat corporis quae. Quaerat voluptatem magni dignissimos rerum distinctio odio id.
    </p>
  </article>
</body>

【讨论】:

【参考方案5】:

如果您想在主题之间来回切换,我建议您在 javascript 中使用以下内容:

var count = 0

document.getElementById('trigger').onclick = function () 
    count = count + 1;
    if (count%2!=0)
      document.getElementById('default').href = 'changeTheme.css';
     else 
      document.getElementById('default').href = 'main.css';
    
;

然后使用前面提到的标记

【讨论】:

【参考方案6】:

或者只是将您的主题 css 放在 css 文件中并将其传递给函数,在页面加载 if (localStorage.getItem("theme") != "") 检查主题是否已设置.. 在这里你有一个例子:

   if (localStorage.getItem("theme") != "") 
        loadcssfile(localStorage.getItem("theme"));
      

      function loadcssfile(filename) 
        if (filename != "") 
          localStorage.setItem("theme", filename);
        
        
        var fileref = document.createElement("link");
        fileref.setAttribute("rel", "stylesheet");
        fileref.setAttribute("type", "text/css");
        fileref.setAttribute("href", filename);

        if (typeof fileref != "undefined")
          document.getElementsByTagName("head")[0].appendChild(fileref);
      
   <div onclick="loadcssfile('css/pink.css')" id="pink">
      Pink
    </div>
    <div
      onclick="loadcssfile('css/blue.css')" id="blue">
      Blue
    </div>

【讨论】:

以上是关于如何使用 CSS 和 JavaScript 制作可变主题的主要内容,如果未能解决你的问题,请参考以下文章

使用CSS和Javascript制作标签

网页首页制作总结(div+css+javascript)

使用 html、javascript、css 制作 IOS 应用程序

如何仅使用 CSS 制作标签? [复制]

如何使用纯 CSS/JavaScript(即没有 jQuery、没有 Boostrap 等)创建可水平和垂直折叠的 HTML div?

具有固定列和标题的可滚动表格,带有现代 CSS