Skip to content

Instantly share code, notes, and snippets.

@jaandrle
Last active August 15, 2020 10:09
Show Gist options
  • Save jaandrle/ed500ce57e7ca06ab64edbe7ca53a434 to your computer and use it in GitHub Desktop.
Save jaandrle/ed500ce57e7ca06ab64edbe7ca53a434 to your computer and use it in GitHub Desktop.
CSS/Stylus Tips & Tricks

Responsive Web Design: Beyond Media Queries

  • see YouTube
  • fluid-fype (responsive font-size):
    :root{
      --min-font: 16px;
      --max-font: 24px;
      --diff-font: 8; //var(--max-font) - var(--min-font)
      --min-screen: 320px;
      --max-screen: 1280px;
      --diff-screen: 960; //var(--max-screen) - var(--min-screen)
    }
    html{
      font-size: calc(var(--min-font) + var(--diff-font) * (100vw - var(--min-screen)) / val(--diff-screen));
    }
  • flex-shrink, flex-wrap
  • flex-grow-9999-hack

Responsible Tables

  • idea from: Lea Verou > Responsive tables, revisited
  • css example based on cllevents.com
    tr, td, th, thead, tbody, table {
        display: block !important;
        float: none;
    }
    table {
        display: flex !important;
        overflow: hidden;
        border-spacing: 0;
        border-collapse: collapse;
    }
    :root{
      --thead-width: 12em;
    }
    thead {
        --cols: 4;
        --height: calc(2.185em * var(--cols));
        flex-basis: var(--thead-width);
        width: var(--thead-width);
        text-align: right;
        padding-left: 2em;
        text-shadow: 0 var(--height), 0 calc(var(--height) * 2), 0 calc(var(--height) * 3), 0 calc(var(--height) * 4), 0 calc(var(--height) * 5), 0 calc(var(--height) * 6), 0 calc(var(--height) * 7), 0 calc(var(--height) * 8), 0 calc(var(--height) * 9);
    }
    tbody{
        flex-basis: calc(100% - var(--thead-width));
        width: calc(100% - var(--thead-width));
    }
    .table > thead > tr > th, .table > tbody > tr > th{
        width: 100%;
    }
$block-UI-creator(_color1, _color2)
        li
                color _color1
        span
                color _color2

ul li
	color black

