
\documentclass[presentation,aspectratio=169]{beamer}
\usepackage{xcolor}
\usepackage[T1]{fontenc}
\usepackage[default]{cantarell}
\beamertemplatenavigationsymbolsempty
\useinnertheme{circles}
\useoutertheme{tree}
\author{Artem Bologov}
\title{Postmodern Front-End}
\definecolor{Coral}{rgb}{0.9411765, 0.5019608, 0.5019608} % LightCoral
\setbeamercolor{palette primary}{bg=black,fg=white}
\setbeamercolor{palette secondary}{bg=black,fg=white}
\setbeamercolor{palette tertiary}{bg=black,fg=white}
\setbeamercolor{palette quaternary}{bg=black,fg=Coral}
\setbeamercolor{subtitle}{bg=black,fg=white}
\setbeamercolor{author}{bg=black,fg=lightgray}
\setbeamercolor{institute}{bg=black,fg=lightgray}
\setbeamercolor{date}{bg=black,fg=lightgray}
\setbeamercolor{structure}{fg=Coral,bg=black} % itemize, enumerate, titles, etc
\setbeamercolor{normal text}{bg=black,fg=white}
\setbeamercolor{block body}{fg=white,bg=red!40!black}
\setbeamercolor{block title}{bg=Coral,fg=white}
\setbeamercolor{block body example}{fg=white,bg=red!40!black}
\setbeamercolor{block title example}{bg=Coral,fg=white}
\setbeamercolor{block body alerted}{fg=white,bg=Coral}
\setbeamercolor{block title alerted}{bg=red,fg=white}
\setbeamercolor{example text}{bg=Coral,fg=white}
\setbeamercolor{quotation}{fg=white,bg=red!40!black}
\setbeamercolor{verse}{fg=white,bg=red!40!black}
\hypersetup{colorlinks,allcolors=.,urlcolor=Coral,}
\begin{document}

\section*{Identity} \label{identity}

Artyom

\begin{itemize}\item Is lazy.
\item Bipolar.
\item Interested in Turing tarpits and using tech in unintended ways.
\item Is an HTML/CSS extremist.
\item Doesn't understand what modern, postmodern, metamodern, and hypermodern are.
\end{itemize}


\section*{Postmodern?} \label{postmodern}

\begin{figure}[h!]
\includegraphics[width=\textwidth,height=\textheight,keepaspectratio]{./assets/postmodern-definition.png}
\caption{It is hard to find a good definition for postmodern!}\end{figure}

\section*{Postmodern 2?} \label{postmodern}

Any definition will do, so here's the one I liked:

\begin{figure}[h!]\begin{quote}
If there is a common denominator to all these postmodernisms, it is that of a crisis in representation: a deeply felt loss of faith in our ability to represent the real, in the widest sense. No matter whether they are aesthestic [sic], epistemological, moral, or political in nature, the representations that we used to rely on can no longer be taken for granted.
\end{quote}\caption{Hans Bertens as cited in Wikipedia}\end{figure}


\section*{Postmodern Front-End?} \label{postmodern-front-end}

\begin{itemize}\item We no longer can rely on modern tech (like React) because it's stagnating (see Niquola's htmx seminar.)
\item We need to find some other way to do interfaces.
\item So why not get radically simple/primitive while we're at it?
\item Like getting back to the basics. Vanilla Web Platform stack—HTML, CSS, and maybe some JS.
\end{itemize}

<button onclick="document.querySelector('#start').showModal()">Shall we get started?</button>

<dialog id=start>
  <h3>Are you sure you're ready for Postmodern Front-End?</h3>
  \includegraphics[width=\textwidth,height=\textheight,keepaspectratio]{./assets/zheu-js.jpg}
  <p>
    Beware: there is no JS in there.
    (Well, maybe a bit?)
  </p>
  <form method=dialog>
    <button formmethod="dialog">Let's get to it!</button>
  </form>
</dialog>

