Svelte app using Bootstrap and Sass

One of the most popular styling libraries is Bootstrap. It’s more than just for layout. With Bootstrap, you’ll get instant styling on forms, buttons, lists and much more. There is a large range of classes that can be added to elements. Bootstrap becomes even more powerful if you start modifying the variables that it uses. The catch is that to take full advantage, you should use the Scss version of Bootstrap.

Please note: Scss and Sass are almost the same. In a nutshell, Sass is an advanced version of CSS where Scss is a superset of CSS. It really means that a CSS file could be renamed Scss and it would work. To convert to Sass you’ll need to make some changes to make work. Pronouncing both is them both is the same; sass.

So why don’t more people use SCSS? With Scss, a preprocessor needs to run to convert the Scss to CSS for the browser to understand. Also, as features of Scss becomes more popular they are being added to CSS. For example variables are now available in CSS. There are still features in Scss not in CSS yet; nesting, partials, modules, mixins, extend/inheritance, and operators. You can read more at Sass Basics.

Turns out Svelte makes adding SCSS and Bootstrap very easy. In this post we’ll go through the steps. At the end we’ll look at looking at how we can make changes to Bootstrap without needing to edit their files.

For this post we’ll be using the Svelte template. You can do these steps in any Svelte project you’re working on.

installing the node modules

There are three node modules we will install

  • Bootstrap
  • node-sass
  • Svelte preprocess

The convenience of Node is that the 3 can be install in a single line.

npm i --save-dev bootstrap node-sass svelte-preprocess

RollupJS

First things things, what is RollupJS and what does it have to do with Scss. As you may have been told, Svelte will bundle your code. It also does by using a module bundler called RollupJS. Well, that’s the default. If you want you can switch it out for WebPack which is a popular module bundler.

Which should you use? Since Svelte comes packaged with rollup as default, I’d suggest sticking with RollupJS unless there is a feature that another module bundler does better then RollupJS. Svelte does have a template that includes Web Pack instead of RollupJS. For this post, I’ll be sticking with RollupJS.

What’s great about most bundlers is that you can add other steps and they’ll handle it all together. In this case we want RollupJS to also handle the Scss preprocess.

rollup.config.js

In the main directory for your Svelte app, you’ll find a file called rollup.config.js. This is the file that handles configuration for RollupJS. We can change how RollupJS works by modifying this file. For the vast majority of projects this will be modified only once at the start if even that.

This file has four parts:

  • import section
  • variable section
  • function section
  • export default section

The file itself isn’t that long and the variable and function sections contain very little. Mostly you’ll be editing the import section and the export default sections.

add the preprocess to rollup

In rollup.config.js add this to the import section.

import preprocess from 'svelte-preprocess';

In the export default object, edit the array plugins, add a key-value to the object passed to svelte to include preprocess: autoPreprocess(), as shown below:

plugins: [
	svelte({
		// enable run-time checks when not in production
		dev: !production,
		// we'll extract any component CSS out into
		// a separate file - better for performance
		css: css => {
			css.write('public/build/bundle.css');
		},
		preprocess: preprocess(),
	}),
]

Using SCSS

Now we can use SCSS directly in the component. In the component, add lang="scss" attribute to the style element to tell Svelte to treat it as SCSS.

As far as Svelte and SCSS goes, everything is working fine. I’ve run into problems with VS code not understanding the SCSS. Keep in mind the file extension is Svelte. VS Code; as most editors; use the extension to determine how to handle errors in the code. I’ve found if I put type="text/scss" also on the style element. Most of the errors go away. Try each attribute to see which works for you, or use both.

If VS Code is still throwing strange errors, Dave Ceddia describes some other troubleshooting you can do in VS Code in his blog Use Svelte with SASS/SCSS in VS Code

Replace the contents of App.svelte with the following.

<script>
	export let name;
</script>

<main>
    <h1>Hello {name}!</h1>
    <div>
        <p>SASS is working!</p>
    </div>
</main>

<style lang="scss" type="text/scss">
$color: red;
$color2: purple;

h1 {
	color: $color;
}

div {
	background: green;

	> p {
	color: $color2;
	}
}
</style>

Here we are using SCSS variables and nesting. Run the app and the styling should take effect.

Bootstrap

Let’s add in Bootstrap and make some changes. Add this import as the first line in the style section.

@import "../node_modules/bootstrap/scss/bootstrap.scss";

When the page reloads you will see a slight change. Mainly padding, margins and font-family will be changed because of Bootstrap.

First let’s change the HTML to add some Bootstrap classes.

<main class="container">
	<h1 class="text-secondary">Hello {name}!</h1>
	
	<div>
		<p class="text-primary">SASS is working!</p>
	</div>
</main>

After the refresh, Bootstrap is styling more. Now let’s change up the colors.

Replace the entire style section with:

<style lang="scss" type="text/scss">
	$primary: yellow;

	$secondary: orange;

	@import "../node_modules/bootstrap/scss/bootstrap.scss";
</style>

The colors are being applied, how? Those variables are what Bootstrap uses. As long as we set the variables prior to the import statement, Bootstrap will use our colors instead of the default ones. Normally to make this type of change we’d need to edit the Bootstrap files themselves, or make an attempt to override the Bootstrap classes.

Since we’re changing the primary and secondary colors, any classes that use those colors; such as text-primary or btn-primary would use our new colors.

As you go through Bootstrap documentation, you’ll find other find other variables you can modify. The list of variables are listed in the file called scss/_variables.scss in the Bootstrap node module folder.

Global vs Local

There is one little detail we need to handle. Since we’re inside a component, Svelte will default to keeping any styling we do to inside that component. We’d need to rewrite all of this styling for every component. In some ways that’s why we like components, each one is independent of all others. Troubleshooting issues is much easier when they don’t mess with each other.

But with Bootstrap and our color scheme, we most likely would like all components to use the same color scheme.

To have Svelte apply the CSS globally we need to add the global attribute to the style element. <style global lang="scss" type="text/scss">. This attribute is not just for SCSS or Bootstrap. Any time you want to make a set of CSS global across all Svelte components, just use global.

A word of caution, since most people expect Svelte styling to be component based. Imagine trying to determine why an h4 element is bright blue and it turns out some small component had it’s style set to global. So use the global attribute carefully. My plan is to limit it to the app.svelte file only.

Wait a minute

Now I hear you; Wait a minute, the reason I don't use Bootstrap is because of the size and now you expect me to add it to every component?. You’re forgetting, we’re using Svelte! Since we are loading Bootstrap inside the component, Svelte will shake out any CSS we’re not using.

The minified file for Bootstrap is about 157KB. The file that Svelte bundled is 7KB! With looking in the file, Svelte could have taken a bit more out, but still it pulled out quite a bit. Now granted as we use more, it’ll get bigger, but this is awesome, we get to use power of Bootstrap without worrying about weighing our site down.

Using Bootstrap with SCSS

While I combined Bootstrap and SCSS together, they can be used separately. If you use Bootstrap without SCSS you’ll need to use the CSS version not SCSS. And as mentioned the variables wouldn’t be available. Also, you’ll always load the entire Bootstrap file. But it’s up to you what you need for your projects.

Next up

While this might not inspire you start using Bootstrap, but I hope that developers that are using Bootstrap and SCSS can see that Svelte gives you complete power to continue use the whatever set of technologies that you want to use.

Resources

Rollup JS

Svelte’s template with Webpack

Bootstrap

Sass

Sass Basics

Use Svelte with SASS/SCSS in VS Code