Styling Themes
This folder contains SCSS files. index.scss is required.
While developing and working with other blogging platforms/CMSs, we understood that customizing a theme becomes really hard when the theme developer puts all CSS in a single file. Therefore, we decided that we want to support "chunk-css" files to make it easy to edit for the blogger. And, we use SCSS instead of CSS to make the theme developer's life easier. All CSS is valid SCSS. So, if you haven't use SCSS earlier, just use CSS. SCSS just have some cool features like nesting rules.
Back to “chunk-css”. let’s say you make a partial file for the blog header (templates/_header.twig
). Then create an SCSS file to hold its CSS (header.scss
). This pattern makes understanding and editing easier for the blogger. Finally, import all chunk files to index.scss
using @import
statements.
@import 'css-variables.scss';
@import 'header.scss';
@import 'body.scss';
On our side, we process index.scss
file and generate a styles.css
, which will be accessible via /styles.css. That is the only CSS file of the whole blog!
We strongly encourage you to write CSS from scratch without using any libraries like Bootstrap. A blog theme is very simple and it is totally possible to manage everything on your own without depending on third-party libraries. If you really want to use a library, add it to assets instead of styles.
Fonts
The easiest way to load fonts is by adding THEME_FONTS
to the config file.
THEME_FONTS: "mulish:400"
Then, you can use the font in your SCSS files. See our fonts page for a in-depth guide.
Advanced Nodes
Writing page describes all supported nodes. We try to use the most basic HTML elements to represent each node. However, there are some advanced components that require some attention when writing styles.
Image
<figure>
<img src="https://exmaple.com/image.png" />
<figcaption>Here goes the caption</figcaption>
</figure>
Note that figcaption can be empty. So, check if margins look good when figcaption is not there.
Embed
<figure>
<div class="rich-embed">
{# embed HTML code goes here... #}
</div>
<figcaption>Here goes the caption</figcaption>
</figure>
Link Bookmark
<figure>
<a class="rich-link">
<div class="rich-link-details">
<div class="rich-link-title">{{ data.title }}</div>
<div class="rich-link-description">{{ data.description }}</div>
<div class="rich-link-domain">{{ data.domain }}</div>
</div>
<div class="rich-link-thumbnail">
<img src="{{ data.thumbnail }}" />
</div>
</a>
<figcaption>{{ data.caption }}</figcaption>
</figure>
Callout
<aside style="background-color:#0000000;color:#ffffff">
<mark></mark>
</aside>
Node Templates
Some nodes have templates. And, as the theme developer, you can customize them if the default template doesn't fit your design. To do that, add the given file to the /templates
folder.
Link Bookmark
Custom file name: node-bookmark.twig
Default template:
<a class="bookmark" target="_blank" href="{{ data.url }}" data-url="{{ data.original_url }}">
<div class="bookmark-details">
<div class="bookmark-title">{{ data.title }}</div>
<div class="bookmark-description">{{ data.description }}</div>
<div class="bookmark-domain">{{ data.domain }}</div>
</div>
<div class="bookmark-thumbnail">
<img src="{{ data.thumbnail_url }}" alt="{{ data.title }}"/>
</div>
</a>
data
object definition:
{
"url": "https://blogs.hyvor.com",
"original_url": "https://blogs.hyvor.com",
"title": "Hyvor Blogs",
"description": "A simple blogging platform",
"domain": "blogs.hyvor.com",
"thumbnail_url": "https://blogs.hyvor.com/thumbnail.png",
}
Table of Contents (TOC)
Custom file name: node-toc.twig
Default template:
{{ toc | raw }}
The toc
variable is a string that contains the HTML of the TOC as nested ul
and li
elements.
Example: If you want to add a heading to the TOC, you can do it as follows. The raw
filter is required to render the HTML of the TOC.
<div class="toc-wrap">
<h2>Table of Contents</h2>
{{ toc | raw }}
</div>
Light/Dark Modes
The blogger has the following options to choose in the Console.
- What modes are allowed?
- What is the default mode?
- User's OS-level preference (default)
- Light
- Dark
It would be troublesome for you to write logic to consider all these options and find out what theme to show to the user. Therefore, we make developing light/dark easy by adding a class name to the <html></html>
element. You can decide colors based on that class. We recommend you to use CSS Variables to define colors in colors.scss
file.
Here's an example of how to define colors for light and dark modes.
.mode-light:root {
--color-background: #ffffff;
--color-text: #000000;
}
.mode-dark:root {
--color-background: #000000;
--color-text: #ffffff;
}
Then, in elements, use those variables. Avoid hard coding colors values!
body {
background-color: var(--color-background);
color: var(--color-text);
}
That is all you have to do to support light and dark modes. We take care of showing the correct theme to the user.
Under the hood, determining the color is handled by a small Javascript code injected into the blog in the _head
placeholder.
Light/Dark Mode Toggler
If you support both light and dark themes, you will mostly likely have a button that allows users to toggle between color modes. In most other platforms, you have to write logic to do this manually and save preferences in local storage - but not in Hyvor Blogs!
We mentioned above that we add a small Javascript code to help you with determining light/dark modes. It also exposes a simple API to help you with toggling modes.
_hb.changeColorMode(mode); // mode = os|light|dark
_hb.getColorMode() // returns light|dark
_hb.getColorModePreference() // returns light|dark|os
Use these global functions in the toggle buttons - We'll handle the LocalStorage.
<div class="mode-toggler">
<button class="toggle-dark" onclick="_hb.changeColorMode('dark')"></button>
<button class="toggle-light" onclick="_hb.changeColorMode('light')"></button>
</div>
You can use a SCSS like this to show buttons on the based on the theme. This will show the light mode icon in dark mode, and dark mode button in light mode.
.mode-dark {
.toggle-dark {
display:none;
}
}
.mode-light {
.toggle-light {
display:none;
}
}
Light + Dark + OS Preference Toggler
Some may also want to add OS preference option to the toggler. In that case, the HTML will be similar but we have to use mode-preference-*
classes to detect the user's preference.
mode-light
and mode-dark
classes are added to the <html>
, and they represent current color mode. mode-preference-light
, mode-preference-dark
, mode-preference-os
are added to the <html>
and they represent the current color mode preference.
<div class="mode-toggler">
<button class="toggle-light" onclick="_hb.changeColorMode('dark')"></button>
<button class="toggle-dark" onclick="_hb.changeColorMode('os')"></button>
<button class="toggle-os" onclick="_hb.changeColorMode('light')"></button>
</div>
The following SCSS code will display the currently active mode preference button.
.toggle-dark, .toggle-light, .toggle-os {
display:none;
}
.mode-preference-light .toggle-light {
display:inline-block;
}
.mode-preference-dark .toggle-dark {
display:inline-block;
}
.mode-preference-os .toggle-os {
display:inline-block;
}
Please note that these examples are just here to explain you how it works. Feel free to design more creative color mode togglers ;)