$block-UI
	$block-UI-creator(#0fc, #fc0)
.ppp
        @extend $block-UI

.ccc
        @extend $block-UI
	li
		color blue

$block-UI-two
	$block-UI-creator(black, black)

ol li
	color black

.ddd
        @extend $block-UI-two

.eee
        @extend $block-UI-two
	li
		color blue

/* OUTPUT
ul li {
  color: #000;
}
.ppp li,
.ccc li {
  color: #0fc;
}
.ppp span,
.ccc span {
  color: #fc0;
}
li {
  color: #00f;
}
.ddd li,
.eee li {
  color: #000;
}
.ddd span,
.eee span {
  color: #000;
}
ol li {
  color: #000;
}
li {
  color: #00f;
}
*/
<html>
<head>
<style>
* {
--default-primary-color: black;
--box-shadow-x: initial;
--box-shadow-y: initial;
--box-shadow-blur: initial;
--box-shadow-spread: initial;
--box-shadow-color: initial;
--box-shadow-inset: initial;
box-shadow: var(--box-shadow-x,0)
var(--box-shadow-y,0)
var(--box-shadow-blur)
var(--box-shadow-spread,0)
var(--box-shadow-color, currentColor)
var(--box-shadow-inset, );
--border-w: 1px;
--border-style: none;
border-width: var(--border-w);
border-style: var(--border-style, solid);
border-color: var(--border-color, --default-primary-color);
}
::before{
content: var(--before-text, none);
}
div {
--border-style: initial;
--size: 5vw;
width: var(--size);
height: var(--size);
margin: 5em;
transition: all .25s;
}
div:nth-of-type(2){
--size: 15em;
width: var(--size);
height: var(--size);
--mouse-x: 0;
--mouse-y: 0;
background-image: radial-gradient(
at calc(100% * var(--mouse-x)) calc(100% * var(--mouse-y) - 2.5rem),
transparent, black
);
}
div:last-of-type{
--before-text: 'Hi';
--box-shadow-blur: 30px;
--box-shadow-color: red;
}
</style>
</head>
<body>
<div></div><div></div><div></div>
<script>
const els= document.getElementsByTagName("div");
const el= els[0];
console.log(getComputedStyle(el).getPropertyValue("--size"));
//inline style: console.log(el.style.getPropertyValue("--size"));
el.style.setProperty("--size", "10vw");
const el_mouse= els[1];
const el_mouse_rect= el_mouse.getClientRects()[0];
el_mouse.addEventListener("mousemove", ev=>{
console.log(el_mouse_rect.width);
let x= (ev.clientX - el_mouse_rect.left) / el_mouse_rect.width;
let y= (ev.clientY - el_mouse_rect.top) / el_mouse_rect.height;
el_mouse.style.setProperty("--mouse-x", x);
el_mouse.style.setProperty("--mouse-y", y);
});
</script>
</body>
</html>

Hot tips CSS

  • Originally from equinsuocha.io > Hot tips CSS
  • property image-rendering: pixelated;
  • @supports (padding: env(safe-area-inset)) {
      /* Your code for Safari 11+ */
    }
  • empty node :empty, or input/textarea empty :not(:placeholder-shown)
  • property shape-outside: polygon(0 0, 0 200px, 300px 600px);
  • svg as background: background-image: url('data:image/svg+xml;utf8,<svg>...</svg>');
  • disable all user interactions: pointer-events: none;
  • clean and self-contained component:
      my-component {
        all: initial;
        contain: content;
      }
  • overflow snapping:
      my-component {
        scroll-snap-type: mandatory;
        scroll-snap-destination: 50% 50%;
      }
  • system font
      my-component {
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI",
                      Helvetica, Arial, Ubuntu, sans-serif,
                      "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
      }

Even More CSS Secrets (Lea Verou) - mix-blend-mode

  • MDN web docs > mix-blend-mode
  • example
  • <div>
      <div>
        <span>Hello</span>
      </div>
      <div>
        <span>Hello</span>
      </div>
    </div>
    <style>
      div{
        display: block;
        width: 25em;
        height: 25em;
        background: red;
      }
      div > div {
        --size: 50;
        display: flex;
        align-items: center;
        text-align: center;
        background: black;
        color: white;
        width: calc(var(--size,75) * 1%);
        height: calc(var(--size,75) * 1%);
        font-size: calc(var(--size,75) * 11%);
        mix-blend-mode: multiply;
    
      }
      div > div:last-of-type{
        mix-blend-mode: luminosity;
      }
    </style>

Even More CSS Secrets (Lea Verou) - SVG❤CSS

  • SVG as background + see, it is possible to use svg text to use emodgi (another usage like ⭐⭐⭐⭐ rating):
      <div></div>
      <style>
        div{
          display: block;
          width: 25em;
          height: 25em;
          background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><style>@keyframes foo %7B from%7B transform: rotate(-90deg)} to%7B transform: rotate(90deg)}}<\/style><text y="0.5em" x="0.5em" font-size="50" style="transform-origin: 50% 50%; animation: foo 3s infinite">🔅</text></svg>') 2.5em 2.5em / 10em 10em repeat;
          /* multiline must be commented because of mardown :-(
          background: url('data:image/svg+xml,\
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">\
              <style>@keyframes foo %7B from%7B transform: rotate(-90deg)} to%7B transform: rotate(90deg)}}<\/style>\
              <text y="0.5em" x="0.5em" font-size="50" style="transform-origin: 50% 50%; animation: foo 3s infinite">🔅</text>\
            </svg>\
          ') 2.5em 2.5em / 10em 10em repeat;
          */
        }
      </style>
  • Animated border
      <div></div>
      <style>
        div{
          display: block;
          width: 25em;
          height: 25em;
          background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><style>@keyframes foo %7B to%7B stroke-dashoffset: -15px;}}<\/style><rect width="100%" height="100%" style="stroke: black; stroke-width: 4px; fill: none; stroke-dasharray: 10px 5px; animation: foo .4s infinite linear"/></svg>') 100% 100% / auto;}
          /* multiline must be commented because of mardown :-(
          background: url('data:image/svg+xml,\
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">\
              <style>@keyframes foo %7B to%7B stroke-dashoffset: -15px;}}<\/style>\
              <rect width="100%" height="100%" style="stroke: black; stroke-width: 4px; fill: none; stroke-dasharray: 10px 5px; animation: foo .4s infinite linear"/>\
            </svg>\
          ') 100% 100% / auto;}
           */
      </style>
  • Border with linear gradient
      <div></div>
      <style>
        div{
          display: block;
          width: 25em;
          height: 25em;
          background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><linearGradient id="gradientColor" gradientTransform="rotate(45)"><stop stop-color="gold"></stop><stop stop-color="#0ac" offset="1"></stop></linearGradient><rect width="100%" height="100%" style="stroke: url(#gradientColor); stroke-width: 40px; fill: none;"/></svg>') 100% 100% / auto;
          /*
          background: url('data:image/svg+xml,\
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">\
              <linearGradient id="gradientColor" gradientTransform="rotate(45)">\
                <stop stop-color="gold"></stop>\
                <stop stop-color="#0ac" offset="1"></stop>\
              </linearGradient>\
              <rect width="100%" height="100%" style="stroke: url(#gradientColor); stroke-width: 40px; fill: none;"/>\
            </svg>\
          ') 100% 100% / auto;
          */
        }
      </style>

filter: drop-shadow### Even More CSS Secrets (Lea Verou) - Other

  • :before/:after "inherit" flex property header-with-line
  • :focus-within <=> "container focus" / also :target-within
  • Variable fonts, fonts list
  • CSS VARIABLES: another possibility is find "responsive functional dependence" like in Example GRID-VARS > 'div>div' > 'font-size' (not only linear!!!)
  • grid-auto-flow see Example GRID-VARS
  • display: contents specification

    “The element itself does not generate any boxes, but its children and pseudo-elements still generate boxes as normal. For the purposes of box generation and layout, the element must be treated as if it had been replaced with its children and pseudo-elements in the document tree.“

      <form>
        <label>Username: <input name="username"></label>
        <label>Password: <input name="password"></label>
      </form>
      <style>
        form{
           display: grid;
           grid-template-columns: auto 1fr;
           grid-gap: .2em;
        }
        form label{
          display: contents;
        }
      </style>

Example GRID-VARS

  <div>
    <div>
      <span>Hello</span>
    </div>
    <div>
      <span>Hello</span>
    </div>
  </div>
  <style>
    div{
      display: grid;
      grid-template-columns: 1fr 1fr;
      grid-auto-flow: column;/* try remove */
      width: 25em;
      height: 25em;
      background: red;
    }
    div > div {
      grid-column: 2;
      --size: 50;
      display: flex;
      align-items: center;
      text-align: center;
      background: black;
      color: white;
      width: calc(var(--size,75) * 2%);
      height: calc(var(--size,75) * 1%);
      font-size: calc(var(--size,75) * 11%);
      mix-blend-mode: multiply;

    }
    div > div:last-of-type{
      grid-column: 1;
      mix-blend-mode: luminosity;
    }
  </style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment