Some time ago I started fooling around with Svelte after hearing a lot from it on Twitter, and so my journey began. Since my time was rather limited I decided to stick to the basics and intended to try and build a simple one-pager with it.
Svelte is a radical new approach to building user interfaces. Whereas traditional frameworks like React and Vue do the bulk of their work in the browser, Svelte shifts that work into a compile step that happens when you build your app. — svelte.dev
This post will walk you trough the basics of Svelte and you will have created a one-pager yourself at the end of it.
By default Svelte can do a lot of things out of the box and it’s very easy to start making your own components. Let’s start our prototyping example.
npx degit sveltejs/template prototyping-with-svelte cd prototyping-with-svelte npminstall npm run dev
If everything went well, the template will be served on localhost:5000. In case you are wondering what degit is, this is a project scaffolding tool. Next to using degit to get started it’s also possible to use the REPL.
Project structure is as straightforward as it can get. There’s a src folder which contains main.js and App.svelte.
main.js is the entry point of the application and App.svelte is the root component.
As you can see both the HTML markup, styling and script are present in the same file. Personally I’m not a big fan of that and for that reason I will later on show you how I excluded the styling from the components to create a shared CSS codebase.
Before we’ll be able to use our ResourceCard component we'll need to import it in our App.svelte component and provide data for it.
For maintainability and scalability I personally prefer my styles to be more centralised. For that reason I will create a _resource-card.scss file in src/styles and move all the styles in the style tag in the ResourceCard component to that file. In our component we replace our styles with the import to our newly created file. Note that I used an underscore character to mark our component styling as a partial.
Hm? Where did our styling go for our ResourceCard component? Well, styles that are added in a component — here App.svelte — are scoped to that component. So we will need to add the global attribute to the style-tag to fix this.
Based on what we have now, I’ll show you how easy it is to prototype a page. We’ll translate a simple one-pager wireframe to code and see how you can use this as a base to implement a real design.
Which components do we see from top to bottom?
Hero component: usually with a title, subtitle and background image.
Card component: can be used to present e.g. services. Includes an image, title and description.
Highlight component: used to highlight a specific number or target e.g. 20 coffees today, 5 releases, ...
Article component: with a title, short description and a link, optionally with date and author.
Footer component: Copyright and some footer links.
As you can see I drew narrow lines to indicate different sections. We'll provide a way to center the content based on a maximum width. Add a file called _mixins.scss in src/styles and insert the following content.
Now let’s add the Hero component. Our component will need four props: title, subtitle, imgPath and imgAlt.
To allow some flexibility in formatting the title and subtitle we’ll use the @html modifier which allows to use HTML markup in the prop value. When using this method, place the prop value between back-ticks instead of double quotes. Let’s create a Hero.svelte component file and input the code below.
Now we’ll create a _hero.scss partial and add the following. Notice that the section-center mixing is included to center the contents of the component like we did above. Don’t forget to import the _hero.scss partial in main.scss.
This component will only appear on the page once, but what if you would have a component that will be used in different places? You would have to change all the instances using find and replace. By creating a component you simply insert the component tag with the properties you need and change the component at one place.
Alright, we have ourselves a Hero. Let's move on to our next component.
We want to make the highlights appear next to each other by four just like in the wireframe. Add the following styling in main.scss. In case you're not familiar with CSS grid, it's totally worth looking into.
The code above would limit us to just 4 props and some flexibility with the @html modifier. To create greater flexibility, we could use a slot. This allows us to make the card contain anything we want.
<articleclass=“card”> <slot></slot> </article>
Using the slot we could add. The content inside the Card tag will be placed inside the slot-tag of our component.
<Card> <h2>Service one</h2> <p>Proin at ante ac lorem blandit auctor sed non lectus. Praesent consequat mauris ac risus rhoncus semper.</p> </Card> <Card> <h2>Service two</h2> <p>Proin at ante ac lorem blandit auctor sed non lectus. Praesent consequat mauris ac risus rhoncus semper.</p> </Card> <Card> <h2>Service three</h2> <p>Proin at ante ac lorem blandit auctor sed non lectus. Praesent consequat mauris ac risus rhoncus semper.</p> </Card>
Next we create the partial _card.scss and of course import it in main.scss.
Create the partial _article.scss. The trick with the after pseudo element is making sure the whole article is clickable, by positioning it absolute to cover the entire .article that is set to relative positioning. Oh and don’t forget to import the partial in main.scss.
Create the partial _footer.scss and add some basic styling. Oh, the * + * is called the owl selector. What this basically does is to apply styling to each element that is preceded by another element within a set of elements.
I love Svelte for fast prototyping, it allows me to create reusable components (with Sass) in languages I already know and the learning curve is not steep at all. For more complex behaviour there is Sapper with Service Worker integration, Server Side Rendering, and more. So yes, I will probably use it more in the future.