Monsters of Mars
A Complete Novelette
By Edmond Hamemlton
Rest of the content goes here
```
## Remove dependency on jQuery and jQueryDoubleTap
In the first version of the project, I'm more concerned with removing the jQuery dependency. It would probably be easier to work with jQuery but part of the challenge is to make this work with as few dependencies as possible.
A portion of the Javascript file looks like this:
```javascript
function setRootVar(name, value) {
let rootStyles = document.styleSheets[0].cssRules[3].style;
rootStyles.setProperty('--' + name, value);
};
document.addEventListener('DOMContentLoaded', function(e) {
const menuButton = document.getElementById('menuButton');
menuButton.addEventListener('click', function(e) {
setRootVar('menu-visibility', 'show');
}, false);
const roboto = document.getElementById('roboto');
roboto.addEventListener('click', function(e) {
setRootVar('body-font', 'roboto');
setRootVar('body-backup', 'Open Sans');
setRootVar('body-default', 'sans-serif');
});
const source = document.getElementById('source');
source.addEventListener('click', function(e) {
setRootVar('body-font', 'Source Serif');
setRootVar('body-backup', 'Georgia');
setRootVar('body-default', 'serif');
});
});
```
Because we're working with CSS Variables I created a little function that will insert them into the correct rule in the stylesheet. `document.styleSheets[0].cssRules[3].style;` represents the style of the 3rd rule in the first stylesheet of the document. We'll look at that third rule in the SASS/CSS section.
In a future iteration, I'm thinking about replacing the click events with [Pointer Events](https://www.w3.org/TR/pointerevents/) to provide a unified interface for both touch events like those in tablets and the mouse events from our desktop environments.
## Change the CSS to use variables and a :root element
Rather than change each individual item for each individual combination of attributes I have set up a [:root](https://css-tricks.com/almanac/selectors/r/root/) pseudo element with sets of different variables.
The first set (starting with `--roboto`) define Open Type Features of the Roboto font. Combined with CSS classes (not shown) we can enable open type features as needed.
I got the CSS by running the variable font through [Wakamaifondue](https://wakamaifondue.com/).
```scss
:root {
--roboto-c2sc: "c2sc" off;
--roboto-dlig: "dlig" off;
--roboto-dnom: "dnom" off;
--roboto-frac: "frac" off;
--roboto-lnum: "lnum" off;
--roboto-numr: "numr" off;
--roboto-onum: "onum" off;
--roboto-pnum: "pnum" off;
--roboto-salt: "salt" off;
--roboto-smcp: "smcp" off;
--roboto-ss01: "ss01" off;
--roboto-ss02: "ss02" off;
--roboto-ss03: "ss03" off;
--roboto-ss04: "ss04" off;
--roboto-ss05: "ss05" off;
--roboto-ss06: "ss06" off;
--roboto-ss07: "ss07" off;
--roboto-tnum: "tnum" off;
--roboto-unic: "unic" off;
--roboto-cpsp: "cpsp" off;
```
The second block contains all the elements that we can manipulate through Javascript, either individually or in groups.
```scss
// Default Colors
--bright-bg-color: rgba(255, 255, 255, 1);
--bright-txt-color: rgba(0, 0, 0, 1);
// Font and Backup description
--body-font: "Roboto";
--body-backup: "Open Sans";
--body-default: sans-serif;
// Font and line-height related
--font-size: 100%;
--line-height: 1.25;
--body-font-size: 1rem;
// Font styling
--font-weight: "wght" 400;
--font-width: "wdth" 100;
--font-italics: "slnt" 0;
// Width container
--body-width: 40rem;
// Menu Visibil3ty
--menu-visibility: hidden;
// Justify?
// in left to right languages, start is
// equivalent to left
--content-justify: start;
}
```
So how do we use the CSS variables we defined?
If you look at the body declaration below you'll see how we use the variables to set their values as the attributes.
The syntax is `var(--name-of-variable)` the two dashes (`--`) are required by the [specification](https://www.w3.org/TR/css-variables-1/) as a way to avoid conflict with built-in property declarations.
Font-family uses three properties defined earlier to control the font stack. One of the advantages of CSS variables that are not part of SASS or other pre-processors is that changing the value of the variable will immediately cascade down and change the value everywhere it appears in the document.
This is the full declaration in the SCSS file:
```scss
body {
background-color: rgba(255, 255, 255, 1);
color: rgba(0, 0, 0, 1);
font-size: 1rem;
line-height: 1.25;
font-family: Roboto, 'Open Sans', sans-serif;
text-align: left;
-webkit-hyphens: manual;
-ms-hyphens: manual;
hyphens: manual;
transition: all linear 0.2s;
background-color: var(--background-color);
color: var(--text-color);
font-family: var(--body-font),
var(--body-backup),
var(--body-default);
font-size: 1rem;
line-height: var(--line-height);
text-align: var(--content-justify);
-webkit-hyphens: var(--content-hyphenate);
-ms-hyphens: var(--content-hyphenate);
hyphens: var(--content-hyphenate);
}
```
I know it looks scary but it's simply the values hardcoded to default values followed by the same declarations using variables where appropriate. There are a couple items I want to highlight.
I've chosen to use a fixed `1rem` size for the body font so I can keep the size of the menu consistent. If I use the `--font-body-size` variable the menu size will grow along with the text.
If changes are going to be noticeable to the user I've used a short transition to make them less jarring. That's the `transition: all linear 0.2s;` item in the body declaration.
### Media Queries, Font Sizes, and Content Width
One of the few things I didn't like about Bibliotype is that it made the assumption that font size is directly related to reading distance.
I don't think this is the case.
In iBooks, for example, I like to set the font larger regardless of the distance I hold the device from my face as I read.
So how do we handle the combination of width and screen sizes?
The best solution I can come with is to split the problem into two areas. Content width and font sizes.
The content width part is easy and it involves setting the value of the `--body-width` to the desired value and hiding the menu, for now, so the text is easier to read. We will handle this via Javascript.
Media queries will handle device orientation. The basic queries look like this:
```css
@media screen and (orientation: landscape) {
// Content for landscape mode
}
@media screen and (orientation: portrait) {
// Content for portrait mode
}
```
Inside the queries, particularly the landscape query, we can make any adjustments we need to make to keep the reading experience a pleasant one.