Post

CSS Cheatsheet

css and scss code snippets for responsive tables, grids, youtube videos, fluid typography and flexbox.

Simple Responsive Tables

Add horizontal scrollbar

1
2
3
4
5
6
7
table {
    width: 100%;
}
.table-container {
    max-width: 100%;
    overflow-x: scroll;
}

Horizontal tables using data attributes

Hide the table row and add the data-cell value before the table cell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@media (max-width: 650px) {
    th {
    display: none;
    }

    td {
    display: block;
    padding: 0.5rem 1rem;
    }

    td::before {
    content: attr(data-cell) " : "
    font-weight: 700;
    text-transform: capitalize;
    }
}

Responsive Grid with CSS Grid

A really simple way to get a responsive, css grid without media queries, using ‘css grid’.

You wouldnt use this method if you need specific widths for your element. Only use it of your happy to get a fluid width that agjusts to the screen size.

CSS example

Automatically set the min and max size for each column.

1
2
3
4
5
6
.blog-feed__wrapper {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  grid-gap: 20px;
}

See it in action

simple responsive grid using css grid

HTML example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style type="text/css" media="screen">
      .blog-feed__wrapper {
        width: 100%;
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
        grid-gap: 20px;
      }
      h3 {
        color: lime;
      }
      body {
        background-color: black;
      }
    </style>
  </head>
  <body>
    <div class="blog-feed__wrapper">
      <div class="blog-feed__post-item">
        <h3>Hello world!</h3>
        <img src="500.png" width="100%" />
      </div>
      <div class="blog-feed__post-item">
        <h3>Hello world!</h3>
        <img src="500.png" width="100%" />
      </div>
      <div class="blog-feed__post-item">
        <h3>Hello world!</h3>
        <img src="500.png" width="100%" />
      </div>
    </div>
  </body>
</html>

more info

See full video

Responsive Youtube Video

To embed a responsive YouTube video in HTML and apply CSS for responsiveness, you can use the following code. This code will ensure that the video adjusts to the width of its container while maintaining its aspect ratio:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* Container for the video */
.video-container {
  position: relative;
  padding-bottom: 56.25%; /* 16:9 aspect ratio (9 / 16 * 100%) */
  padding-top: 30px;
  height: 0;
  overflow: hidden;
}

/* Responsive iframe */
.video-container iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
1
2
3
4
5
6
7
8
9
<div class="video-container">
  <iframe
    width="560"
    height="315"
    src="https://www.youtube.com/embed/VIDEO_ID"
    frameborder="0"
    allowfullscreen
  ></iframe>
</div>

In this code:

1
2
3
4
5
The video-container div acts as a wrapper for the embedded YouTube video.
The padding-bottom property is set to 56.25% to maintain a 16:9 aspect ratio. You can adjust this value if you want a different aspect ratio.
The padding-top and height properties are set to ensure the container has the correct height to maintain the aspect ratio.
The overflow: hidden property hides any content that overflows the container.
The iframe inside the container takes up 100% of the container's width and height, making the video responsive.

You’ll need to replace “https://www.youtube.com/embed/VIDEO_ID” with the actual YouTube video URL or embed code for the video you want to display. This code will ensure that the video resizes proportionally to the width of its container, making it responsive on different screen sizes.

restrict width

if you want to restrict the width of the video you will need to add a container to the html markup and apply amax-width to that.

1
2
3
4
5
<div class="wrapper">
  <div class="video-container">
    <iframe></iframe>
  </div>
</div>
1
2
3
4
.wrapper {
  margin: 0 auto;
  max-width: rem(807px);
}

Flexbox

Flex Container

  • display: flex | inline-flex
  • flex-direction: row | row-reverse | column | column-reverse
  • flex-wrap: nowrap | wrap | wrap-reverse
  • justify-content: flex-start | flex-end | center | space-between | space-around
  • align-items: flex-start | flex-end | center | baseline | stretch
  • align-content: flex-start | flex-end | center | space-between | space-around | stretch

Flex Items

1
2
3
4
5
6
7
8
9
10
display: flex | inline-flex
flex-direction: row | row-reverse | column | column-reverse
flex-wrap: nowrap | wrap | wrap-reverse
justify-content: flex-start | flex-end | center | space-between | space-around
align-items: flex-start | flex-end | center | baseline | stretch
align-content: flex-start | flex-end | center | space-between | space-around | stretch
Flex Items
order: { index: Number }
flex: { flex-grow: Number } { flex-shrink: Number } { flex-basis } Urls to: flex-grow, flex-shrink, and flex-basis.
align-self: auto | flex-start | flex-end | center | baseline | stretch

Responsive 2 Column using Flexbox

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.row {
  display: flex;
  column-gap: 20px;
  row-gap: 20px;
}

.row .col-6 {
  width: 50%;
}
@media (max-width: 736px) {
  .row {
    flex-direction: column;
  }

  .row .col-6 {
    width: 100%;
  }
}
1
2
3
4
<div class="row">
  <div class="col col-6">//some content</div>
  <div class="col col-6">//some content</div>
</div>

Fonts

Fluid Typography

Fluid typography is where the font-size dynamically change size and line-height according to the viewport width. Fluid typography in CSS refers to the practice of designing text elements with relative units like percentages or viewport units, rather than fixed pixel values. This approach allows the font size to scale smoothly based on the dimensions of the viewport or the parent container. The goal is to create a more adaptable and responsive typographic system. Benefits of fluid typography in user interface design include:

  1. Responsive Design: Fluid typography ensures that text elements adjust proportionally to different screen sizes and devices, providing a consistent reading experience.
  2. Improved Readability: By dynamically adjusting font size based on the available space, fluid typography can enhance readability across various devices, preventing issues like text becoming too small or too large.
  3. Accessibility: Fluid typography supports better accessibility by accommodating users who may need to adjust text size preferences. It aligns with principles of inclusive design.
  4. Consistency: The relative scaling of fonts helps maintain a harmonious visual hierarchy, keeping the relationships between different text elements consistent as the layout adapts.
  5. Future-Proofing: As new devices and screen sizes emerge, fluid typography offers a more future-proof solution compared to fixed font sizes, as it naturally adjusts to different environments.

