Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set background color based on YAML front matter (Jekyll)

Tags:

html

css

jekyll

I want to be able to set the background color of a post based on a color defined in the YAML front matter.

This theme does it: Single Paged (github here)

But I cannot understand how it's being done. This code within the CSS file is what's making it happen:

{% for c in site.colors %}
.border-{{c[0]}} { border-color: {{ c[1] }} !important; }
.text-{{c[0]}}   { color: {{ c[1] }}; }
.text-{{c[0]}} a { color: {{ c[1] }}; }
.bg-{{c[0]}}     { background-color: {{ c[1] }} !important; }
{% endfor %}

/* ----- per-post colors! ----- */
{% for node in site.posts %}
  {% capture id %}{{ node.id | remove:'/' | downcase }}{% endcapture %}
  {% capture bg %}{% if site.colors[node.bg] %}{{ site.colors[node.bg] }}{% else %}{{ node.bg }}{% endif %}{% endcapture %}
  {% capture fg %}{% if site.colors[node.color] %}{{ site.colors[node.color] }}{% else %}{{ node.color }}{% endif %}{% endcapture %}
  nav .p-{{id}} { border-color: {{ bg }}; }
  #{{id}} { background-color: {{ bg }} !important; color: {{ fg }}; }
  #{{id}} a { color: {{ fg }}; }
  #{{id}} .sectiondivider { color: {{ bg }}; }
{% endfor %}

Is this Liquid within the CSS? Can someone walk me through the code? Thank you!

like image 994
Lia Bogoev Avatar asked Jul 16 '15 18:07

Lia Bogoev


People also ask

How do you use YAML front matter?

YAML frontmatters can be defined at the beginning of a file, by starting on the first line with three dashes ( --- ) and ending the frontmatter either with three dashes or three dots (the former variant is more common). They contain valid YAML and can be used to define arbitrary variables.

Which property is used to apply background color?

The background-color CSS property sets the background color of an element.

What is Jekyll front matter?

Front matter is a snippet of YAML placed between two triple-dashed lines at the start of a file. You can use front matter to set variables for the page: --- my_number: 5 ---


1 Answers

From the _config.yml file for that Jekyll theme:

### template colors, used site-wide via css ###
colors:
  black:     '#111111'
  white:     '#f8f8f8'
  blue:      '#49a7e9'
  green:     '#9bcf2f'
  purple:    '#c869bf'
  orange:    '#fab125'
  turquoise: '#0fbfcf'

We can see that colors is an array of key-values.

Yes, this is Liquid in CSS.

(Remember that one can have Liquid's templating engine process any file in Jekyll by adding YAML frontmatter, which is three dashes, [Enter key], and another three dashes. Without the front matter the file is ignored by the Liquid engine)

Based on the CSS code snippet you've managed to narrow down:

{% for c in site.colors %}
.border-{{c[0]}} { border-color: {{ c[1] }} !important; }
.text-{{c[0]}}   { color: {{ c[1] }}; }
.text-{{c[0]}} a { color: {{ c[1] }}; }
.bg-{{c[0]}}     { background-color: {{ c[1] }} !important; }
{% endfor %}

This is a for-loop that will iterate through all the Key-values in colors array.

An example output for this would be the CSS rule for black - #111111:

.border-black { border-color:  #111111 !important; }
.text-black   { color: #111111; }
.text-black a { color:#111111; }
.bg-black     { background-color: {{ c[1] }} !important; }

Since c is a variable for each color in the colors array, c[0] refers to the 'key' which is black, white, blue etc and c[1] refers to the 'value' which is the RGB codes respectively. You can also do a c[3] if you had another semicolon followed by a value if need be.

This is repeated for all the other colors.

Now for the second snippet of code:

/* ----- per-post colors! ----- */
{% for node in site.posts %}
  {% capture id %}{{ node.id | remove:'/' | downcase }}{% endcapture %}
  {% capture bg %}{% if site.colors[node.bg] %}{{ site.colors[node.bg] }}{% else %}{{ node.bg }}{% endif %}{% endcapture %}
  {% capture fg %}{% if site.colors[node.color] %}{{ site.colors[node.color] }}{% else %}{{ node.color }}{% endif %}{% endcapture %}
  nav .p-{{id}} { border-color: {{ bg }}; }
  #{{id}} { background-color: {{ bg }} !important; color: {{ fg }}; }
  #{{id}} a { color: {{ fg }}; }
  #{{id}} .sectiondivider { color: {{ bg }}; }
{% endfor %}

It's another for-loop that iterates through all the posts in _posts.

All the capture tags you see are liquid syntax to get variables. Using this file as an example:

Notice how the frontmatter is as such:

---
title: "home"
bg: white
color: black
style: center
---

The variables are captured and put into bg, fg respectively. id is taken from a posts.id (I believe this is a special variable in Jekyll), after which the variables are just inserted into where the variables are placed.

The reason it is wrapped inside capture and if statements are to handle cases where posts do not have bg,fg defined (such as when a programmer forgets to define or if they want a custom color, and avoid broken CSS).

For all intents and purposes, just add colors into the _config.yml file using the same format of color and then RGB value, and add custom bg, fg values in each post if you desire. The template will generate all the necessary CSS styles for you.

like image 63
matrixanomaly Avatar answered Nov 16 '22 01:11

matrixanomaly