【问题标题】:Correct way to customize Bootstrap 4 using NPM and SASS?使用 NPM 和 SASS 自定义 Bootstrap 4 的正确方法?
【发布时间】:2020-11-03 00:55:49
【问题描述】:

我在尝试自定义 Bootstrap 4 时失去理智。从字面上看,每一个 YouTube 视频、博客文章和 Bootstrap 自己的文档要么缺乏足够的信息,要么令人困惑,要么已经过时且不再相关。以下是我所知道的:

  • 我知道我需要使用 NPM 将 Bootstrap 下载到我的项目目录中
  • 我知道我不应该直接对 Bootstrap 的源文件进行更改
  • 我知道我需要设置一个自定义 SCSS 文件并将 Bootstrap 函数导入该文件中
  • 我知道在对 SCSS 文件进行更改后需要“调用”Bootstrap
  • 我知道我需要设置、运行和编译 Sass

我的问题:

  • node-sass 和常规 sass 有什么区别,我用哪一种?
  • 安装 Sass 并将其设置为监视更改的正确方法是什么?
  • 如果我想使用 Google 字体,我应该在哪里导入/链接?在 HTML 中?在我的自定义 SCSS 文件中?两者都有?
  • 导入我想要覆盖的 Bootstrap 函数的正确方法是什么?

我知道这很多,但说真的,网上有十亿个相互冲突的教程,但没有一个对我有用。非常感谢任何帮助!

【问题讨论】:

  • 您使用的是哪个编辑器? Visual Studio 还是 VS Code?我问这个是因为我不确定所有编辑器都支持 package.json 但我们假设你的支持...

标签: twitter-bootstrap bootstrap-4 sass frontend


【解决方案1】:

node-sass 和普通 sass 有什么区别,我用哪一个?

  • Bootstrap 4 使用 scss(Compass,它是围绕 sass 构建的)
  • 它们使用相似的语法,但在某些功能上有所不同
  • node-sass 是一个为 Node 提供绑定的库。它允许您将 .scss 文件本地编译为 css。由于使用 NPM 之类的包管理器,您将使用 Node.js。该库绑定到您的环境和 Node 版本,以预处理您的 scss 文件。
  • 在 gulp 中使用 css watcher,需要其他包才能使其工作
  • 你不需要 gulp 作为观察者,但你很可能必须安装 Ruby Compass(现在作为设置有点过时了,我可能错了)

安装 Sass 并将其设置为监视更改的正确方法是什么?

等等,你已经决定使用 sass 还是你指的是 scss? 正确的做法是坚持使用 Bootstrap 包中的内容。如果您使用 package.json 文件,并且应该使用,那么您将需要 node-sass(我认为)。可能还有其他软件包,但我知道它是这样工作的。

要考虑的另一件事是转译器,例如 Babel。 Babel 需要在 package.json 或 .browserslistrc 文件中进行设置。

所以 package.json 中的一些要点:

{
    "dependencies": {
        "bootstrap": "^4.3.1", // your bs version
        "font-awesome": "^4.7.0", // we'll get to fonts later
        "jquery": "^3.4.1", // bs dependency
        "popper.js": "^1.15.0" // bs dependency
    },
    "devDependencies": {
        "@babel/core": "^7.5.5", // transpiler requirement
        "@babel/preset-env": "^7.5.5", // transpiler requirement
        "debounce": "^1.2.0", // gulp task, depends on your Gulpfile.js
        "es6-promise": "^4.2.8",
        "eslint": "^5.16.0", 
        "graceful-fs": "^4.2.2",
        "gulp": "^4.0.2", // your task runner Gulp
        "gulp-autoprefixer": "^6.1.0", // gulp util
        "gulp-babel": "^8.0.0-beta.2", // transpiler for gulp tasks
        "gulp-clean": "^0.4.0", // gulp util
        "gulp-clean-css": "^3.10.0",
        "gulp-cli": "^2.2.0", // gulp requirement
        "gulp-concat": "^2.6.1", // gulp util
        "gulp-fs-cache": "^0.1.0", // gulp util
        "gulp-modernizr": "^3.3.0", // great way to detect js requirements
        "gulp-sass": "^4.0.2", // node-sass version for gulp
        "gulp-sourcemaps": "^2.6.5", // gulp util
        "gulp-uglify": "^3.0.2", // gulp util
        "gulp-util": "^3.0.8", // hey gulp util
        "gulp-watch-sass": "^1.4.1", // css compiler
        "invariant": "^2.2.4", // not sure, probably got some warning
        "minimatch": "^3.0.4", // not sure, probably got some warning
        "node-gyp": "^3.8.0", // meh
        "npm": "^6.11.2", // your package manager
        "requirejs": "^2.3.6", // requirements in Gulpfile.js
        "stream-series": "^0.1.1", // task util
        "strip-ansi": "^4.0.0" // not sure, probably got some warning
    },
    "browserslist": [
        "> 0.5%",
        "not ie <= 10",
        "not dead"
    ]
}