By embracing fluid typography, designers can create more flexible and user-friendly interfaces that gracefully adapt to the diverse landscape of devices and screen sizes.

Take the following code where we set the font-size of paragraphs to 4% of the viewports width. Although this is lovely and fluid the problem is the fonts get too big and too small as the screen gets larger and smaller. For example, if the browser width is 904px the font size is 36px. Way too big.

1
2
3
p {
  font-size: 4vw;
}

Using Clamp() for fluid typography

Take the following code which uses the css clamp function to set the min(16px) and max(22px) font-size. Furthermore, we through in some calc to multiply the font-size by 1.5 to archive fluid line-height.

1
2
3
4
p {
  font-size: clamp(16px, 4vw, 22px);
  line-height: clamp(calc(16px * 1.5), 4vw, calc(22px * 1.5));
}

Font name mappings

In web design and development, font weights have two methods of reference, numbers and names. Below is a list of common ways to map the number to the name.

  • 100 - Thin (Hairline)
  • 200 - Extra Light (Ultra Light)
  • 300 - Light
  • 400 - Normal (Regular)
  • 500 - Medium
  • 600 - Semi Bold (Demi Bold)
  • 700 - Bold
  • 800 - Extra Bold (Ultra Bold)
  • 900 - Black (Heavy)
  • 950 - Extra Black (Ultra Black)

Display Background Image Outside of Container With CSS

If you’re just using a regular background image applied to the section of a block. Your background images will get cut off based on the container width and height. We get around this problem by using a pseudo after class with position absolute.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.tabs-group {
 margin: 30px 0;
  position: relative;
  z-index: 10;
  &:after {
    content: " ";
    display: block;
    width: 250px;
    height: 200px;
    position: absolute;
    top: -90px;
    background-image: url("../../src/assets/backgrounds/my_image.png");
    left: 0;
    z-index: -10;
  }

BEM

Know your element (__) from your modifier (--). Both blocks and elements can have modifiers. (.b--m, .b__e--m). In react lingo, BEM’s “B” (for “Block”) is a component. Elements can nest deep in html, but the selector doesn’t represent this deep nesting. (no .a__b__c, instead just .a__c - which can be in .a__b).

The idea

The idea with BEM is to keep a flat hierarchy (don’t nest selectors) with simple selectors - only one class per selector, and no IDs or element tags. By not nesting we have a low and consistent specificity of all html elements, which makes it possible to have modifications of styles without using !important. Don’t ever use the html element as well as a class in the selector for this same reason (no button.button), as well as not to lock oneself into having to use a specific type of element. Only time nesting of selectors is allowed is if elements need changing when the block has a modifier class applied to it (.editor--dark .editor__text {color: white} for example). Use of html element selectors can be used at times, for example in the case of the flag above, where we need to wrap the img in an element for styling, but might still want to apply styles to the img without having another class (.flag__actual-image is a bit ugly). But try to keep it to a minimum, and don’t have “magic” elements, where (for example) a span in a .media gets grey text and centered (give it a name instead, .media__caption maybe?). Since we scope every element and modifier, we are free to use whatever names we want - no risk of clashes between the icon called danger and the button style called danger.

Example:

Notice the two buttons which are both elements of the editor, as well as blocks in their own right, in two different ways. Also, note that there are two navs, but one would be stuck to the top (--top) and the other bottom, but they are both nav bars of the editor, and so share most styles (different variants/modifications of the same element). Lastly, notice the use of icon--remove even though we don’t have icon. Since we don’t nest our selectors it’s possible to “borrow” modifiers (and elements) from blocks without applying the full block styles. In this case icon--remove sets the content of the :before pseudo element to the right icon, but doesn’t apply any base icon styles, something .icon does but a button doesn’t need. If we combined classes when making selectors .icon.icon--remove this wouldn’t be possible, only thanks to the flat hierarchy with simple selectors is this possible.

1
2
3
4
5
6
7
8
9
10
11
12
<div class="editor editor--dark-mode">
  <div class="editor__nav editor__nav--top">
    <input class="editor__filename" type="text" />
    <button class="editor__button btn btn--danger btn--icon icon--remove">Move to trash</button>
  </div>
  <div class="editor__body">
    ...
  </div>
  <div class="editor__nav editor__nav--bottom">
    <button class="editor__button btn btn--primary btn--icon icon--save">Save</button>
  </div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.flag {}

.flag__image,
.flag__body {}

.flag--top .flag__image,
.flag--top .flag__body {}

.flag--bottom .flag__image,
.flag--bottom .flag__body {}

.flag__image {}

.flag__image > img {}

.flag__body {}
1
2
3
4
5
6
7
8
9
<div class="flag flag--top">
	<div class="flag__image">
		<img src="{author.img}" width="55">
	</div>
	<div class="flag__body">
		<span class="block smallcaps txt grey delta">Words By</span>
		<strong>{author.name}</strong>
	</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.flag {
  display: table;
  &__image,
  &__body {
    display: table-cell;
    vertical-align: middle;

    .flag--top & {
      vertical-align: top;
    }
    .flag--bottom & {
      vertical-align: bottom;
    }
  }
  &__image {
    padding-right: $margin / 2;
    > img {
      display: block;
      max-width: none;
    }
  }
  &__body {
    width: 100%;
  }
}
This post is licensed under CC BY 4.0 by the author.