(I make websites.)
* Okay Maybe You Know About Some Of This, I Don't Know... I Don't Know What Blogs You Read.
* Okay Maybe You Know About Some Of This, I Don't Know... I Don't Know What Blogs You Read. So Maybe Some Of This Is Familiar, But I Bet Not All Of It. Look: The Point Is I'm Going To Show You Some Features In Modern CSS, And It's Highly Likely Some Of This Information Is New.
* Okay Maybe You Know About Some Of This, I Don't Know... I Don't Know What Blogs You Read. So Maybe Some Of This Is Familiar, But I Bet Not All Of It. Look: The Point Is I'm Going To Show You Some Features In Modern CSS, And It's Highly Likely Some Of This Information Is New. But Either Way You're Going To Learn Some New Stuff About CSS Or At Least We'll Have Fun Together And That's Okay Too.
variables
Sass
for about 20 years...$white: #eee;
$black: #313131;
$orange: #e98741;
$red: #ee2a2a;
$white: #eee;
$black: #313131;
$orange: #e98741;
$red: #ee2a2a;
main {
background:$white;
color:$black;
}
button {
background: $orange;
color: $white;
}
$white: #eee;
$black: #313131;
$orange: #e98741;
$red: #ee2a2a;
main {
background:$white;
color:$black;
}
button {
background: $orange;
color: $white;
}
button.warning {
background: $black;
color: $red;
}
$white: #eee;
$black: #313131;
$orange: #e98741;
$red: #ee2a2a;
$background-color: $white;
$text-color: $black;
$link-color: $orange;
$warning-color: $red;
main {
background: $background-color;
color: $text-color;
}
button {
background: $link-color;
color: $background-color;
}
button.warning {
background: $text-color;
color: $warning-color;
}
CSS
...:root {
--white: #eee;
--black: #313131;
--orange: #e98741;
--red: #ee2a2a;
}
:root {
--white: #eee;
--black: #313131;
--orange: #e98741;
--red: #ee2a2a;
}
main {
background: var(--white);
color: var(--black);
}
button {
background: var(--orange);
color: var(--white);
}
:root {
--white: #eee;
--black: #313131;
--orange: #e98741;
--red: #ee2a2a;
--body-color: var(--white);
--text-color: var(--black);
--link-color: var(--orange);
--warning-color: var(--red);
}
main {
background-color: var(--body-color);
color: var(--text-color);
}
button {
background-color: var(--link-color);
}
button {
background-color: var(--button-bg);
color: var(--button-fg);
border-color: var(--button-border-color);
font-size: var(--button-font-size);
}
button.secondary {
--button-bg: var(--light-grey);
}
button.warning {
--button-bg: var(--warning-color);
--button-fg: var(--black);
}
button.transparent {
--button-bg: transparent;
}
button.huge {
--button-font-size: 2rem;
}
:root {
--background-color: #ffffff;
--text-color: #000000;
--primary-color: #1e7e34;
--secondary-color: #4cae4c;
}
[data-scheme="warm"] {
--primary-color: #b3542e;
--secondary-color: #a12e2b;
button {
--text-color: #eee;
}
}
[data-scheme="cool"] {
--primary-color: #17a2b8;
--secondary-color: #5bc0de;
}
[data-scheme="grayscale"] {
--primary-color: #808080;
--secondary-color: #a9a9a9;
}
[data-theme="dark"] {
--background-color: #343a40;
--text-color: #f8f9fa;
}
[data-theme="dark"][data-scheme="warm"] {
--primary-color: #ff7f50;
--secondary-color: #ff6347;
button {
--text-color: #111;
}
}
[data-theme="dark"][data-scheme="cool"] {
--primary-color: #1ba5b8;
--secondary-color: #5fc8d4;
}
[data-theme="dark"][data-scheme="grayscale"] {
--primary-color: #b0b0b0;
--secondary-color: #bcbcbc;
button {
--text-color: #222;
}
}
:root {
--background-color: #ffffff;
--text-color: #000000;
--primary-color: #1e7e34;
--secondary-color: #4cae4c;
}
[data-scheme="warm"] {
--primary-color: #b3542e;
--secondary-color: #a12e2b;
button {
--text-color: #eee;
}
}
[data-scheme="cool"] {
--primary-color: #17a2b8;
--secondary-color: #5bc0de;
}
[data-scheme="grayscale"] {
--primary-color: #808080;
--secondary-color: #a9a9a9;
}
[data-theme="dark"] {
--background-color: #343a40;
--text-color: #f8f9fa;
}
[data-theme="dark"][data-scheme="warm"] {
--primary-color: #ff7f50;
--secondary-color: #ff6347;
button {
--text-color: #111;
}
}
[data-theme="dark"][data-scheme="cool"] {
--primary-color: #1ba5b8;
--secondary-color: #5fc8d4;
}
[data-theme="dark"][data-scheme="grayscale"] {
--primary-color: #b0b0b0;
--secondary-color: #bcbcbc;
button {
--text-color: #222;
}
}
body {
background-color: var(--background-color);
color: var(--text-color);
}
button {
background-color: var(--primary-color);
color: var(--text-color);
border: 0.2em solid var(--secondary-color);
transition: all 0.3s linear;
}
button:hover, button:focus-visible {
background-color: var(--secondary-color);
color: var(--background-color);
border: 0.2em solid var(--primary-color);
}
a[href] {
color: var(--primary-color);
text-decoration: none;
transition: color 0.3s ease;
}
a[href]:hover, a[href]:focus-visible {
color: var(--secondary-color);
text-decoration: underline;
}
nesting
Scss
.card {
display: flex;
flex-direction: column;
padding: 1rem;
background-color: #f8f9fa;
h3 {
font-size: 1.5rem;
margin-bottom: 0.5rem;
}
p {
font-size: 1rem;
color: #6c757d;
a {
color: #007bff;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
.actions {
margin-top: 1rem;
display: flex;
gap: 0.5rem;
button {
padding: 0.5rem 1rem;
border: none;
cursor: pointer;
&.primary {
background-color: #007bff;
color: #fff;
}
&.secondary {
background-color: #6c757d;
color: #fff;
}
}
}
}
CSS
.card {
display: flex;
flex-direction: column;
padding: 1rem;
background-color: #f8f9fa;
h3 {
font-size: 1.5rem;
margin-bottom: 0.5rem;
}
p {
font-size: 1rem;
color: #6c757d;
a {
color: #007bff;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
.actions {
margin-top: 1rem;
display: flex;
gap: 0.5rem;
button {
padding: 0.5rem 1rem;
border: none;
cursor: pointer;
&.primary {
background-color: #007bff;
color: #fff;
}
&.secondary {
background-color: #6c757d;
color: #fff;
}
}
}
}
Scss Differences
// SCSS uses // for comments, which is not valid in CSS.
$dark-color: #323232;
$primary-color: #007bff;
$secondary-color: #6c757d;
.block {
display:block;
// .block { display:block; }
&-element {
padding: 1em;
// .block-element { padding:1em; }
&--modifier {
color: $primary-color;
// .block-element-modifier { color:#007bff }
}
}
}
div {
.grid& {
display:grid;
// .griddiv { display:grid; }
}
}
.foo, #bar {
.baz {
background-color: $secondary-color;
// .foo .baz,
// #bar .baz { background-color:#6c757d; }
}
}
.call-to-action .heading {
.dark-theme & {
background: $dark-color;
// .dark-theme .call-to-action .heading { background: #323232 }
}
}
.brother {
~ .brother {
font-style:italic;
}
& ~ .sister {
font-style:italic;
}
// .brother ~ .brother,
// .brother ~ .sister { font-style-italic; }
// (the initial & is optional)
}
CSS Differences
/* CSS uses wrapped /* for comments, which is valid in both CSS and SCSS. */
:root {
--dark-color: #313131;
--primary-color: #007bff;
--secondary-color: #6c757d;
}
.block {
display:block;
/* .block { display:block; } */
&-element {
padding: 1em;
/* -element.block { padding:1em; } */
&--modifier {
color: var(--primary-color);
/* ❌ invalid syntax */
}
}
}
div {
.grid& {
display:grid;
/* div.grid { display:grid; } */
}
}
.foo, #bar {
.baz {
background-color: var(--secondary-color);
/* :is(.foo, #bar) .baz { background-color:#6c757d; } */
}
}
.call-to-action .heading {
.dark-theme & {
background: $dark-color;
/* .dark-theme :is(.call-to-action .heading) */
}
}
.brother {
~ .brother {
font-style:italic;
}
& ~ .sister {
font-style:italic;
}
/* (❌ Invalid syntax - .brother ~ .brother needed the &) */
/* .brother ~ .sister { font-style-italic; } */
}
HTML Family Tree
Scss Family Tree
.parent {
> .child {} // .parent > .child
& > .child { // .parent > .child
&.brother { // .parent > .child.brother
~ .brother {} // .parent > .child ~ .brother
& ~ .brother {} // .parent > .child ~ .brother
& + .sister {} // .parent > .child.brother + .sister
+ .sister {} // .parent > .child + .sister
}
&.sister { // .parent > .child.sister
~ .brother {} // .parent > .child.sister ~ .brother
& ~ .brother {} // .parent > .child.sister ~ .brother
& + .sister {} // .parent > .child.sister + .sister
+ .sister {} // .parent > .child + .sister
}
& > .grandchild {} // .parent > .child > .grandchild
.grandchild {} // .parent > .child .grandchild
}
}
CSS Family Tree
.parent {
> .child {} /* ❌ Invalid — combinator requires & */
& > .child { /* .parent > .child */
&.brother { /* .parent > .child.brother */
~ .brother {} /* ❌ Invalid — combinator requires & */
& ~ .brother {} /* .parent > .child ~ .brother */
& + .sister {} /* .parent > .child.brother + .sister */
+ .sister {} /* ❌ Invalid — combinator requires & */
}
&.sister { /* .parent > .child.sister */
~ .brother {} /* ❌ Invalid — combinator requires & */
& ~ .brother {} /* .parent > .child.sister ~ .brother */
& + .sister {} /* .parent > .child.sister + .sister */
+ .sister {} /* ❌ Invalid — combinator requires & */
}
& > .grandchild {} /* .parent > .child > .grandchild */
.grandchild {} /* .parent > .child .grandchild */
}
}
field-sizing
input,
textarea,
select {
padding:0.5em 1em;
min-width: 7em;
max-width:100%;
}
input,
textarea,
select {
padding:0.5em 1em;
min-width: 7em;
max-width:100%;
field-sizing: content;
}
container queries
HTML
...
...
...
...
...
CSS
.grid {
display: grid;
gap: var(--gap);
&[columns="3"] {
grid-template-columns: repeat(3, 1fr);
}
&[columns="2"] {
grid-template-columns: repeat(2, 1fr);
}
}
Responsive CSS w/ @media queries
@media (max-width: 940px) {
.grid[columns="3"] {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 700px) {
.grid[columns="2"] {
grid-template-columns: repeat(1, 1fr);
}
}
@media (max-width: 620px) {
.grid[columns="3"] {
grid-template-columns: repeat(1, 1fr);
}
}
@media queries
@media (max-width: 940px) {
.grid[columns="3"] {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 700px) {
.grid[columns="2"] {
grid-template-columns: repeat(1, 1fr);
}
}
@media (max-width: 620px) {
.grid[columns="3"] {
grid-template-columns: repeat(1, 1fr);
}
}
@container queries
.content {
container-type: inline-size;
.grid[columns="2"] {
@container (max-width: 560px) {
grid-template-columns: 1fr;
}
}
.grid[columns="3"] {
@container (max-width: 600px) {
grid-template-columns: repeat(2, 1fr);
}
@container (max-width: 400px) {
grid-template-columns: repeat(1, 1fr);
}
}
}
.ads {
container-type: inline-size;
.grid[columns="2"] {
@container (max-width: 340px) {
grid-template-columns: 1fr;
}
}
}
let's make this fancier...
.content {
container-type: inline-size;
.grid[columns="2"] {
@container (max-width: 560px) {
grid-template-columns: 1fr;
}
}
.grid[columns="3"] {
@container (max-width: 600px) {
grid-template-columns: repeat(2, 1fr);
}
@container (max-width: 400px) {
grid-template-columns: repeat(1, 1fr);
}
}
}
.ads {
container-type: inline-size;
.grid[columns="2"] {
@container (max-width: 340px) {
grid-template-columns: 1fr;
}
}
}
...with named @container queries
.content {
container-type: inline-size;
container-name: content-container;
.grid[columns="2"] {
@container content-container (max-width: 560px) {
grid-template-columns: 1fr;
}
}
.grid[columns="3"] {
@container content-container (max-width: 600px) {
grid-template-columns: repeat(2, 1fr);
}
@container content-container (max-width: 400px) {
grid-template-columns: repeat(1, 1fr);
}
}
}
.ads {
container-type: inline-size;
container-name: stupid-ads;
.grid[columns="2"] {
@container stupid-ads (max-width: 340px) {
grid-template-columns: 1fr;
}
}
}
height:auto
Let's build an accordion!
HTML
-
-
...
-
Question #2
-
...
-
Question #2
-
...
Javascript
document.addEventListener("click", (event) => {
if (event.target.matches("button[aria-controls]")) {
const button = event.target;
const content = button.closest("dt").nextElementSibling;
// Remove 'active' class and set aria-expanded to false for all buttons
document.querySelectorAll("button[aria-controls]").forEach((btn) => {
if (btn !== button) {
btn.classList.remove("active");
btn.setAttribute("aria-expanded", "false");
}
});
// Remove 'visible' class from all content elements
document.querySelectorAll('[role="region"]').forEach((item) => {
if (item !== content) {
item.classList.remove("visible");
}
});
// Toggle the clicked button and its corresponding content
const isActive = button.classList.toggle("active");
button.setAttribute("aria-expanded", isActive ? "true" : "false");
if (content && content.matches('[role="region"]')) {
content.classList.toggle("visible");
}
}
});
HTML w/ JS
-
-
...
-
-
...
-
-
...
HTML w/ JS
-
-
...
-
-
...
-
-
...
CSS, attempt #1
dl {
dd {
overflow:hidden;
}
&[example-number="1"] {
dd {
height: 0;
&.visible {
height: auto;
}
}
}
}
Let's animate this!
dl {
dd {
overflow:hidden;
height: 0;
&.visible {
height: auto;
}
}
}
simple enough, right?
dl {
dd {
overflow:hidden;
height: 0;
transition: height 2s ease-out;
&.visible {
height: auto;
}
}
}
:(
dl {
dd {
overflow:hidden;
height: 0;
transition: height 2s ease-out;
&.visible {
height: auto;
}
}
}
dl {
dd {
overflow:hidden;
height: 0;
transition: height 2s ease-out;
&.visible {
height: 300px;
}
}
}
dl {
dd {
display:grid;
grid-template-rows: 1fr
}
}
dl {
dd {
display:grid;
grid-template-rows: 1fr;
}
}
1fr = 1 fraction
/* All of these are valid */
dd {
grid-template-columns: 1fr;
grid-template-rows: 1fr 1fr;
grid-template-rows: repeat(4,1fr);
grid-template-columns: 20% 1fr;
grid-template-rows: 210px 1fr 2rem;
}
/* All of these are valid */
dd {
grid-template-columns: 1fr;
grid-template-rows: 1fr 1fr;
grid-template-rows: repeat(4,1fr);
grid-template-columns: 20% 1fr;
grid-template-rows: 210px 1fr 2rem;
grid-template-colummns: 0fr;
grid-template-rows: 0fr;
/* 👆 yes, those too! */
/* and you can animate any of these! */
}
dl {
dd {
display:grid;
grid-template-rows: 0fr;
}
}
dl {
dd {
display:grid;
grid-template-rows: 0fr;
transition: grid-template-rows 2s ease-out;
&.visible {
grid-template-rows: 1fr;
}
}
}
/* Okay, we also have to do this... */
dl {
dd {
display:grid;
grid-template-rows: 0fr;
transition: grid-template-rows 2s ease-out;
.inside {
visibility: hidden;
}
&.visible {
grid-template-rows: 1fr;
.inside {
visibility: hidden;
}
}
}
}
calc-size()
Let's go back to our first example
dl {
dd {
height: 0;
transition: height 2s ease-out;
&.visible {
height: auto;
}
}
}
One tiny change...
dl {
dd {
height: 0;
transition: height 2s ease-out;
&.visible {
height: calc-size(auto, size);
}
}
}
@starting-style
HTML
...
CSS
.container {
position: relative;
}
.hamburger-menu {
position: absolute;
top: var(--topnav-height);
right: 0;
width: 100%;
max-width: var(--maxburger);
background-color: $black;
/* etc */
}
Javascript
const hamburgerMenu = document.querySelector("#HamburgerMenu");
const toggleButton = document.querySelector("#ToggleHamburgerMenu");
toggleButton.addEventListener("click", () => {
const isExpanded = toggleButton.getAttribute("aria-expanded") === "true";
toggleButton.setAttribute("aria-expanded", !isExpanded);
hamburgerMenu.classList.toggle("visible");
});
hidden
...
visible
...
CSS
.hamburger-menu {
position: absolute;
top: var(--topnav-height);
right: 0;
width: 100%;
max-width: var(--maxburger);
background-color: $black;
}
CSS w/ transition
.hamburger-menu {
position: absolute;
top: var(--topnav-height);
right: 0;
width: 100%;
max-width: var(--maxburger);
background-color: $black;
transform: translateX(100%);
transition: transform 2s ease-out;
&.visible {
transform: translateX(0)
}
}
@starting-style
CSS w/ transition
.hamburger-menu {
position: absolute;
top: var(--topnav-height);
right: 0;
width: 100%;
max-width: var(--maxburger);
background-color: $black;
transform: translateX(100%);
transition: transform 2s ease-out;
&.visible {
transform: translateX(0)
}
}
CSS w/ @starting-style
.hamburger-menu {
position: absolute;
top: var(--topnav-height);
right: 0;
width: 100%;
max-width: var(--maxburger);
background-color: $black;
transform: translateX(100%);
transition: transform 2s ease-out;
&.visible {
transform: translateX(0)
}
@starting-style {
transform: translateX(100%);
}
}
animation-timeline: view()
HTML
-
-
-
-
...
ul {
display: grid;
grid-template-columns: repeat(2,1fr);
gap: 0 var(--vertical-gap);
}
li {
list-style:none;
&:nth-child (even) {
margin-top: var(--horizontal-gap);
}
&:nth-child (odd) {
margin-top: var(--negative-horizontal-gap);
}
}
‼️ We need this to animate!
Okay, sure.
How would you like it to look?
Make it look friggin' COOL!!! ✨😎💎💯🔥🤯🤩🎸⚡️🌀
CSS (Before)
ul {
display: grid;
grid-template-columns: repeat(2,1fr);
gap: 0 var(--vertical-gap);
}
li {
list-style:none;
&:nth-child (even) {
margin-top: var(--horizontal-gap);
}
&:nth-child (odd) {
margin-top: var(--negative-horizontal-gap);
}
}
CSS (After)
ul {
display: grid;
grid-template-columns: repeat(2,1fr);
gap: 0 var(--vertical-gap);
}
li {
list-style:none;
&:nth-child (even) {
margin-top: var(--horizontal-gap);
}
&:nth-child (odd) {
margin-top: var(--negative-horizontal-gap);
}
}
@keyframes appear {
from {
opacity: 0;
scale: 0.25;
transform: translateY(100%);
}
to {
opacity: 1;
scale: 1;
transform: translateY(0);
}
}
img {
animation: appear linear;
animation-timeline: view();
animation-range: entry 0 cover 35%;
}
Let's see what the designer thinks...
OMG YES! MORE! 🤸♀️🥳🎊✨🎉🍾🥂🕺💃🌟🔥
Uhhhhhhhhh.... Okay, sure.
CSS (Before)
@keyframes appear {
from {
opacity: 0;
scale: 0.25;
transform: translateY(100%);
}
to {
opacity: 1;
scale: 1;
transform: translateY(0);
}
}
img {
animation: appear linear;
animation-timeline: view();
animation-range: entry 0 cover 35%;
}
CSS (After)
@keyframes appear {
from {
opacity: 0;
scale: 0.25;
transform: translateY(100%);
}
to {
opacity: 1;
scale: 1;
transform: translateY(0);
}
}
@keyframes disappear {
from {
opacity: 1;
scale: 1;
transform: translateY(0);
}
to {
opacity: 0;
scale: 0.25;
transform: translateY(-100%);
}
}
img {
animation: appear linear;
animation-timeline: view();
animation-range: entry 0 cover 45%;
}
li:has(img) {
animation: disappear linear forwards;
animation-timeline: view();
animation-range: exit 0 exit 45%;
}
So... That's a lot...
CSS (Before)
img {
animation: appear linear;
animation-timeline: view();
animation-range: entry 0 cover 45%;
}
li:has(img) {
animation: disappear linear forwards;
animation-timeline: view();
animation-range: exit 0 exit 45%;
}
CSS (After)
@media (prefers-reduced-motion: no-preference) {
img {
animation: appear linear;
animation-timeline: view();
animation-range: entry 0 cover 45%;
}
li:has(img) {
animation: disappear linear forwards;
animation-timeline: view();
animation-range: exit 0 exit 45%;
}
}
:has()!
My favorite CSS QoL improvement since grid
Select any descendent
.target-person .person { }
Select direct descendent
.target-person > .person { }
Select next sibling
.target-person + .person { }
Select siblings *
.target-person ~ .person { }
* assuming that sibling comes later in the order
.target-person ~ .person { }
But we can't do this...
.target-person < .person { }
has()
!So, let's make some cards...
{{Product Title}}
{{product.description}}
{{Product Title}}
{{product.description}}
And let's style them differently...
.card-conainer {
display: flex;
flex-direction: column;
background: var(--no-image-bg);
}
.card-container .description {
display:flex;
flex-grow:1;
justify-content: center;
align-items: center;
}
.card-container:has(img) {
border: var(--has-image-border);
box-shadow: var(--has-image-shadow);
background-color: var(--has-image-bg);
}
Okay, let's build a form!
And let's style it with :has() !!!
fieldset:has([required]) {
label {
&:after {
content: "*";
color: var(--red);
}
}
}
fieldset:has(:focus) {
label { color:var(--blue); }
input,
textarea,
select {
border-color: var(--blue);
color: var(--blue);
}
}
fieldset:has(input[required]:invalid) {
border-color: var(--red);
label {
color: var(--red);
}
}
fieldset:has(select[required]:invalid) {
border-color: var(--red);
label {
color: var(--red);
}
}
Hooray! Another grid!!!
...
...
...
.grid[columns="3"] {
display:grid;
gap: var(---gap);
grid-template:repeat(3,1fr)
}
IS THAT A WIDOW!!!????????
.grid[columns="3"] {
display:grid;
gap: var(---gap);
grid-template:repeat(3,1fr)
}
/* Option 1... */
.grid:has(.box:nth-child(4)) {
grid-template-columns: repeat(2,1fr)
}
.grid[columns="3"] {
display:grid;
gap: var(---gap);
grid-template:repeat(3,1fr)
}
/* Option 2... */
.grid:has(.box:nth-child(4)) {
display:flex;
flex-wrap: wrap;
justify-content: center;
}
.grid:has(.box:nth-child(4)) .box {
flex-basis:33.333%;
max-width: calc(33.333% - var(--halfGap));
}
:not()
We'll make this quick..
Some examples:
a:not([target="_blank"]) {
/*
Do something to any links that don't open in a new tab.
*/
}
input:not([disabled]):not([readonly]) {
/*
Do something to inputs which are editable,
meaning they're not marked as disabled or readonly.
*/
}
.content p:not(:first-of-type) {
/*
Do something to all paragraphs after the 1st one.
*/
}
.topnav li a:not([aria-current="page"]) {
/*
Add some link styles to any link that doesn't go to this page.
*/
}
.card:not(.featured) a {
/*
Do something to any link in non-featured cards.
*/
}
text-wrap
.default {
/* text-wrap:wrap is the default */
}
.pretty {
text-wrap: pretty;
}
.balanced {
text-wrap: balanced;
}
@layer
dark-light()
@property
scrollbar
::first-letter
@layer
@layer red {
p { color: red; }
}
@layer green {
p { color: green; }
}
@layer blue {
p { color: blue; }
}
@layer blue, green, red;
/*
RESULT: p { color: red; }
*/
dark-light()
:root {
--text-color: dark-light(black, white)
--bg-color: dark-light(white, black);
--accent-color: dark-light(purple, lightblue);
}
body {
color: var(--text-color);
background-color: var(--bg-color);
}
button {
background-color: var(--accent-color);
color: var(--bg-color);
}
property()
@property --color-start {
syntax: '<color>';
initial-value: blue;
}
@property --size-multiplier {
syntax: '<number>';
initial-value: 1;
}
.my-element {
background-color: var(--color-start);
width: calc(100px * var(--size-multiplier));
}
.scrollable {
scrollbar-width: thin;
scrollbar-color: gold silver; /* Gold thumb, silver track */
}
.scrollable {
scrollbar-width: thin;
scrollbar-color: gold silver; /* Gold thumb, silver track */
}
/*
Okay, you're gonna need a bunch of vender-prefix crap...
*/
.scrollable {
&::-webkit-scrollbar {
width: 10px;
height: 10px;
background-color: transparent;
}
&::-webkit-scrollbar-track {
/* The main background of the scrollbar area */
background: silver;
border-radius: 5px;
}
&::-webkit-scrollbar-thumb {
/* The draggable part of the scrollbar */
background-color: gold;
border-radius: 5px;
border: 2px solid silver;
}
&::-webkit-scrollbar-thumb:hover {
background-color: darkgoldenrod;
}
&::-webkit-scrollbar-corner {
/* Keeping a light gray for the corner */
background-color: lightgray;
}
}
::first-letter
p {
color: var(--color-normal);
font-family: var(--font-normal);
&:first-letter {
initial-letter: 4 3; /* height width */
color: var(--color-silly);
font-family: var(--font-silly);
}
}
lemon@ahoylemon.xyz | |
@ahoylemon.xyz | |
@ahoylemon@mastodon.social | |
sessionize.com/lemon | |
github.com/AhoyLemon |