\paragraph{Post-presentation notes} \begin{quote}
Only after this talk was I introduced to
\href{https://www.cssreactions.com/}{Postmodern CSS}.
Not sure if we're talking the same thing with them.
But the name clash is worth noting.
\end{quote}

\section*{Snapping Fragments / Carousel} \label{snapping}

You already see one!

  But, in case you need more,
  \href{https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_scroll_snap#scroll_snap_in_action}{MDN has more!}

\begin{figure}[h!]\begin{verbatim}
  html {
      scroll-snap-type: y mandatory;
  }
  section, footer {
      min-height: 100vh;
      padding: 1em;
      background-color: var(--bg);
      scroll-snap-align: start;
  }
\end{verbatim}\caption{CSS used in these slides}\end{figure}

\section*{Autocomplete} \label{autocomplete}

<datalist id=list>
  <option value="Take Me to Church">Take Me to Church</option>
  <option value="Too Sweet">Too Sweet</option>
  <option value="Work Song">Work Song</option>
  <option value="From Eden">From Eden</option>
  <option value="Almost (Sweet Music)">Almost (Sweet Music)</option>
  <option value="Someone New">Someone New</option>
  <option value="Eat Your Young">Eat Your Young</option>
  <option value="Unknown / Nth">Unknown / Nth</option>
  <option value="Nina Cried Power">Nina Cried Power</option>
  <option value="Like Real People Do">Like Real People Do</option>
  <option value="Shrike">Shrike</option>
  <option value="Angel of Small Death & the Codeine Scene">Angel of Small Death & the Codeine Scene</option>
  <option value="Moment’s Silence (Common Tongue)">Moment’s Silence (Common Tongue)</option>
  <option value="Would That I">Would That I</option>
  <option value="De Selby (Part 1)">De Selby (Part 1)</option>
  <option value="Movement">Movement</option>
  <option value="Jackie and Wilson">Jackie and Wilson</option>
  <option value="NFWMB">NFWMB</option>
  <option value="Wasteland, Baby!">Wasteland, Baby!</option>
  <option value="Francesca">Francesca</option>
  <option value="To Be Alone">To Be Alone</option>
  <option value="Talk">Talk</option>
  <option value="I, Carrion (Icarian)">I, Carrion (Icarian)</option>
  <option value="De Selby (Part 2)">De Selby (Part 2)</option>
  <option value="In a Week">In a Week</option>
  <option value="No Plan">No Plan</option>
  <option value="Arsonist’s Lullabye">Arsonist’s Lullabye</option>
  <option value="Dinner & Diatribes">Dinner & Diatribes</option>
  <option value="Swan Upon Leda">Swan Upon Leda</option>
  <option value="First Time">First Time</option>
  <option value="Foreigner’s God">Foreigner’s God</option>
  <option value="Abstract (Psychopomp)">Abstract (Psychopomp)</option>
  <option value="Sunlight">Sunlight</option>
  <option value="As It Was">As It Was</option>
  <option value="All Things End">All Things End</option>
  <option value="Nobody’s Soldier">Nobody’s Soldier</option>
  <option value="It Will Come Back">It Will Come Back</option>
  <option value="Sedated">Sedated</option>
  <option value="Be">Be</option>
  <option value="To Someone From A Warm Climate">To Someone From A Warm Climate</option>
  <option value="In the Woods Somewhere">In the Woods Somewhere</option>
  <option value="Nobody">Nobody</option>
  <option value="Who We Are">Who We Are</option>
  <option value="Wildflower and Barley">Wildflower and Barley</option>
  <option value="Butchered Tongue">Butchered Tongue</option>
  <option value="Run">Run</option>
  <option value="Damage Gets Done">Damage Gets Done</option>
  <option value="Empire Now">Empire Now</option>
  <option value="First Light">First Light</option>
  <option value="Through Me (The Flood)">Through Me (The Flood)</option>
  <option value="Son of Nyx">Son of Nyx</option>
  <option value="Fare Well">Fare Well</option>
  <option value="To Noise Making (Sing)">To Noise Making (Sing)</option>
  <option value="Anything But">Anything But</option>
  <option value="Hymn to Virgil">Hymn to Virgil</option>
  <option value="That You Are">That You Are</option>
  <option value="July">July</option>
  <option value="Better Love">Better Love</option>
  <option value="The Bones">The Bones</option>
  <option value="Jackboot Jump (Live)">Jackboot Jump (Live)</option>
  <option value="Devil">Devil</option>
  <option value="My Love Will Never Die">My Love Will Never Die</option>
  <option value="Blood Upon the Snow">Blood Upon the Snow</option>
  <option value="Why Would You Be Loved">Why Would You Be Loved</option>
  <option value="Tell It to My Heart">Tell It to My Heart</option>
  <option value="Blood in My Eyes">Blood in My Eyes</option>
  <option value="Blood">Blood</option>
  <option value="Northern Attitude">Northern Attitude</option>
  <option value="Say My Name">Say My Name</option>
  <option value="But the Wages">But the Wages</option>
  <option value="The Love Of">The Love Of</option>
  <option value="Tell It to My Heart">Tell It to My Heart</option>
  <option value="Rob The Goddess">Rob The Goddess</option>
  <option value="My Lagan Love">My Lagan Love</option>
  <option value="I Could Be Yours">I Could Be Yours</option>
  <option value="In Your Own Sweet Time">In Your Own Sweet Time</option>
  <option value="Humours of Whiskey">Humours of Whiskey</option>
</datalist>

<form action=mailto:hozier-feedback@aartaka.me>
  <input type=hidden name=subject value="My favorite Hozier song">
  <input name=body list=list placeholder="Your favorite Hozier song?">
  <button type=submit>Submit</button>
</form>

\paragraph{Post-presentation notes} \begin{quote}
Notice that calling this "autocomplete" is not necessarily right.
Autocomplete is a lot—smart just-in-time suggestions, dynamic content reloading, etc.
This is a rather simplistic approach (that works nonetheless!)
\end{quote}

\section*{Tabs} \label{tabs}

<style>
  div[id*="tab"] {
      display: none;
  }
  div[id*="tab"]:target {
      display: block;
      padding: 1em;
      border: 0.1em solid var(--accent);
  }
  div[id="tab1"]:not(:has(~ :target)) {
      display: block;
      padding: 1em;
      border: 0.1em solid var(--accent);
  }
  nav:has(~ div#tab1:target) a[href="#tab1"],
  nav:has(~ div#tab2:target) a[href="#tab2"],
  nav:has(~ div#tab3:target) a[href="#tab3"] {
      border: 0.1em solid var(--on-accent);
  }
</style>

<nav>
  \href{"#tab1"}{Tab 1}
  \href{"#tab2"}{Tab 2}
  \href{"#tab3"}{Tab 3}
</nav>
<div id=tab1>
  <p> Est voluptates harum excepturi qui at. Dignissimos repellendus et ad sit veniam saepe sit libero. Ullam qui laboriosam consequatur similique facilis deleniti. Itaque iste est blanditiis laborum.

  <p> Velit esse molestiae eveniet ipsa alias tenetur corporis. Quo quia dignissimos et quisquam fugiat maxime voluptate. Aut nemo iste blanditiis amet saepe. Voluptas molestias enim ab veniam eligendi. Aperiam id qui sint nemo.
</div>

<div id=tab2>
  <p> Accusamus minus rerum perspiciatis sit aut qui autem. Fugiat corporis aliquid cum. Et in distinctio nesciunt autem ut debitis impedit quo. Quibusdam incidunt praesentium itaque id est consequatur quibusdam dolor. Aspernatur ea qui aut quam ea quis qui voluptas. Harum enim natus et quia.
</div>

<div id=tab3>
  <p> Temporibus quo nulla iusto. Fugiat autem nam at. Molestiae qui est ab voluptatibus modi voluptates dolor. Praesentium cumque est ut est aut blanditiis quo qui. Inventore eos voluptatem numquam perspiciatis modi.

  <p> Libero aperiam error beatae. Ad suscipit voluptas quasi amet quisquam. Praesentium animi repellendus tempora provident omnis sed totam sed. Et quis possimus doloremque mollitia.
</div>

\paragraph{Post-presentation notes} \begin{quote}
  This, as one of the people in the audience mentioned, is not an accessible tabs widget.
  And it's not the snappiest way to implement it either—radio button tabs might work better for your case.
  Still, I'm including it for completeness.
  And for you to check out the sources and get horrified at CSS selectors I'm using.
\end{quote}

\section*{Resizing} \label{resizing}

<style>
  #resizable {
      table-layout: fixed;
      width: 20vw;
      height: 20vh;
      display: block;
      resize: both;
  }
</style>
\begin{table} \begin{tabularx}{0.8\textwidth}
<tr>
 & <b>Clear</b> In the clear domain there are tight constraints, no degrees of freedom, and best practice can be used to sense, categorize and respond
 & <b>Complicated</b> In the complicated domain there are governing constraints, problems are tightly coupled, and appropriate good practice should be used to sense, analyze and respond
 \\
<tr>
 & <b>Complex</b> In the complex domain there are enabling constraints, problems are loosely coupled, and one should use emergent practice to probe, sense and respond
 & <b>Chaotic</b> In the chaotic domain there is a lack of constraints, the problems are de-coupled, and one creates novel practice by acting, sensing and responding
 \\
\end{tabularx} \caption{Cynefin framework with restricted size and "resize: both;"} \end{table}

\section*{Variables/custom properties} \label{variables}

\begin{figure}[h!]\begin{verbatim}
  /* Dark theme. */
  @media (prefers-color-scheme: dark) {
      :root {
          --bg: var(--dark, black);
          --fg: var(--light, papayawhip);
          --accent: var(--dark-accent, lightcoral);
          --on-accent: var(--bg);
          --gray: var(--neutral, lightgray);
      }
      * {
          font-palette: dark;
      }
  }
\end{verbatim}\caption{Minimal theming setup I use}\end{figure}

\paragraph{Post-presentation notes} \begin{quote}
  I used this (and the next) slide to mock SCSS.
  But it was rightly noted that SCSS does more than just vars and nesting.
  There is even some control flow there!
  Still, these advanced features are rarely useful for the interfaces I'm working on.
  So I have all the right to mock it for myself.
\end{quote}

\section*{Nested rules} \label{nesting}

<style>
  pre#nested {
      code {
          background-color: var(--accent);
          color: var(--on-accent);
      }
      &:hover {
          background-color: var(--accent);
          color: var(--on-accent);
      }
  }
</style>

\begin{figure}[h!]\begin{verbatim}
  pre#nested {
      code {
          background-color: var(\verb|--accent|);
          color: var(\verb|--on-accent|);
      }
      &:hover {
          background-color: var(\verb|--accent|);
          color: var(\verb|--on-accent|);
      }
  }
\end{verbatim}\caption{Nested CSS selectors!}\end{figure}

  Note that it only gained major browser support in 2023, so it's relatively unreliable.

\section*{Custom Elements (JS Warning!)} \label{custom-elements}

This is a sorted list.
It starts out as 3-2-1 unsorted sequence, but gets sorted in a short while.
Notice that the timeout is mostly so that you notice the whole sorting thing.
The element itself renders in ~2 milliseconds
</p>

<script>
  class SortedList extends HTMLElement {
      constructor() {
          super();
      }
      connectedCallback() {
          setTimeout(() => {
              let nodelist = this.children;
              let sorted = (Array.from(nodelist)).sort((a,b) => a.innerText - b.innerText);
              sorted.forEach((elem) => {
                  this.removeChild(elem);
                  this.appendChild(elem)
              });
          }, 100);
      }
}
customElements.define("sorted-ul", SortedList);
</script>

<sorted-ul>
\item 3</li>
\item 2</li>
\item 1</li>
</sorted-ul>

\paragraph{Post-presentation notes} \begin{quote}
  There are reasons for why Custom Elements didn't take off.
  I'm still waiting for links about that.
  I'll include these links here when I get them.
\end{quote}

\section*{Cons of Postmodern Front-end} \label{cons}

\begin{itemize}\item Requires modern (фить-ха!) browsers (2019+)
\item Styles of HTML elements vary between browsers.
\item Not many people know the APIs.
\item It is conceptually dependent on Modern Front-end.
\end{itemize}

\section*{Metamodern? Hypermodern?} \label{metamodern-hypermodern}

\begin{figure}[h!]\begin{quote}
Metamodernism reflects an oscillation between, or synthesis of, different "cultural logics" such as modern idealism and postmodern skepticism, modern sincerity and postmodern irony, and other seemingly opposed concepts.
\end{quote}\caption{Metamodernism is cool}\end{figure}

\begin{figure}[h!]\begin{quote}
Hypermodernity (supermodernity) is a type, mode, or stage of society that reflects an inversion of modernity. Hypermodernism stipulates a world in which the object has been replaced by its own attributes.
\end{quote}\caption{Hypermodernism is... Something?}\end{figure}

\section*{Metamodern, actually!} \label{metamodern-actually}

Now, throwing away all the things previous Web Design generations generated is not fun.
Luckily, Postmodern Front-end is compatible with most of the previous generation tech!
You can even use these new CSS goodies from inside React!
(I didn't tell you that.)

That's what Metamodern Front-end means: we don't have to forget the past.
And we don't.
Let's just pick whatever works.

But not React, please.

\par\noindent\rule{\textwidth}{0.4pt}
\href{https://creativecommons.org/licenses/by/4.0}{CC-BY 4.0} 2022-2026 by Artyom Bologov (aartaka,)
\href{https://codeberg.org/aartaka/pages/commit/a91befa}{with one commit remixing Claude-generated code}.
Any and all opinions listed here are my own and not representative of my employers; future, past and present.
\end{document}
