An online markdown blog and knowledge repository.
Collection of notes from various sources (but started by watching an NDC Oslo presentation) regarding web design pattern sans javascript.
What will not be used:
What will be used:
Some of the following sub-sections are notes related to the topics discussed and demoed by Amy.
Goal: Create an SPA with multiple tabbed pages using Anchor links and CSS.
Use Content Targeting:
target
property of an element to get or update that elements' attributes.<html>
<head>
</head>
<body>
<header>
<nav>
<a href="#home">Home</a>
...
<a href="#contact">Contact</a>
</nav>
</header>
<main>
<section id="home">
...
</section>
<section id="contact">
...
</section>
<main>
</html>
section {
display: none; // hide this parent element
&:target { // ampersand causes affect to apply to parent
display: block; // show the parent element
}
}
The Target Pseudo Selector:
The Nesting Selector:
element { property: style & childEl { proprty: style }}
.Normally, a nested CSS Selector rule would apply to the child of the parent element in the nested CSS. Use of &
causes the rule to apply to the parent given the parent element and child attribute/rule setting.
Warning: In practice, this is probably an incomplete solution. For example, a browser first arriving at the website would need to navigate to the website at the #home
ID e.g. http://foo.bar/#home
(instead of http://foo.bar/
or http://foo.bar/index.html
) in order to display any content at all.
<details>
<summary>Accordian Item Summary</summary>
<p>Accordian Item content</p>
</details>
Browser Support:
Required Fields:
required
attributes to the input element.Data Format:
Browser Support:
Generally, Pre-Processors are used to make this simple.
Lately, CSS has enabled nesting to enable nesting.
Support:
Apply these attributes to input
elements:
type
: Set to 'range'.min
: Set the minimum value in quotes i.e. '0'.max
: Set the maximum value in quotes i.e. '9'.The has
pseudo-selector:
:nth-child()
).div:has(p:nt-child(1)) { --chilren: 1; }
Amy configured a complicated
Support:
has
selector: Generally 2022 (FF: 2023).Testimonial Slider: Usually these are rendered as a 'slider' UI, showing multiplt testimonial cards, often automatically.
<input type='radio' id='t_1' name='testimonials' />
<label for='t_1'>Quote 1</label>
<blockquote>
<!-- quote -->
</blockquote>
Use Input type radio
to make a selectable UI element.
Apply CSS to the testimonials
element:
.testimonials {
display: grid; // layout
grid-template-rows: 1fr auto; // resizable sections
grid-template-columns: 1rf repeater(var(--num_test), auto) 1ft; // ad spacing for each column data
justify-content: center;
&:has(blockquote:nth-of-type(1)) { // count quotes
--num_test: 1;
}
...
}
blockquote {
grid-column: 1 / -1; // across end-to-end of display
grid-row: 1 / 2; // at the end display on the second row
}
label {
order: 2;
grid-row: 2;
}
Hide all quotes so they can be selected later:
blockquote {
...
pointer-events: none;
opacity: 0;
}
input[type='radio']:checked {
& + label + blockquote {
opacity: 1;
pointer-events: auto;
}
}
Leverage before
and after
pseudo-elements to label the block quotes nicely:
label {
...
position: relative;
cursor: pointer;
&:before, &:after {
height: 20px;
width: 20px;
border-radius: 50%;
border: 2px solid var(--green);
}
}
Add "selected" styling to the labels:
label {
...
&:after {
background: radial-gradient(
circle, var(--green) calc(100% - 6px),
transparent calc(100% - 6px)
);
position: absolute;
}
}
Relatively new (less than 5 years) Selectors:
Warnings:
This segment was very involved, and included a large amount of CSS (much like the previous topic).
Amy also discussed using the :has
pseudo-selector to toggle light and dark mode, using :before
and :after
selectors in conjunction with :has
.
In summary, it was not a great solution because:
An Image Carousel layout can be broken down into 4 elements:
input
of type 'radio' with a 'value' and 'id' set, and the checked
attribute.label
element with a 'for' attribute pointing to the the radio input, with label text content.div
element with a class attribute to CSS assignment, application.img
element with src attribute to a valid image and alt attribute for accessibility.How is this displayed and styled?
.carousel {
display: grid;
grid-template-columns: 4em 1fr 4em;
grid-template-rows: 300px;
grid-template-areas: 'previous image next';
overflow: hidden; // do not overflow the page
max-width: 100%;
}
.image {
grid-area: image; // see grid-template-areas values
opacity: 0;
}
label {
display: none;
}
Find a radio input that is checked, the label after it, and the image
class after that, and set the opacity to '1':
input[type='radio']:checked + label + .image {
opacity: 1;
}
Check if none of the radios have been checked within the carousel, and get the radio input after that, the label after that, and the image after that, and set its opacity to '1':
.carousel:not(:has(input[type='radio']:checked)) {
& input[type='radio']:first-of-type + label + .image {
opacity: 1;
}
}
Add Controls by finding the radio button that is checked, get the label next to it, get the image next to that, then get the radio button next to that and the label next to that, assign its display to block, set grid-area to 'next', and add the :arrow-right: emoji as the content:
inptu[type='radio']:checked + label + .image + input[type='radio'] + label {
display: block;
grid-area: next;
&::before {
content: ':arrow-right:';
}
}
Do a similar thing to find the 'previous image' to place the :arrow-left: emoji.
Support and Best Pracrtices:
Instead: Use Gallery or something other than an Image Carousel.
JS is useful, but is it really necessary?
"The escalator is temporarily stairs." [Mitch Hedberg]
"If you are presenting a UI element to a user and it's non-functional, it is a broken experience." Instead, present the basic UI Elements and only add additional elements and functionality if JavaScript is present. [Wes Boss and Scott Tolinski]
target
of pointer events :arrow-right: Auto, None, Stroke, or Fill.grid
) are grid-auto-columns
, grid-auto-flow
, grid-auto-rows
, grid-template-areas
, grid-template-columns
, and grid-template-rows
.:Has()
CSS pseudo-class represents an element where any of the relative selectors passed-in match at least one element when anchored against this element.:Not()
CSS pseudo-class represents elements that do not match a list of selectors. Aka 'negation pseudo-class'.Top
, Right
, Bottom
, and Left
properties deterine final location of the element.