hey! it's berry!

 

full-time software developer, part-time cs master's student, free-time languages enthusiast, some-time rhythm game attempter, big-time c++ hater


lexyeevee
@lexyeevee
  1. 1

    text stuff mostly
  2. 2

    boxes, transform
  3. 3

    positioning, clicking stuff
    🌟 your here 🌟
  4. 4

    flexbox and grid
  5. 5

    animation and other nonsense

Are YOU a CSS BABY who has been keeping up with this series so far?

Are your friends doing stupid css tricks and leaving you feeling  left out?

Do you wish Eevee
Eevee
would help you out?

great news it's time to Put Stuff On The God Dang Screen


Put Stuff On The God Dang Screen

in our previous installment i told you about changing the size of a box... but it still gets placed with flow layout, which means put in the jenga stack of block boxes.

you can use
horizontal margins to
shift stuff horizontally,

but that will only get you so far.

css has several whatchamacallits for letting you arrange boxes in more interesting ways, but they generally get more complex as you go, so we're kinda gonna start with the more straightforward stuff and work our way up. as luck would have it, this is also the order this stuff was added to css, so it's like a historical jaunt through how horrible it was to be a web developer in 2004

positioning

there's a css property called position and hmm that sounds like a pretty good place to start. this sets the type of positioning the element uses, and as of this writing, there are five of them:

static positioning

this is what everything has by default. it's what we've been using all along. it's kind of a weird name but you can think of it as "normal". nothing to see here

relative positioning

this one is a little weird, and 99.9% of the time it's only used for a side effect, which we'll get to in a moment

but what it does is place the box normally, and then let you adjust where the box actually displays. so it's a bit like using transform: translate();. except it's, um, older.

you can adjust the positioning with the four "edge" properties: top, bottom, left, and right. they're all lengths, relative to the box's original position, and where positive values mean "inwards" — so a positive left will shift the box to the right, whereas a positive right will shift the box to the left.

so you might do bottom: 0.5em; or bottom: -0.5em; or bottom: 50%;.

hmm. that last one didn't seem to do anything. that's interesting. i wonder why that i—

ahem. other deets of note here:

  • the "edge" properties do nothing on a static element. they're just completely ignored.

  • depending on how the text wrapping shakes out, you might notice that relative positioning works on inline elements, even when they're wrapped! the whole wrapped box gets shifted. sort of like wrapped boxes can also have wrapped borders.

  • there's a newish property called inset that lets you set all four of these properties at once, using the same kinds of "four edge" syntax as e.g. margins and borders. it's not very useful here, since inset: 4px; would move the box four pixels in every direction which puts it right back where it started, but that's a fantastic segue into...

absolute positioning

here's our first Cool Tool. in fact i believe a series of escalating demonstrations is in order.

here's a box with a line of text in it.
and here is a div that appears, physically, between those two sentences. go on, check with inspect element
nothing weird here
<div style="border: 1px dashed black; height: 10em; padding: 0.5em 0.75em;">
  here's a box with a line of text in it.
  <div style="position: absolute; background: #eee; padding: 0.25em 0.5em;">
    and here is a div that appears, physically, <em>between</em> those two sentences.  go on, check with inspect element
  </div>
  nothing weird here
</div>

wooooaaahhhhh. so what happened here?

the lil guy in your browser got to that div and saw it was a block, so they stacked it underneath the previous line of text, as normal. however, since it's absolutely positioned, it has no effect on how anything else gets laid out. once the lil guy got past the div, they forgot all about it, and they placed the second line of text right next to the first line, just like any two inline bits next to each other.

