04 Custom styles - harvardinformatics/informatics-website GitHub Wiki

For the custom HTML portions of the site, like the About page banner, profile cards, Resources page, tag tables, and Software page, we use corresponding custom CSS located in the docs/stylesheets/extra.css file.

A few important styles are described below.

1. The primary color scheme

The main black color (actually #1e1e1e) is set by first setting primary: custom under the palette: section in the configuration file mkdocs.yml. Then, in docs/stylesheets/extra.css, we set the main palette with:

:root {
  --md-primary-fg-color:        #1e1e1e;
  --md-primary-fg-color--light: #ec8f9c;
  --md-primary-fg-color--dark:  #6d1220;
}

Likewise, the light color for links throughout the site is set with:

.md-typeset a {
  color: #EF5552 !important;
}

And the link color in the footer is set with:

.md-footer-meta.md-typeset a {
  color: #ffffff !important;
}

Most other colors follow the default Material theme.

2. The CSS grid

For custom CSS layouts, a grid system is used to space out elements in rows throughout the site. This is specified under the /* Grid */ heading in docs/stylesheets/extra.css.

Briefly, the grid has a class, row, which fills 100% the width of its parent element. Within each row one can then place one or more col-N-24 elements, where N is any integer between 0 and 24. As long as the N's of each element within a row add up to 24, then the content should fit nicely within the width of the row's parent.

For example:


<div class="row">
    <div class="col-2-24"></div>
    <div class="col-8-24"></div>
    <div class="col-4-24"></div>
    <div class="col-8-24"></div>
    <div class="col-2-24"></div>
</div>

This grid is used as the basis for all custom HTML layouts throughout the site.

3. Page Navigation and Table of Contents columns

By default, the Material theme brackets page content with a Navigation column on the left and a Table of Contents column on the right.

Navigation shows the directory structure as links from the current page, while the Table of Contents shows links for each header in the page.

Throughout the site, we have disabled the Navigation column and shifted the Table of Contents to the left side of the content. This is done within the Markdown file of each page (or its template) as follows:

  1. To disable the Navigation column, add this as a header in the Markdown file:
---
hide:
    - navigation
---
  1. To move the Table of Contents to the left, add this CSS snippet just below the header in the Markdown file:
<style>
    .md-sidebar--secondary {
        order: 0;
    }
</style>

4. Banner background image on main page (docs/index.md)

Recall that the main page docs/index.md is generated via a Markdown template, HTML template, and Python script. To change the background image in the banner, one needs to edit the HTML template for the banner: docs/assets/home.html.

The banner is selected randomly from a set of possible images using a small embedded Javascript script at the end of the file:

<script>
    // Array of image paths
    var images = [
        {path: 'img/banners/IMG_1445.jpg', position: 'center 25%'}, 
        {path: 'img/banners/IMG_1867.jpg', position: 'center 15%'},
        {path: 'img/banners/IMG_2171.jpg', position: 'center 13%'},
        {path: 'img/banners/IMG_2177.jpg', position: 'center 70%'},
        {path: 'img/banners/IMG_3075.jpg', position: 'center 48%'},
        {path: 'img/banners/IMG_6113.jpg', position: 'center 75%'},
        {path: 'img/banners/IMG_6203.jpg', position: 'center 50%'},
        {path: 'img/banners/IMG_7402-HDR.jpg', position: 'center 50%'},
        {path: 'img/banners/IMG_7404.jpg', position: 'center 50%'}
    ];
    
    // Generate a random index
    var index = Math.floor(Math.random() * images.length);
    
    // Select an image path
    var image = images[index];
    
    // Set the background image
    var banner = document.querySelector('.banner-row-container');
    banner.style.backgroundImage = 'url(' + image.path + ')';
    banner.style.backgroundPosition = image.position;
</script>

Note the position: 'center N% that has been applied to each image to make it appear nicely. This was done manually by trial and error.

Default background image if JavaScript is disabled

In the case that Javascript is disabled, a default background image is set in the <style> section. Specifically in the .banner-row-container class. To edit the default image, simply edit the path set in the background-image: attribute to another file:

.banner-row-container {
    .
    .
    .
    background-image: url(img/banners/IMG_7404.jpg);
    .
    .
    .
}

5. Responsive styles for varying screen sizes

The Material for mkdocs theme is already mostly responsive and changes styles and content depending on the size of the viewport, however we have made a few changes.

@media tags explained

CSS @media tags are used to conditionally change styles based on the dimensions of the screen or window for specified HTML elements. This allows for responsive web design. These are used frequently in docs/stylesheets/extra.css, so this section gives a general explanation of how they are used, and a few specific examples for the site are provided in the subsequent sections.

For any website element, styles are applied based on its class or id. For example, a div element may be of class example, written in the HTML as:

<div class="example">content</div>

In our stylesheet, we can apply various styles to all elements of this class:

.example {
  width: 80%;
  border: 1px solid black;
  background-color: #ececec;
}

These will be used as the default styles for the example class. If we want to conditionally change these styles based on the dimensions of the screen or window, we can do the following:

@media (max-width:1600px) {
  .example {
    width: 95%;
  }
}

This means that for screens smaller than 1600px, the width: attribute will be changed to 95%, and all elements of class example will take up more screen space (relative to their parent element). The opposite can be achieved using the min-width setting (GWCT: though I generally like to work from bigger screens to smaller ones with the default styles being for the largest screen and the media tags working their way down to smaller screens).

All styles not changed in the @media tag will retain their default settings.

Main content width

The default styles set the main content width to 80%, suitable for large screens. This can be found in docs/stylesheets/extra.css:

.md-main__inner { 
  width: 80% !important;
  max-width: 80% !important;
}

When the viewport shrinks to be smalled than 1600px in width, the content will take up more of the screen:

@media (max-width: 1600px) {
  .md-main__inner {
    width: 95% !important;
    max-width: 95% !important;
  }
}

This is so we maximize our content width and minimize wasted whitespace at the edge of screens, however we do want to prevent content from being too wide on bigger screens.

Other styles for smaller (mobile) screens

Some other styles have media tags for even smaller screens, usually < 1025px, for better viewing on mobile devices. For example:

.software-logo-cont {
  display: flex;
  justify-content: center;
  align-items: center;
}

@media (max-width: 1025px) {
  .software-logo-cont {
    min-height: 10vh;
  }
}

In the case of the example above, elements of class .software-logo-cont will keep their display:, justify-content:, and align-items: rules when the viewport is below 1025px, however a new rule will be applied in addition to those rules that says the minimum height of the element should be 10% of the vertical height of the viewport (min-height: 10vh;).

⚠️ **GitHub.com Fallback** ⚠️