Alle demoer virker i Chrome Canary
@layer theme {
html {
--color: oklch(80% 2 220);
}
* {
text-box-trim: both;
text-box-edge: cap alphabetic;
}
}
@layer component {
div {
margin-trim: block;
padding: 2rlh;
:is(article):has(&) {
--rainbow-gradient: in oklch longer hue, red 0 0;
padding-inline: max(1rem, (100% - 800px) / 2);
background: linear-gradient(45deg var(--rainbow-gradient));
container: div / inline-size;
}
:is(article) & {
border: 2px solid color(display-p3 1 none 1);
background: oklch(80% .37 220 / 25%);
@container div (inline-size > 35rem) {
font-size: calc(1rem * pow(1.25, 1));
}
}
:is(aside) {
container: aside / sticky;
position: sticky;
inset-block-start: 0;
@container aside state(stuck) {
& h2 {
background: red;
}
}
}
:is(h2, h3) {
inline-size: 17ch;
text-wrap: balance;
}
> h2 {
background: hsl(from var(--color) h s calc(l + 10%));
}
:not(article) & :nth-child(2 of .paragraph) {
&:first-letter {
initial-letter: 3;
margin-inline-end: 1ch;
}
}
& section {
max-inline-size: 400px;
> p {
text-wrap: pretty;
}
}
}
}
@layer theme {
html {
--color: oklch(80% 2 220);
}
* {
text-box-trim: both;
text-box-edge: cap alphabetic;
}
}
@layer component {
div {
margin-trim: block;
padding: 2rlh;
:is(article):has(&) {
--rainbow-gradient: in oklch longer hue, red 0 0;
padding-inline: max(1rem, (100% - 800px) / 2);
background: linear-gradient(45deg var(--rainbow-gradient));
container: div / inline-size;
}
:is(article) & {
border: 2px solid color(display-p3 1 none 1);
background: oklch(80% .37 220 / 25%);
@container div (inline-size > 35rem) {
font-size: calc(1rem * pow(1.25, 1));
}
}
:is(aside) {
container: aside / sticky;
position: sticky;
inset-block-start: 0;
@container aside state(stuck) {
& h2 {
background: red;
}
}
}
:is(h2, h3) {
inline-size: 17ch;
text-wrap: balance;
}
> h2 {
background: hsl(from var(--color) h s calc(l + 10%));
}
:not(article) & :nth-child(2 of .paragraph) {
&:first-letter {
initial-letter: 3;
margin-inline-end: 1ch;
}
}
& section {
max-inline-size: 400px;
> p {
text-wrap: pretty;
}
}
}
}
Det ligner CSS, men det føles som et nyt sprog
— "CSS4" måske?
2012 - 2017
Intrinsic web
2017 -
Intrinsic web
2017 -
2023 -
Intrinsic web
Robust, pålidelig og fleksibel
meget snart!
section {
border: 2px solid red;
color: red;
}
}
h2 {
section {
border: 2px solid red;
color: red;
}
}
&
h2 {
section {
border: 2px solid red;
color: red;
}
}
>
h2 {
section {
border: 2px solid red;
color: red;
}
}
:is( )
h2 {
✅
Hoisted
.feature-list {
display: grid;
grid: "stack";
:is(img, ul) {
grid-area: stack;
}
> ul {
z-index: 1;
place-self: center start;
> li {
animation: opacity linear both;
animation-timeline: view();
&:hover {
opacity: .8;
}
}
}
}
article {
padding: 1rem;
background: aliceblue;
color: darkslateblue;
:nth-child(even) > & {
color: aliceblue;
background: darkslateblue;
}
}
p:not(#id) {
color: green;
}
p.class {
color: red;
}
<p class="class">text</p>
<p id="id">last text</p>
0,0,0
0,0,1
@layer reset {
/* ... other reset rules */
input[type="text"] {
border: 1px solid gray;
}
}
@layer components {
/* ... other component rules */
.my-input {
border: 4px solid blue;
}
}
@layer reset, components, utilities;
@layer reset {
/* ... other reset rules */
input[type="text"] {
border: 1px solid gray;
}
}
@layer components {
/* ... other component rules */
.my-input {
border: 4px solid blue;
}
}
1
2
3
@layer reset, components, utilities;
@layer components {
/* ... other component rules */
.my-input {
border: 4px solid blue;
}
}
@layer reset {
/* ... other reset rules */
input[type="text"] {
border: 1px solid gray;
}
}
1
2
3
@layer reset, components, states;
@layer components {
/* Buttons, inputs etc. */
}
@layer states {
/* Make sure stats override, no matter specificity count */
:disabled {
background-color: #ddd;
color: #999;
}
:focus-visible {
outline: 2px solid var(--focus-color, currentColor);
outline-offset: 2px;
}
}
@layer reset, theme, global, layout, components, utilities, states;
.grid {
align-items: last baseline;
grid-template-columns: subgrid;
}
meget snart!
Loading...
Loading...
Loading...
.subgrid {
display: grid;
grid-template-rows:
[system-status] 3.5rem
[primary-nav] 3rem
[primary-header] 4rem
[main] auto
[footer] 4rem
[system-gestures] 2rem;
grid-template-columns:
[fullbleed-start] 1rem
[main-start] auto
[main-end] 1rem
[fullbleed-end];
}
nav {
grid-area: primary-nav / fullbleed;
display: grid;
grid-template-columns: subgrid;
}
nav > .content {
grid-area: main;
}
body {
display: grid;
grid-template-rows: auto 1fr auto;
grid-template-columns:
[full-start]
1fr
[content-start]
minmax(0, 800px)
[content-end]
1fr
[full-end];
gap: 1rlh;
> * {
grid-column: content;
}
}
header,
main,
footer {
display: grid;
grid-template-columns: subgrid;
grid-column: full;
align-content: start;
> * {
grid-column: content;
}
}
.full-bleed {
display: grid;
grid-template-columns: subgrid;
grid-column: full;
> * {
grid-column: content;
}
}
.cards {
display: grid;
gap: 1rlh;
@media (width > 600px) {
grid-template-columns: repeat(3, 1fr);
}
}
.card {
display: grid;
grid-template-rows: subgrid;
grid-row: span 3;
}
@container (inline-size > 40em) {
.card {
flex-direction: column;
}
}
width
range
@media (20em < width <= 40em) {
...
}
.card-wrapper {
container-type: inline-size;
}
@container (inline-size > 40em) {
.card {
flex-direction: column;
}
}
.card-wrapper {
container-type: inline-size;
container-name: main;
}
@container main (inline-size > 40em) {
.card {
flex-direction: column;
}
}
.card-wrapper {
container: main / inline-size;
}
@container main (inline-size > 40em) {
.card {
flex-direction: column;
}
}
flere navne
.card-wrapper {
container: main / inline-size;
}
.card {
font-size: clamp(1.45rem, 6cqi, 1.75rem);
}
6 % af inline (bredden)
li:nth-last-child(odd):first-child
meget snart!
artcle:has(> img) {}
p:not(article > *) { ... }
article > :is(.class, #id) { ... }
:where(#article) a { ... }
article:has(h2) { ... }
article:not(:has(h2)) img { ... }
article:has(> :last-child:nth-child(3)) { ... }
body {
display: grid;
}
body:has(main + aside) {
grid-template-columns: 1fr 300px;
}
body:has(aside + main) {
grid-template-columns: 300px 1fr;
}
:root:has(dialog[open]) {
overflow: hidden;
}
.valid-css-color-function-colors {
--srgb: color(srgb 1 1 1);
--srgb-linear: color(srgb-linear 100% 100% 100% / 50%);
--display-p3: color(display-p3 1 1 1);
--rec2020: color(rec2020 0 0 0);
--a98-rgb: color(a98-rgb 1 1 1 / 25%);
--prophoto: color(prophoto-rgb 0% 0% 0%);
--xyz: color(xyz 1 1 1);
}
.most-hyped {
--display-p3: color(display-p3 1 1 1);
--rec2020: color(rec2020 0 0 0);
}
.element {
background: oklch(80% .2 220);
}
lightness
chroma
hue
In OKLCH all backgrounds with L≥87% have good contrast with black text.
in oklch
--bg:
color-mix(
in oklch,
var(--color-a),
var(--color-b) var(--percent)
)
;
Centering stuff
.element {
display: flex;
gap: 1.25ch;
align-items: center;
}
Centering stuff
Overskrift
Morbi tortor mi, semper id magna quis, auctor auctor purus. Nam pellentesque vulputate lectus, et euismod est tincidunt sed.
Overskrift
Overskrift
Overskrift
giraf
Figma: Vertical trim
h1 {
text-box-trim: both;
text-edge: cap alphabetic;
}
Overskrift
Morbi tortor mi, semper id magna quis, auctor auctor purus. Nam pellentesque vulputate lectus, et euismod est tincidunt sed.
h1 {
text-box-trim: both;
text-edge: cap alphabetic;
/* future? */
/* text-box-trim: cap alphabetic; */
}
.balance {
text-wrap: balance;
}
.pretty {
text-wrap: pretty;
}
article {
padding: 2rlh;
gap: 1rlh;
}
Intrinsic web
Hvorfor griber man typisk fat i JS?
Comparison Function
min(), max(), clamp()
Stepped Value Functions
round(), mod(), rem()
Trigonometric Functions
sin(), cos(), tan(), asin(), acos(), atan(), atan2()
Exponential Functions
pow(), sqrt(), hypot(), log(), exp()
Sign-Related Functions
abs(), sign()
Numeric Constants
e, pi
Degenerate Numeric Constants
infinity, -infinity, NaN
Er CSS snart et programmeringssprog? 😉
Inert, Esc dismiss,
top-layer
Loading...
.box {
rotate: 45deg;
translate: -50% -50%;
scale: 1.1;
}
.box:hover {
rotate: 0deg;
}
@property --colorPrimary {
syntax: '<color>';
}
@property --colorPrimary {
syntax: '<color>';
initial-value: magenta;
}
@property --colorPrimary {
syntax: '<color>';
initial-value: magenta;
inherits: false;
}
@property --colorPrimary {
syntax: '<color>';
initial-value: magenta;
inherits: false;
}
@property --colorPrimary {
syntax: '<color>';
initial-value: magenta;
inherits: false;
}
@property --colorPrimary {
syntax: '<color>';
initial-value: magenta;
inherits: false;
}
OBS! @property performance
Optimized composited scroll animations
Not blocking main thread
Loading...
Loading...
Loading...
Loading...
Loading...
.element {
animation: progress linear;
animation-timeline: scroll(block root);
}
.element {
animation: progress linear;
animation-timeline: scroll();
}
.element {
animation: reveal linear;
animation-timeline: view();
animation-range: cover 0% entry 100%;
}
section > * {
animation:
entry linear,
exit linear;
animation-timeline: view();
animation-range: [...];
}
Optimized flip-animations
Loading...
Loading...
Loading...
Loading...
.box-1 {
view-transition-name: box-1;
}
.box-2 {
view-transition-name: box-2;
}
.box-1 {
view-transition-name: box-1;
}
.box-2 {
view-transition-name: box-2;
}
btn.addEventListener("click", () => {
document.startViewTransition(_ => grid.classList.toggle("col-count"));
});
.box-1 {
view-transition-name: box-1;
}
.box-2 {
view-transition-name: box-2;
}
btn.addEventListener("click", () => {
if (document.startViewTransition) {
document.startViewTransition(_ => grid.classList.toggle("col-count"));
} else {
grid.classList.toggle("col-count");
}
});
.box-1 {
view-transition-name: box-1;
}
::view-transition-new(box-1) {
animation: scale-in .5s both;
}
::view-transition-old(box-1) {
animation: scale-in .5s both reverse;
}