So what’s “Super Layout!”? It goes beyond the normal, humdrum existence of the ordinary layout. This layout climbs Mt. Everest and the other peaks. This layout bought Bitcoin in 2008. This layout now owns a Pilatus PC12 AND a Piper Meridian.
You're a Real Edge Case Mr.
Project Emulate is a good example of an edge case. That emulator image; what a pain. Making the whole thing responsive; ouch! First I’m thinking just flexbox that with an "align-items: top" and presto; immediately again thwarted by the small screen. Mobile first; bah! Didn’t look good at all and I wanted the first line to be above the image with the rest of the script (I’m writing an afternoon short on the side, hit me up Hollywood!) below. Enter nth-child. Did you know browsers have children? Turns out you can use a media query to rearrange child elements that you can also probably do with like a clamp and maybe flexbox attributes. But I used this Media Query.
@media screen and (max-width: 860px) {
.container {
flex-direction: column;
align-items: flex-start;
}
.first-line-phone {
display: block;
font-weight: bold;
margin-bottom: 1rem;
}
.first-line-laptop {
display: none;
}
.container :nth-child(1) {
order: 2;
}
.container :nth-child(2) {
order: 1;
}
.container :nth-child(3) {
order: 3;
}
.remaining-text {
margin-left: 0;
}
.responsive-image {
margin-right: 0;
margin-bottom: 1rem;
max-width: 100%;
}
.responsive-video {
width: 100%;
}
.responsive-text {
max-width: 100%;
}
}
Requires some ‘splaining. Say you have this HTML:
<article class="container">
<img
class="responsive-image"
src="img/EmulatorFirstCut.png"
alt="Element 1"
/>
<h3 class="first-line-phone" alt="Element 2">Behold!</h3>
<div class="remaining-text" alt="Element 3">
<h3 class="first-line-laptop">Behold!</h3>
<p>Rest of the script.</p>
</div>
</article>
Couple things going on. Class first-line-phone is “display: none” (hidden) on wide screens and class first-line-laptop is visible on wide screens. On narrow screens, the opposite is true. On wide screens, normal humdrum flexbox does it’s thing. On narrow screens, the nth-child shines; as you can see, the children get rearranged - Element 2 (first line of the script) goes first, then Element 1 (the image) followed by Element 3 (rest of the script). Now it occurs to me that I might be able to just put Element 2 first and let "display: none" keep it invisible until needed, but then I wouldn’t need all these children running around making a mess. I don’t remember if I tried that, and it’s sunk cost at this point anyway.
Fight the Good Fight
The last piece of layout that is only partially solved are these blog code blocks. Continually a pain, I had to resort to java script to get them looking right, and notepad++ for the editing. Here’s the CSS:
.code-block {
background-color: #080808;
border: 2px solid #004242;
border-radius: 4px;
padding: 1rem;
margin: 1rem;
overflow-x: auto;
max-width: var(--std-max-width);
}
code {
font-family: "Courier New", Courier, monospace;
color: #00bfff;
white-space: pre;
display: block;
margin: 0;
}
The CSS is straightforward; the “overflow-x: auto” adds a horizontal scroll bar when the screen gets too narrow to display the entire line. The “white-space: pre” preservers any whitespace and only breaks lines at newline characters or HTML break elements - so the code stays looking like code, with the proper indents and no auto-wrapping of lines; but not without some finagling.
Finagle #1 involves adding explicit spaces for proper indenting with the entity. Interestingly, searching now for what these things are called (i.e. entity), there’s supposed to be a ’;’ on the end. But it works without it so, efficiency! I also might just pair explicit spacing with explicit line breaks (<br />), but not always. Sometimes I use neither. Ahhh the evolving standard.
Finagle #2 involves java script. We all like our HTML to look nice in VS Code, so the code blocks will be indented accordingly in the HTML document itself. But that pesky “white-space: pre” makes the whole code block appear indented. So I use a query selector to get all the text in the code block and run it through this leading-space eliminator brought to me by Chat GPT.
document.querySelectorAll(".code-block code").forEach((block) => {
const lines = block.textContent.split("\n");
if (lines.length > 1) {
const firstNonEmptyLine = lines.find(
(line) => line.trim().length > 0
);
if (firstNonEmptyLine) {
const leadingSpaces = firstNonEmptyLine.match(/^\s*/)[0].length;
block.textContent = lines
.map((line) => line.slice(leadingSpaces))
.join("\n")
.trim();
}
}
});
For each code block on the page, this script:
- Splits each block into an array of lines.
- Finds the first non-empty line, which is the line that I want no-indenting on.
- Determines the number of leading spaces in that line, which equals the number of spaces that the whole code block is indented in the HTML document.
- Maps the lines back into the block, first slicing off the leading spaces, joining them with a newline character and trimming that and and whitespace...wait...trim()’s supposed to trim whitespace and newline characters from both ends?...Hmmph. OK, think I got it, no thanks to the AI confusicators. The map operation is first, returning an array of lines with the whitespace removed. Then, the join concatenates them together into one big string, with each stringlet (just coined that, gonna Trademark) post-pended with a newline character. THEN, the trim comes in and removes the leading whitespaces (which there are none) AND that last newline character (which doesn’t matter) from the entire concatenated string. Get Harvard on the line, I want to know WHY they rejected me!
Finagle #3 (Too many finagles!)
I have the popular Prettier formatting plugin for VS Code, set to format on save. Normally, it works pretty well, but it formats my code blocks into code blobs if I don’t do the whole explicit spacing and return characters, which gets annoying. Plus, even if I do the explicit stuff, Prettier might just go and wrap a line or two, and I don’t want that. So, I use the wonderful multi-step manual process of writing out the rest of the HTML, then opening the file in notepad++ and pasting in the code blocks. Since I have no formatter activated in notepad++, I can finish up editing and save the final result with no blobification. One of these days I’ll just import Tailwind and it will do everything for me.