好吧,不是真正的 node-sass,但 gulp-sass 是 node-sass 的包装器,它反过来绑定到您的环境。我知道,现在很容易与包裹混在一起。

可以使用https://browserl.ist/ 更改 Babel 设置。这用于 CSS 中的自动前缀。不再需要写 -webkit-blabla 了。根据 browserslist 设置,它会为您选择这个。

如果我想使用 Google 字体,我应该在哪里导入/链接?在 HTML 中?在我的自定义 SCSS 文件中?两者都有?

我更喜欢复制包 scss 文件并在根目录中创建一个 fonts.scss。 从那里我们可以导入谷歌字体或自定义字体,如 font-awesome。

我的 fonts.scss 文件

@import '_variables/myprojectname.custom.variables';

/*
 * font-weight: 100; // Thin (Hairline)
 * font-weight: 200; // Extra Light (Ultra Light)
 * font-weight: 300; // Light
 * font-weight: 400; // Normal
 * font-weight: 500; // Medium
 * font-weight: 600; // Semi Bold (Demi Bold)
 * font-weight: 700; // Bold
 * font-weight: 800; // Extra Bold (Ultra Bold)
 * font-weight: 900; // Black (Heavy)
 */

//https://github.com/webpack-contrib/less-loader/issues/67
//https://github.com/madskristensen/BundlerMinifier/issues/191

// DIN PRO (converted)
@font-face {
    font-family: "DINPro";
    src: url('#{$converted-font-path}/DINPro-Light.eot');
    src: url('#{$converted-font-path}/DINPro-Light.eot?#iefix') format('embedded-opentype'), url('#{$converted-font-path}/DINPro-Light.woff2') format('woff2'), url('#{$converted-font-path}/DINPro-Light.woff') format('woff'), url('#{$converted-font-path}/DINPro-Light.ttf') format('truetype'), url('#{$converted-font-path}/DINPro-Light.svg#DINPro-Regular') format('svg');
    font-weight: 300;
    font-style: normal;
}

@font-face {
    font-family: "DINPro";
    src: url('#{$converted-font-path}/DINPro-Regular.eot');
    src: url('#{$converted-font-path}/DINPro-Regular.eot?#iefix') format('embedded-opentype'), url('#{$converted-font-path}/DINPro-Regular.woff2') format('woff2'), url('#{$converted-font-path}/DINPro-Regular.woff') format('woff'), url('#{$converted-font-path}/DINPro-Regular.ttf') format('truetype'), url('#{$converted-font-path}/DINPro-Regular.svg#DINPro-Regular') format('svg');
    font-weight: 400;
    font-style: normal;
}

@font-face {
    font-family: "DINPro";
    src: url('#{$converted-font-path}/DINPro-Medium.eot');
    src: url('#{$converted-font-path}/DINPro-Medium.eot?#iefix') format('embedded-opentype'), url('#{$converted-font-path}/DINPro-Medium.woff2') format('woff2'), url('#{$converted-font-path}/DINPro-Medium.woff') format('woff'), url('#{$converted-font-path}/DINPro-Medium.ttf') format('truetype'), url('#{$converted-font-path}/DINPro-Medium.svg#DINPro-Medium') format('svg');
    font-weight: 500;
    font-style: normal;
}

@font-face {
    font-family: "DINPro";
    src: url('#{$converted-font-path}/DINPro-MediumItalic.eot');
    src: url('#{$converted-font-path}/DINPro-MediumItalic.eot?#iefix') format('embedded-opentype'), url('#{$converted-font-path}/DINPro-MediumItalic.woff2') format('woff2'), url('#{$converted-font-path}/DINPro-MediumItalic.woff') format('woff'), url('#{$converted-font-path}/DINPro-MediumItalic.ttf') format('truetype'), url('#{$converted-font-path}/DINPro-MediumItalic.svg#DINPro-MediumItalic') format('svg');
    font-weight: 500;
    font-style: italic;
}