(note that the box is also weirdly wide. there's a good reason for that. hold your horses)

anyway, you can see more concretely how this works if i make the text long enough to wrap, and put an opacity on the div:

here is a completely normal box with a line of text in it.
and here is a div that appears, physically, between those two sentences. go on, check with inspect element
nothing weird here, in fact i would say it is the most normal thing possible

ah! the text overlaps. and this is a common risk with absolute positioning, precisely because it gets pulled out of normal flow. it really does not care what else is going on outside of it.

so far this doesn't look very useful, unless you want to make overlapping text for some reason. but i can put inset or those four edge properties on an absolute element too. let's try bottom: 0.5em...

here's a box with a line of text in it.
and here is a div that appears, physically, between those two sentences. go on, check with inspect element
nothing weird here

oh no, where did it go?? (see if you can find it)

see, there's a special rule for positioning absolute elements: if you give them a position, it's not taken relative to the parent, like with position: relative;. it's relative to the nearest positioned ancestor. that means you go up through its parent and its parent's parent and so on, and you look for the first ancestor that is not position: static;, and that is the box whose edges are used as the baseline.

since the containing box above (the one with the dashed border) doesn't have a position property, it defaults to static, and it's not eligible. so the browser keeps searching outwards, and it will find... the element containing this entire post. and now you should be able to find the missing element.

and, surprise: this is what position: relative; is used for, 99.9% of the time! it's slapped on some parent element in order to say: hey, i've got an absolute box or two inside me somewhere, and i want it to position itself relative to me. here's what happens if i slap position: relative; on the container and change nothing else:

here's a box with a line of text in it.
and here is a div that appears, physically, between those two sentences. go on, check with inspect element
nothing weird here

hey hey! there it is. welcome back, little guy.

you may also notice that it's no longer weirdly wide! that's because, in the absence of any other properties telling it where the right edge should be, it acts like it has right: 0;. that puts the right edge flush with the edge of the nearest positioned ancestor — which previously was the post body, but now is the dashed container.

of course this is still a little ugly and i cannot resist fixing it by specifying more edges with inset: auto 0.5em 0.5em;, which you may recall is equivalent to top: auto; left: 0.5em; right: 0.5em; bottom: 0.5em;.

here's a box with a line of text in it.
and here is a div that appears, physically, between those two sentences. go on, check with inspect element
nothing weird here
<div style="position: relative; border: 1px dashed black; height: 10em; padding: 0.5em 0.75em;">
  here's a box with a line of text in it.
  <div style="position: absolute; inset: auto 0.5em 0.5em; background: #eee; padding: 0.25em 0.5em;">
    and here is a div that appears, physically, <em>between</em> those two sentences.  go on, check with inspect element
  </div>
  nothing weird here
</div>

note a cool, but slightly subtle property of absolute positioning here: i only gave a bottom and not a top, and the element is only as tall as it needs to be. (of course, if the rest of the text were long enough, it would still overlap. absolute positioning requires some careful consideration of how big you expect things to be.)

the general idea is that there are now three properties in each direction that are all vying for attention: top + height + bottom, and left + width + right. the idea is that you can give whatever subset of these you want, and the rest will be determined automatically. (i am not sure what happens if you give all three in a conflicting way but it's probably not helpful.) for example, you can give a width and one edge, and leave the other edge automatic:

i'm leaving out the text this time since it really doesn't matter, the point is that there's a box. wait i guess by typing this i'm not leaving the text out at all. dammit
top: 1em;
bottom: 1em;
right: 0.5em;
width: 50%;

that's right baby: percentages do work on absolute elements, both in theory and practice. an absolute box has no impact on how its parents are drawn, so there's nothing complicated about using percentages here; the browser just figures out the size of the parents, then bases the size of the absolute box on that.

but wait! there's other positions!

fixed positioning

i'm actually not allowed to show you this one because @staff specifically strips it out of posts. but it's like position: absolute;, except instead of the edge properties being relative to any particular parent, they are always relative to the viewport. so this is how you'd make one of those header bars that sticks to the top of the screen no matter how where you scroll.

i'm sure you can imagine why this is no longer allowed on cohost

sticky positioning

this is the most recent addition by far, and it is actually pretty cool. it's uhhh kind of weird to describe, like a hybrid of relative and absolute and fixed positioning but for scrolling areas— okay look lemme just show you

Welcome To Scrolling Area

ohhh daaaannnggg this box is gonna have a lot of text i bet

like i can't even imagine how far down it might go

luckily there's a scrollbar

oh wait i didn't explain how to make scrolling areas yet

well we'll get to that in a minute i guess

but it's kind of important for this property so i'm cheating and skipping ahead

Deal W It :sunglasses:

yeah see so it's kind of like position: fixed; in that it stays in one position without caring about where you scroll to...

but it's also like position: relative; because it is part of regular layout, it just gets displaced.

and the funky part is that it only gets displaced once it would be scrolled out of view, in a direction given by which edge properties you set. i gave that one top: 0;, so it "sticks" to the top edge of the scrolling region, once you scroll below its normal position.

i actually don't know the precise rules, but several times now i've slapped position: sticky; top: 0; on something and it's just worked exactly how i wanted. it's kind of great. you can even put it on like table rows, to keep the table header visible as you scroll down! and it won't "stick" beyond the top of its parent, so if you scroll entirely past the table, it goes away. i love it. it seems so niche but when you want it, you really want it

i guess i should tell you about overflow now

right, so, how did I even make a box with a scrollbar?? that's pretty easy actually: there's a property called overflow that says what to do when there's too much stuff in a box.

i forced this to happen above: all the dashed containers have height: 10em;, but i put in a bunch of paragraphs that would end up being way more than 10em tall. but it can also happen naturally, such as by having an unexpectedly long word appear in a small area.

did you know? the state fish of Hawai‘i is the humuhumunukunukuāpuaʻa

yeah, like that. cohost actually fixes that particular problem with a newer property, so i had to unfix it to make that happen

anyway on to the properties

overflow

this is the big one, the one that lets you have scrollbars. basically you can set it to

  • visible: the default behavior, where stuff overflows and you can see it and that's that

  • hidden: anything that escapes its box is just cut off and not drawn

  • auto: if something would overflow this box, slap a scrollbar on

  • scroll: there are always scrollbars, which are disabled unless necessary. this is usually ugly but it has historically been used to avoid having quantum scrollbars possibly eat part of the box's inner dimensions. of course now it seems like browsers use those mobile-like overlay scrollbars exclusively, so, this doesn't really matter any more

there's also a clip value, which seems to be like hidden except you can specify exactly where the line is where stuff gets sliced off. i don't know why you would care so much about that but you can do it apparently.

this is pretty straightforward and you will rarely ever do anything other than overflow: hidden; (spite) or overflow: auto; (scrollbars)

you can also specify different behavior horizontally vs vertically, by either giving two values or setting overflow-x and overflow-y separately, but like, why, man

overflow-wrap

this is the guy that forces words to break if necessary to avoid overflow: overflow-wrap: break-word;. it's already on cohost posts by default so you basically don't have to care about it unless you're writing a css guide and need to turn it off to show why someone might want to turn it on. (turn it off by setting it back to normal.)

text-overflow

this one's kind of cool. well. it's cool that browsers can do it, and it's better than not doing it in some cases, but the results can be unfortunate. lemme just—

did you know? the state fish of Hawai‘i is the humuhumunukunukuāpuaʻa

perhaps you can see what i mean. it's very aesthetically satisfying that the text no longer escapes the box, but, uhh... now you can't... see... what it says.

so you might want to make the text available some other way if you're gonna do this. i guess the common case is for a title in a grid of thumbnails or something, where you can also put a tooltip with the full title.

anyway the property is text-overflow: ellipsis;. you can also give a string to specify what to use for the cutoff instead of an ellipsis, but this won't work in legacy browsers like chrome. haha, zing.

note that this only works if you also use overflow: hidden; — this puts an ellipsis where the text cuts off, so if it doesn't actually cut off, nothing happens.

white-space

this controls how text breaks on whitespace:

  • white-space: nowrap; will never break and will effectively put your text as a single line, unless you use <br> explicitly

  • white-space: pre; acts like the <pre> ("preformatted") tag and preserves whitespace exactly as it's written in the HTML. (normally, line breaks and excess spaces in HTML are collapsed to a single space.) it will also never break.

  • white-space: pre-wrap; is like pre, but it will break lines if necessary. this is a cool middle ground that i use sometimes

there's a couple others but these are the main ones. in particular, nowrap pairs well with text-overflow.

boy, that got a bit dry for a while there! let's do something with a big colorful box.

practical example

we now know more than enough to pick apart my newest iteration of <aside>:

there's not a lot to it. the border and box-shadow you already know about. (the shaded bit on the left is just a second inset box shadow.)

the interesting part is the emoji peeking out of the box, but that's pretty easy. the box itself has position: relative;, of course. then the emoji has

  display: block;
  position: absolute;
  transform: rotate(-15deg);
  width: 4em;
  margin: 0;
  left: -2.5em;
  top: 1em;

and i don't think any of this will be very surprising. (the margin: 0; is to override cohost's default CSS, which expects an image to be a block on its own with margins above and below.) it overlaps the edge of the box because i said left: -2.5em, which puts its left edge 2.5em outside the reference box... but the emoji itself is 4em wide, so it sticks partway in.

the text along the top works the same way, although i gave it a few stacked text-shadows so it's still readable with the border running through it.

i mean that's basically it. you already know everything else from previous installments! wow, look at the big brain on you already

one more thing

before we leave positioning behind, there's one subtle trick i want to call out. recall my very first example:

here's a box with a line of text in it.
and here is a div that appears, physically, between those two sentences. go on, check with inspect element
nothing weird here

the absolute box has no edge properties here. without them, its top left corner goes exactly where it would have gone, if it weren't absolutely positioned.

and if you only set the horizontal edges or only set the vertical edges, the other edge will remain in this "default" position!

every so often, you might find a compelling reason to use this. for example, this absolutely-positioned dingbat will stay horizontally aligned with its "original" position in the text, because i never told it to move vertically:

it would be pretty convenient to have a long block of example text to use here, like i could pull out a lorem ipsum generator maybe? but honestly i'm kind of tired right now and opening a new tab feels like more effort than just rambling into an element that doesn't need to say anything in particular. [heart exclamation mark] that's where the dingbat actually is by the way, it's between the brackets

it only comes up once in a while, but when it does, it feels galaxy brain to be able to do this. another handy use is for stuff that only shows on hover... but we can't do that on cohost.

also, i did move the dingbat vertically a bit up there, but i didn't use top. instead i used margin-top, because margins on an absolute box will shift it around independently of its inset. you can use this to, say, center an absolute element on the border of its container. although nowadays you can often just use calc() the same way.

and now, you know most of how the row of navigation buttons on these posts works. the giant numbers are just absolute positioning. the "your here" label uses absolute positioning to keep the label the same width as its relative parent (which is the default!) but move it outside.

actually putting that stuff in a row takes a bit more effort still. wait til part 4.

LAYERING

now that we have touched upon the fact that absolute boxes can overlap stuff, a question arises. if two things overlap — something it seems we might even want to do on purpose at times — then which goes on top?

luckily, the default behavior is pretty straightforward. a later sibling appears above an earlier sibling. all children appear above their parent. that's it.

(well, almost. all positioned boxes also appear above all non-positioned boxes. that's pretty sensible; if you slap position: absolute; on something then you probably want it above normal text.)

let me, uhh, see if i can rig a 3d diagram of this

1
1a
1b
2
2a

that's not very 3d. i'm super good at css i'm sure i can—

1
1a
1b
2
2a

yeah. okay. beautiful.

(i used negative margins here to overlap these, which might be instructive to inspect with devtools.)

i think that makes sense. stuff that comes later goes on top. it's like the little guy in your browser puts each box on the screen in the order they appear, so every time they see a new box, they just put it on top of all the other boxes.

alright so what if i want 1a to be on top, but i have compelling reasons to not rearrange the elements? enter z-index.

1
1a, now with a z-index of 1
1b
2
2a

z-index takes something out of the usual order and puts it on its own numbered layer, where the default layer is number 0. so by giving box 1a z-index: 1;, i've raised it above everything else on layer 0.

within a layer, i'm pretty sure the usual ordering applies. so if i also put z-index: 1; on box 2, it would once again appear above 1a. (use devtools and try it!)

you can also use negative layers, which can be used to put a box underneath its own parent. this is usually done for goofy visual effects involving the parent's background.

also, this only works on positioned boxes, i.e. not position: static;. but once again, position: relative; can come to the rescue and enable z-index without actually moving the box around.

cool. easy, right?

well,

it is a little complicated. but good news: it is no longer as complicated as it once was.

the problem that arises, which i think is a pretty reasonable problem, is this: what happens when a box with a z-index has children?

like, imagine my rainbow assortment of elements above. i used z-index: 1; to move one of them to the foreground. sure. but what happens if i want to put the whole collection inside some other element?

and what if the element i want to put them inside already has z-index: 5;?

whoops. now by saying z-index: 1;, it seems like i'm asking box 1a to draw behind everything else. but... everything else was layer 0. right? what?

that behavior wouldn't make any goddamn sense at all, so the wizards at CSS Inc. had the foresight to solve this problem by having the layers be nestable.

1 (z-index: 1)
1a (z-index: 9)
1b (z-index: 9)
2 (z-index: 2)
2a (z-index: 4)

what actually happens is that putting z-index on a box creates a thing called a "stacking context". the phrase strikes dread into the hearts of many CSS users for reasons i will get to shortly, but it really means two things:

  1. everything on the inside gets layered on its own, and then all that stuff acts like a single layer on the outside. as a result, nothing on the outside can be layered between two boxes on the inside.

  2. the layer numbering on the inside is completely independent of any layer numbering on the outside.

you can see this in the diagram, where i've given everyone a z-index.

  • boxes 1a and 1b have the same z-index, so they stack in the default order.

  • box 2 is above box 1, because it has a higher z-index.

  • boxes 1a and 1b do NOT stack above box 2a, despite having a higher z-index, because they're insulated within the stacking context created by box 1.

compare with what happens if i remove the z-index from boxes 1 and 2:

1
1a (z-index: 9)
1b (z-index: 9)
2
2a (z-index: 4)

box 1 no longer creates a stacking context, so it and its children are free to interleave with other boxes.

the wrinkly part

this was a headache for a long time, because the set of properties that create a stacking context was kind of a mess of special cases that no one could remember. so it was hard to make a new stacking context when that was specifically what you wanted, and it was much harder to understand at a glance which elements were creating stacking contexts.

and this is something you only care about once in a blue moon so it tended to fall out of your head anyway.

luckily, they finally made a property that just creates a stacking context and nothing else: isolation: isolate;. it's like making a new layer group.

hope all of that makes sense lol

consequences

because boxes are layered individually, it's impossible to make something like this:

A
A
B
C
D

hmmm! i sure wonder how i did that, then.

moving right along—

floats

here's a cool tip: dont use floats!

there is some history here.

tengu_maskTIP: To defeat the cyberdemon, shoot at it until it dies.

floats were designed for doing like a magazine "floated image" sort of thing. in fact they were based on the original html 2.0 or something <IMG ALIGN=RIGHT> attribute. a lot about html is designed from a sort of "magazine article" perspective, and i think the whole subject makes more sense if you think about it like that. so then when they designed CSS, which was meant to get "style" out of HTML, it sort of inherited this capability as the float property.

paw hand with crossed fingers (light pink)

and that's fine because if you really do just want a little magazine inset with text wrapping around it, it does exactly that. the problem is that circa 2000 we didn't really have a lot of layout tools in CSS, but some madmen discovered you could slap float on anything, and off we went. entire websites were built out of them, out of floating boxes that weren't really floating around anything. some websites, if you resized them just right, the entire website would drop below the sidebar. it was a fucking nightmare.

worst of all was when you tried to use it for smaller pieces of a page, like putting an avatar on the side of a comment. because now you had the problem that if the float was taller than the rest of the box, it would just stick out the bottom and possibly fuck up text in the next box down. and to fix this you would have to do some unholy thing like

.clearfix:after {
    visibility: hidden;
    display: block;
    font-size: 0;
    content: " ";
    clear: both;
    height: 0;
}

and that's assuming it actually worked in your target browsers; sometimes it wouldn't and you'd need more nonsense for that.

nowadays you can just do display: flow-root; or use the newfangled contain property to enforce that floats can't escape a box, but frankly it's easier to just not use them unless you're pretty dang sure they won't do any damage.

it's float: left; or float: right;, and you can also put clear: both; (or just left/right) on an element to make it drop below any neighboring floats, which is how the "clearfix" thing works.

but unless the exact specific thing you're doing is to wrap the lines of a paragraph snugly around an inset box, don't use floats. thanks

AT LONG LAST: THE DETAILS ELEMENT (CLICKABLE STUFF)

this one sure did get kinda long boy howdy! positioning is complicated. we haven't even gotten to the new shiny stuff yet! this is all baseline 2001 web development. you had to make an entire website out of only the stuff here. good luck

anyway time for something new and fun: the <details> element. this is an html5 addition that lets you have a collapsible section. it is the reason i get mad every time i find a fucking FAQ page that only shows the questions because it uses javascript to show the answers. come on. we've got this built in now. also why would you hide the answers by default? this would work fine without god damn javascript if you j

right right okay sure. here it is, with no CSS whatsoever, except a border for clarity:

Who lives in a pineapple under the sea?

No one. Pineapples are not native to the ocean floor.

<details style="border: 1px solid gold;">
  <summary>Who lives in a pineapple under the sea?</summary>
  <p>No one.  Pineapples are not native to the ocean floor.</p>
</details>

you can click on the line with the chevron (the <summary>) to toggle the visibility of its contents. you can also do <details open> to have it start out opened already.

and that's it, that's the whole thing.

that's cool and all. but it's of particular interest on cohost because it allows us to engage in some manner of shenanigans.

consider the following, which you may click at your leisure.

smiling smiley angry_steam
<details style="position: relative; font-size: 4em; width: 1em; margin: 0 auto; cursor: pointer;">
  <summary style="list-style: none;">
    <img src="https://lxhom.github.io/mutant-html/assets/svg/smile.svg#generated_with_https://mutant.us.to/" alt="smiling smiley" title="smiling smiley" style="width: 1em; margin: 0; display: block;">
  </summary>
  <img src="https://lxhom.github.io/mutant-html/assets/svg/angry_steam.svg#generated_with_https://mutant.us.to/" alt="angry_steam" title="angry_steam" style="width: 1em; margin: 0; display: block; position: absolute; top: 0; pointer-events: none;">
</details>

this could be better but i want you to get the idea. here's what is happening.

  • the details element has relative positioning and a fixed size. it also has cursor: pointer; to give people with mice a hint that you can click it.

  • the summary element contains a single image. it has list-style: none; to hide the chevron. (note that this doesn't work in safari. there's a trick to use font-size: 0; to make the chevron 0 pixels tall, then change the font size back for the actual text, but it complicates things too much for this example.)

  • the only other child is another image, with position: absolute; top: 0;. when the details element is opened, this image now appears overlaid atop the original image.

  • the second image also has pointer-events: none;, a funny property that makes it completely invisible to the mouse (as well as touchscreen stuff). so if you try to click it, the click goes through it to whatever's underneath... which is the summary element. and clicking that makes the second image disappear again.

this perhaps seems a bit simple and clumsy, but it's the secret behind every single clickable css crime you've seen on cohost. anything you can click is a summary element, and the rest is doing nonsense with toggling visible contents to get the desired effect.

my minesweeper, for example? every cell is a details, where the part you click is a summary. the visible contents are whatever part of the grid clicking that cell ought to reveal, absolutely positioned in the right place. it's absurd and it means a lot of duplication, and i had to write a horrible python script to generate it for me, but it works!

going into great detail about how to add some more polish, or do other things that seem impossible even after i've already done them, is probably far beyond the scope of this series. but maybe i'll write up something separate about how my crimes work one day.

well, okay. one more little example to get your gears turning. you can make something that disappears entirely on click:

cross
<details open style="position: relative; cursor: pointer;">
  <summary style="list-style: none; position: absolute; inset: 0;"></summary>
  <img src="https://lxhom.github.io/mutant-html/assets/svg/cross.svg#generated_with_https://mutant.us.to/" alt="cross" title="cross" style="width: 4em; margin: 0 auto;"/>
</details>

this time, the details is already open. the summary is empty, but it's absolutely positioned with inset: 0; — which will make it exactly the same size as its (still relative) parent. and then the rest of the contents are the X image.

the summary is layered on top even though it's earlier, because it's positioned and the X isn't — but the summary is empty, so it's just a big transparent click zone. and then when you click on it, the X vanishes, the details collapses to zero height, and the summary shrinks to match, so the whole thing effectively disappears.

you could even control the size of the summary to make something that only vanishes when you click a particular area. hmmmm.


that's all she wrote! for now. sorry this took so long; it's kinda dry in places and i've been endlessly busy. hopefully flex/grid will be a bit more fun to explore.

go forth and make some nonsense. be sure to tag it #css crimes so i see it.

thanks for readin', hope it helps!

  1. 1

    text stuff mostly
  2. 2

    boxes, transform
  3. 3

    positioning, clicking stuff
    🌟 your here 🌟
  4. 4

    flexbox and grid
  5. 5

    animation and other nonsense

oops gotta leave some space for that lost little guy down here


You must log in to comment.

in reply to @lexyeevee's post:

This is great. I'm a pretty vanilla HTML/CSS user; my only concern is being able to get poetry excerpts to look OK. But it's wonderful how cohost has become a place where people can do weird and wonderful things with their posts, and equally wonderful that you're teaching people how to do it.

nowadays you can just do display: flow-root; or use the newfangled contain property to enforce that floats can't escape a box

Woah, I've never heard about this before. I've still been using clear: both; for things.

Also oh my god I didn't know we had details/summary either. We can do spoiler warnings without javascript! We can do CONTENT WARNINGS without javascript. YOU HEAR THAT MASTODON--

"overflow: clip" is like hidden, but it's not scrollable.

That is, "hidden" still let's you scroll the content. There's no scrollbar, but you can use el.scrollTo() or whatever. All custom scrollbars are done like that. But if you're not gonna scroll it, then making it a "scroll container" has consequences, which you may or may not want.

So "clip" doesn't make it scrollable. It just clips. Done.


Abspos is fun and all but as you explained, it's pretty limited since it can barely respond to what's around if. Enter the new cool shit Anchor Positioning. (Chrome's impl was just about to ship, but csswg is having a f2f meeting this week where there might be some changes proposed that'll delay it a bit. We'll see.)

ahh, that was not clear from mdn. it did seem weird as hell to make a new variant of hidden just so it could interact with a new property. i guess i should err on the side of clip once i'm confident it works everywhere then


holy moly. this is a lot. everybody gangsta til the new positioning scheme introduces new @-rules

in one of your previous posts you had an image of those overlapping boxes in the "consequences" section, and i took the "this is impossible to do in CSS" as a challenge and eventually did figure out how to do it with 3D transforms, i'll have to dig up the CSS for it at some point and put it in a post

I'm a CSS veteran but this series is great. It's always good to refresh. There's always something you forgot, misunderstood, or just plain missed that you can learn anew.

I spent probably fully two hours reading this whole series this morning but I’m willing to defend that use of my on-the-clock time as Professional Development. This is all excellent, thank you for taking I know must have been a horrifying amount of time to draft it!