Bootstrap 5.2及以上版本已提供本文所述方法的解决方案。因此,如果您使用的是Bootstrap 5.2或更高版本,可以直接使用CSS变量进行自定义覆盖。
Bootstrap,这个老牌的Web前端框架,有人爱之如命,也有人对其嗤之以鼻。无论您持何种观点,它都是一个强大的UI框架,应用广泛,大多数人都了解其基础知识,并且能提供高度可预测的结果。
Bootstrap 有其固有的设计理念。它要求您以特定的方式构建HTML,以特定的方式覆盖样式,以特定的方式构建核心文件,并以特定的方式将其包含在网站中。通常情况下,除非您的同事编写了糟糕的Bootstrap代码,否则这都没问题,但它并不涵盖所有用例。
Bootstrap 倾向于在服务器端生成,并且不喜欢在运行时覆盖其样式。如果您需要在应用程序中实现某种视觉主题功能,Bootstrap建议您为每个主题生成单独的样式表,并在需要时切换样式表。如果您要为用户提供预定义的主题,这是一种很好的方法。但是,如果您想要用户自定义主题呢?您可以设置您的应用程序来运行Sass并编译新的样式表并将其保存到服务器,但这需要大量的工作——此外,您还必须与后端人员和DevOps团队沟通,如果您只想,比如说,交换主色和次色,这将是一大堆麻烦。
这就是我当时面临的情况。
我正在使用Django和Vue构建一个多用户SaaS应用程序,它具有固定的布局,但也需要能够为每个用户帐户更改品牌颜色,并具有自动的默认颜色主题。还有一个要求是,我们不会在每次添加新用户时都重新部署应用程序。最后,每个后端和DevOps开发人员目前都忙于其他项目,所以我必须独自解决这个问题。
由于我不想在运行时编译Sass,我可以创建样式表并将它们注入页面,但这并不是一个好的解决方案,因为我们关注的是颜色。编译后的Bootstrap样式表将颜色值呈现为明确的十六进制值,而且(我刚刚检查过)我的样式表中主蓝色的实例有23个。仅仅为了主色,我就需要覆盖每个实例,然后再次为次色、警告色、危险色以及我们想要更改的所有其他约定和颜色标准化进行操作。这很复杂,而且工作量很大。我不想那样做。
幸运的是,这个新应用程序不需要支持Internet Explorer 11,这意味着我可以使用CSS变量。它们也很棒,可以在加载样式表后定义,向各个方向流动并更改所有我想要的颜色,对吧?Bootstrap在:root元素中生成该大型变量列表,因此这应该很简单。
这时我了解到,Bootstrap只将其某些值呈现为样式表中的变量,并且此变量列表完全用于最终用户使用。该列表中的大多数变量在样式表的其余部分中都没有被引用,因此重新定义它们没有任何作用。(但是,值得注意的是,未来可能会提供更好的运行时变量支持。)
因此,我希望我的Bootstrap样式表能够使用CSS变量呈现,这些变量可以在服务器端而不是静态颜色值进行操作,严格来说,这是不可能的。如果您将颜色变量设置为CSS变量,Sass将无法编译。有一些巧妙的技巧可以使Sass做到这一点(这里有一个,还有一个),但它们需要分支Bootstrap,而脱离升级路径会给我的应用程序带来一些我不愿意添加的脆弱性。如果我完全说实话,我没有实现这些解决方案的真正原因是我无法弄清楚如何让任何一个与我的Sass编译器一起工作。但您可能运气更好。
我认为在这里解释我首选的工作流程是值得的。我更喜欢在我的开发机器上本地运行Sass来构建样式表并将编译后的样式表提交到仓库。最佳实践建议应该在部署期间编译样式表,这是正确的,但我为一家不断发展、人手 perpetually understaffed 的创业公司工作。我使用Sass是因为我喜欢它,但在我的工作中显然是一个主题,我没有时间、能力或精神力量将我的Sass构建与我们的各种部署管道集成。
这也是一种合法的邪恶自卫:我不希望我们的全栈开发人员接触到我精心制作的样式并开始编写他们想要的任何内容;而且我发现,由于某种原因,他们在笔记本电脑上安装Node时遇到了很大的麻烦。唉!他们只能求我帮忙,而这正是我想要的方式。
所有这些都是说:如果我无法让样式表以其中的变量呈现,那么没有什么可以阻止我在样式表编译后将其注入到样式表中。
见证查找和替换的力量!
我们要做的就是进入Bootstrap并找到我们想要替换的颜色,这些颜色方便地位于编译后的样式表顶部的:root样式中:
<code>:root { --bs-blue: #002E6D; --bs-indigo: #6610F2; // ... other variables }</code>
获取例如 --bs-primary 的值,也就是老式的Bootstrap蓝色。我使用Gulp来编译我的样式表,因此让我们在gulpfile.js中查看Sass任务函数:
var gulp = require('gulp'); var sass = require('gulp-sass')(require('sass')); var sourcemaps = require('gulp-sourcemaps'); var gulpreplace = require('gulp-replace'); function sassCompile() { return gulp.src('static/sass/project.scss') .pipe(sourcemaps.init()) .pipe(sass({outputStyle: 'expanded'})) .pipe(sourcemaps.write('.')) .pipe(gulpreplace(/#002E6D/ig, 'var(--ct-primary)')) .pipe(gulp.dest('static/css/')); } exports.sass = sassCompile;
编译样式表,然后查看它。
:root { --bs-blue: var(--ct-primary); --bs-indigo: #6610F2; // ... other variables }
太棒了,好的,我们现在有一个完整的样式表,它需要一个变量值来表示蓝色。请注意,它同时更改了主色和“蓝色”。这并非一种微妙的技术。我称之为快速而粗糙是有原因的,但是如果您需要,获得更细粒度的颜色替换控制相当容易。例如,如果您想将“蓝色”和“主要”作为单独的值保留,请进入您的Sass并将$blue和$primary Sass变量重新定义为不同的值,然后您可以根据需要分别查找和替换它们。
接下来,我们需要在应用程序中定义新的默认变量值。在HTML头部执行此操作非常简单:
<link href="/static/css/project.css" rel="stylesheet"> <style> :root { --ct-primary: #002E6D; } </style>
运行它,一切都会显示出来。所有需要是蓝色的东西都是蓝色的。重复此过程几次,您突然可以控制Bootstrap样式表中的许多颜色。这些是我选择提供给用户的变量,以及它们的默认颜色值:
--ct-primary: #002E6D; --ct-primary-hover: #00275d; // ... other variables
现在,乐趣开始了!从这里开始,您可以根据需要直接操作这些默认值,或者在默认值下方添加第二个:root样式来仅覆盖您想要的颜色。或者像我一样,在用户配置文件中放置一个文本字段,该字段将:root样式输出到您的标题中,从而覆盖您需要的任何内容。瞧,您现在可以在运行时覆盖Bootstrap,而无需重新编译样式表或让自己抓狂。
这当然不是一个优雅的解决方案,但它解决了一个多年来开发人员一直在尝试解决的非常具体的用例。并且在Bootstrap决定允许我们轻松地在运行时覆盖变量之前,这对我来说已被证明是一个非常有效的解决方案。
以上是快速而肮脏的引导程序在运行时覆盖的详细内容。更多信息请关注PHP中文网其他相关文章!