@font-face {
    font-family: "DINPro";
    src: url('#{$converted-font-path}/DINPro-Bold.eot');
    src: url('#{$converted-font-path}/DINPro-Bold.eot?#iefix') format('embedded-opentype'), url('#{$converted-font-path}/DINPro-Bold.woff2') format('woff2'), url('#{$converted-font-path}/DINPro-Bold.woff') format('woff'), url('#{$converted-font-path}/DINPro-Bold.ttf') format('truetype'), url('#{$converted-font-path}/DINPro-Bold.svg#DINPro-Bold') format('svg');
    font-weight: 700;
    font-style: normal;
}

// HELVETICA ROUNDED
@font-face {
    font-family: "Helvetica";
    src: url('#{$cond-font-path}/HelveticaRounded-BoldCond.eot');
    src: url('#{$cond-font-path}/HelveticaRounded-BoldCond.eot?#iefix') format('embedded-opentype'), url('#{$cond-font-path}/HelveticaRounded-BoldCond.woff2') format('woff2'), url('#{$cond-font-path}/HelveticaRounded-BoldCond.woff') format('woff'), url('#{$cond-font-path}/HelveticaRounded-BoldCond.ttf') format('truetype'), url('#{$cond-font-path}/HelveticaRounded-BoldCond.svg#HelveticaRounded-BoldCond') format('svg');
    font-weight: 700;
    font-stretch: condensed;
    font-style: normal;
}

// ICON
@font-face {
    font-family: $ico-font-family;
    src: url('#{$ico-font-path}/#{$ico-font-family}.eot?v=#{$ico-font-version}');
    src: 
    //url('#{$ico-font-path}/WHN-Icons.eot?#iefix&v=#{$ico-font-version}') format('embedded-opentype'),
    url('#{$ico-font-path}/#{$ico-font-family}.woff?v=#{$ico-font-version}') format('woff'),
    url('#{$ico-font-path}/#{$ico-font-family}.ttf?v=#{$ico-font-version}') format('truetype'),
    url('#{$ico-font-path}/#{$ico-font-family}.svg?v=#{$ico-font-version}#fontawesomeregular') format('svg');
    font-weight: normal;
    font-style: normal;
}

请注意第一行我如何使用自定义变量文件。这只是 Bootstrap 的 _variables.scss 的一个副本。我在自己的 scss 文件中重新创建设置并覆盖变量文件。

使用单独文件的最重要原因是因为字体render block while loading。分离资产(字体、艺术品、图像...)允许我使用异步 CSS &lt;link /&gt;eliminate render blocking issues

自定义引导设置项目名.atomic.scss:

/*!
 * Atomic design principle
 */

@import "../vendor/bootstrap/scss/functions";
@import "_variables/fa.custom.variables"; // font awesome override variables
@import "_variables/projectname.custom.variables"; // bootstrap override variables
@import "../vendor/bootstrap/scss/variables";
@import "../vendor/bootstrap/scss/mixins";
@import "_mixins/company.custom.mixins"; // custom mixins
@import "../vendor/bootstrap/scss/root";
@import "../vendor/bootstrap/scss/reboot";
@import "../vendor/bootstrap/scss/type";
@import "../vendor/bootstrap/scss/images";
@import "../vendor/bootstrap/scss/code";
@import "../vendor/bootstrap/scss/grid";
@import "../vendor/bootstrap/scss/tables";
@import "../vendor/bootstrap/scss/forms";
@import "../vendor/bootstrap/scss/buttons";
@import "../vendor/bootstrap/scss/transitions";
@import "../vendor/bootstrap/scss/dropdown";
@import "../vendor/bootstrap/scss/button-group";
@import "../vendor/bootstrap/scss/input-group";
@import "../vendor/bootstrap/scss/custom-forms";
@import "../vendor/bootstrap/scss/nav";
@import "../vendor/bootstrap/scss/navbar";
@import "../vendor/bootstrap/scss/card";
@import "../vendor/bootstrap/scss/breadcrumb";
@import "../vendor/bootstrap/scss/pagination";
@import "../vendor/bootstrap/scss/badge";
@import "../vendor/bootstrap/scss/jumbotron";
@import "../vendor/bootstrap/scss/alert";
@import "../vendor/bootstrap/scss/progress";
@import "../vendor/bootstrap/scss/media";
@import "../vendor/bootstrap/scss/list-group";
@import "../vendor/bootstrap/scss/close";
@import "../vendor/bootstrap/scss/modal";
@import "../vendor/bootstrap/scss/tooltip";
@import "../vendor/bootstrap/scss/popover";
@import "../vendor/bootstrap/scss/carousel";
@import "../vendor/bootstrap/scss/utilities";
@import "../vendor/bootstrap/scss/print";

// This is where my real work comes in, for big projects this has proven to be succesful in maintaining and multisite setup
@import "atoms/atoms";
@import "molecules/molecules";
@import "organisms/organisms";
@import "tenants/projectname/themes/themes";
@import "tenants/projectname/pages/pages";

通过重新创建设置,覆盖默认设置变得很容易。当您插入自己的变量时,请注意 !default 的用法,当它是引导变量时不要使用 !default

我的 _projectname.custom.variables.scss 的一部分

$design-path: "/Design" !default;
$font-family-headings: Helvetica, sans-serif !default;
$font-family-headings-fallback: DINPro, sans-serif !default;

$cond-font-path: "../../../fonts/app/helvetica-rounded-converted" !default;
$pro-font-path: "" !default;
$converted-font-path: "../../../fonts/app/din-pro-converted" !default;
$ico-font-path: "../../../fonts/app/icomoon/projectname" !default;
$ico-font-version: "xyftn5" !default;
$ico-font-family: 'icomoon' !default;

$theme-green: #7EC796 !default; // de york
$theme-yellow: #FFBD51 !default; // texas rose
$theme-red: #E24B43 !default; // cinnabar
$theme-blue: #7CB1D1 !default; // half baked
$theme-pink: #FE8980 !default; // vivid tangerine
$theme-cyan: #A5B54E !default; // olive green
$theme-indigo: #12884E !default; // salem
$theme-orange: #F77D54 !default; // coral
$theme-teal: #307A83 !default; // paradiso

// FONTAWESOME VARIABLES override
$fa-var-arrow-down: "\e903";
$fa-var-arrow-left: "\e900";
$fa-var-arrow-right: "\e901";
$fa-var-arrow-up: "\e902";
$fa-var-bars: "\e914";
$fa-var-calendar: "\e908";
$fa-var-chevron-down: "\e907";
$fa-var-chevron-left: "\e904";
$fa-var-chevron-up: "\e906";
$fa-var-chevron-right: "\e905";

// BOOTSTRAP VARIABLES override
$grid-breakpoints: ( xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px );
$grid-gutter-width: 2rem;
$grid-gutter-fluid-width: 2.1875rem !default; // custom variable
$container-max-widths: ( sm: 540px, md: 720px, lg: 960px, xl: 1140px, xxl: 1340px );

// and many many more become available at your fingertips

导入我想要覆盖的 Bootstrap 函数的正确方法是什么?

这应该在上一个问题中涉及。 只需创建自己的 _functions.scss 并将其添加到原始文件下方即可。

@import "../vendor/bootstrap/scss/functions";
@import "_functions/company.custom.functions"; // override or extend, your choice

我知道这需要接受很多,但你问了很多 :) 好像你已经掌握了窍门,或者只是到处都是。随时询问更多信息,例如 Gulpfile.js 或其他内容。

祝你好运,愉快地消化我较长的答案之一^^

【讨论】:

  • 蒂姆,非常感谢您的详尽回答!我听说过使用 Gulp 编译 sass,但我的理解是我可以在我的 package.json 或命令行中添加一行代码来观看它。我会更多地研究它和你在这里给出的例子。再次感谢!
【解决方案2】:

最简单的方法是使用包含 bootstrap 和 sass 的入门模板。例如:

https://github.com/abhijithvijayan/gulp-sass-bootstrap-boilerplate

然后按照说明通过 npm 进行安装,并查看文件夹和文件结构以查看可以放置编辑的位置。

【讨论】:

  • 非常感谢,我会调查的!
猜你喜欢
  • 1970-01-01
  • 2016-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-14
相关资源
最近更新 更多