translating things, building chill software for my friends, playing ttrpgs, making procedural vector art, learning piano, writing unhinged Utena fanfics, and just vibing



xenofem
@xenofem

i saw @mojilove-j doing some fun posts using CSS's functionality for vertical text, and i was curious what'd happen if i wrote something too long to fit within the width of the chost. what i think would be ideal is for it to basically work like multi-column text, but with rows instead of columns: each line of vertical text has a fixed limited length that ideally fits within a screen without scrolling; when there's enough lines to fill the width of the container, we move down and start a new row of lines with a little gap to separate it from the first row of lines. CSS's multi-column functionality seems to work basically like this with vertical text... as long as you know exactly how many "columns" (rows) you're going to have. even if that weren't dependent on screen size etc, i'd rather not have to count it out manually. but if i just specify column-width and not column-count, for some reason, my browser decides that the height of the div is just the height of a single "column", and all the remaining "columns" end up as overflow. for instance, here's the first chapter of Night on the Galactic Railroad, with overflow-y: scroll so it's easier to actually see the overflowing parts without it messing up the text below:

一 午後の授業


「ではみなさん、さういふふうに川だと云はれたり、乳の流れたあとだと云はれたりしてゐた、このぼんやりと白いものが何かご承知ですか。」
 先生は、黒板に吊した大きな黒い星座の圖の、上から下へ白くけぶつた銀河帶のやうなところを指しながら、みんなに問ひをかけました。
 カムパネルラが手をあげました。それから四五人手をあげました。ジヨバンニも手をあげようとして、急いでそのままやめました。
 たしかにあれがみんな星だと、いつか雜誌で讀んだのでしたが、このごろはジヨバンニはまるで毎日教室でもねむく、本を讀むひまも讀む本もないので、なんだかどんなこともよくわからないといふ氣持がするのでした。
 ところが先生は早くもそれを見附けたのでした。
「ジヨバンニさん。あなたはわかつてゐるのでせう。」
 ジヨバンニは勢よく立ちあがりましたが、立つて見るともうはつきりとそれを答へることができないのでした。ザネリが前の席から、ふりかへつて、ジヨバンニを見てくすつとわらひました。ジヨバンニはもうどぎまぎしてまつ赤になつてしまひました。
 先生がまた云ひました。
「大きな望遠鏡で銀河をよつく調べると銀河は大體何でせう。」
 やつぱり星だとジヨバンニは思ひましたが、こんどもすぐに答へることができませんでした。
 先生はしばらく困つたやうすでしたが、眼をカムパネルラの方へ向けて、
「ではカムパネルラさん。」と名指しました。
 するとあんなに元氣に手をあげたカムパネルラが、もぢもぢ立ち上つたままやはり答へができませんでした。
 先生は意外のやうにしばらくぢつとカムパネルラを見てゐましたが、急いで、
「では。よし。」と云ひながら、自分で星圖を指しました。
「このぼんやりと白い銀河を大きないい望遠鏡で見ますと、もうたくさんの小さな星に見えるのです。ジヨバンニさんさうでせう。」
 ジヨバンニはまつ赤になつてうなづきました。けれどもいつかジヨバンニの眼のなかには涙がいつぱいになりました。さうだ僕は知つてゐたのだ、勿論カムパネルラも知つてゐる、それはいつかカムパネルラのお父さんの博士のうちでカムパネルラといつしよに讀んだ雜誌のなかにあつたのだ。それどこでなくカムパネルラは、その雜誌を讀むと、すぐお父さんの書齋から巨きな本をもつてきて、ぎんがといふところをひろげ、まつ黒な頁いつぱいに白い點々のある美しい寫眞を二人でいつまでも見たのでした。
 それをカムパネルラが忘れる筈もなかつたのに、すぐ返事をしなかつたのは、このごろぼくが、朝にも午後にも仕事がつらく、學校に出てももうみんなともはきはき遊ばず、カムパネルラともあんまり物を云はないやうになつたので、カムパネルラがそれを知つて氣の毒がつてわざと返事をしなかつたのだ。
 さう考へるとたまらないほど、じぶんもカムパネルラもあはれなやうな氣がするのでした。
 先生はまた云ひました。
「ですからもしもこの天の川がほんたうに川だと考へるなら、その一つ一つの小さな星はみんなその川のそこの砂や砂利の粒にもあたるわけです。またこれを巨きな乳の流れと考へるなら、もつと天の川とよく似てゐます。つまりその星はみな、乳のなかにまるで細かにうかんでゐる脂油の球にもあたるのです。そんなら何がその川の水にあたるかと云ひますと、それは眞空といふ光をある速さで傳へるもので、太陽や地球もやつぱりそのなかに浮んでゐるのです。
 つまりは私どもも天の川の水のなかに棲んでゐるわけです。そしてその天の川の水のなかから四方を見ると、ちやうど水が深いほど青く見えるやうに、天の川の底の深く遠いところほど星がたくさん集つて見え、したがつて白くぼんやり見えるのです。この模型をごらんなさい。」
 先生は中にたくさん光る砂のつぶの入つた大きな兩面の凸レンズを指しました。
「天の川の形はちやうどこんななのです。このいちいちの光るつぶがみんな私どもの太陽と同じやうにじぶんで光つてゐる星だと考へます。私どもの太陽がこのほぼ中ごろにあつて地球がそのすぐ近くにあるとします。みなさんは夜にこのまん中に立つてこのレンズの中を見まはすとしてごらんなさい。こつちの方はレンズが薄いのでわずかの光る粒即ち星しか見えないのでせう。こつちやこつちの方はガラスが厚いので、光る粒即ち星がたくさん見え、その遠いのはぼうつと白く見えるといふ、これがつまり今日の銀河の説なのです。そんならこのレンズの大きさがどれ位あるか、またその中のさまざまの星についてはもう時間ですから、この次の理科の時間にお話します。では今日はその銀河のお祭なのですから、みなさんは外へでてよくそらをごらんなさい。ではここまでです。本やノートをおしまひなさい。」
 そして教室中はしばらく机の蓋をあけたりしめたり本を重ねたりする音がいつぱいでしたが、まもなくみんなはきちんと立つて禮をすると教室を出ました。

the full set of style rules i'm using here is

writing-mode: vertical-rl;
width: 100%;
column-width: 30rem;
column-fill: auto;
overflow-y: scroll;

writing-mode: vertical-rl; does what it says on the tin. width: 100%; and column-fill: auto; have it fill the first "column" until it takes up the full width of the container, and then start filling the next column, etc; the default is to try to give all the columns the same number of lines. setting column-width: 30rem; and not setting column-count means it'll create as many 30rem-tall1 columns as it needs to fit all the text.

i went on another CSS spec dive to try and figure out what's going on, and i think the overflow might be related to this section on breaking boxes2:

Intrinsic sizes are calculated and maintained across the entire element. Where an initial containing block size is needed to resolve an intrinsic size, assume the size of the first fragmentainer defining a fragmentation context.

basically, when i'm using multi-column text in CSS, that creates a "fragmentation context" where each column is a "fragmentation container" or "fragmentainer" (that's the official technical term, i'm not joking). when content would overflow a fragmentainer, the excess goes into the next fragmentainer, and so on. and it sounds like when the browser needs to know the size of the div as a whole, but doesn't know how many columns there are (possibly because the size of the div is part of the calculation for how many columns there'll be), it just decides that the size of the div is the size of the first fragmentainer on its own?

things i've tried so far:

  • height: max-content; – no effect. seems like the "intrinsic preferred height" is also just the height of the first fragmentainer?
  • column-count: 10; or some other large number. when column-width is also set, column-count should define the maximum number of columns, so i hoped this would maybe help the browser take the hint that there's more than one column, but not actually produce extra empty columns? what actually seems to happen is that the height of the div is now approximately one viewport-height worth of columns, regardless of whether that's longer or shorter than the actual number of columns of text.
  • column-count: 10; and height: max-content; – somewhat predictably, the div is now 10 columns tall, with a bunch of empty columns at the end.
  • height: fit-content; seems to be the same as just leaving height unset in this case.

not really sure what else i could try in order to accomplish what i actually want (get the div height to fit the exact number of columns i actually end up using, without me needing to know the exact number of columns). it's frustrating because with overflow-y: scroll; there's this nice little scrollbox, the browser clearly does know how tall the content actually is, i just can't get it to properly act on that information. if anyone's got ideas, i'd love to hear them!

(fallback idea: ditch the multicolumn stuff altogether, just put it all in one row and set overflow-x: scroll and make sure the scrollbar starts all the way to the right, so readers can scroll horizontally to the left through the vertical text and then scroll vertically down the timeline when they're done. i honestly don't hate it lol, but i still do wanna find out if there's a way to do my first idea)


  1. or possibly a slightly different height for Reasons

  2. note to self: pitch netflix on a drama series about a frustrated computer science teacher who goes deeper and deeper into the seedy, violent world of CSS crimes


xenofem
@xenofem

"let's make our own multi-row layout using regions!"

haha nice try

"let's make our own multi-row layout using flexbox!"

turns out flexbox also hates vertical layouts? and what "vertical" actually means is "block-axis", so if we do

<div style="
  writing-mode: vertical-rl;
  width: 100%;
  display: flex;
  flex-flow: column wrap;
  justify-content: flex-start;
">

then the flexbox won't expand its height to accommodate the wrapped "columns" (rows). I can do

<div style="
  width: 100%;
  display: flex;
  flex-flow: row-reverse wrap;
  justify-content: flex-start;
">

and then individually set writing-mode: vertical-rl; on every single <p> inside the <div> (i'm already individually setting height: 30rem; margin-top: 0; margin-bottom: 0;, so it's not much additional hassle :p). that does mostly work, but it still means that a paragraph can never be split across rows, which looks real awkward when there's a long paragraph at the end of a row.

I could go absolute sicko mode and take advantage of the fact that Japanese text is fixed-width – ditch the height: 30rem bit altogether, and just split all of the text into <div>s each of which contains exactly 30 characters (or fewer if it's the end of a paragraph). that would work, but would be a) horrible, b) a huge pain, and c) would get awkward if i ever wanted to include any English text in the middle of the vertical Japanese text. i guess i could just only use fullーwidth letters?

honestly the single-row horizontal scroll really is the only workable option i actually like, i'm giving up on poking at the multi-row thing :eggbug-pensive:

web technology is real weird huh


You must log in to comment.

in reply to @xenofem's post:

i only dabbled a little in this, but soon found myself way over my head when trying to do anything multi-column in a way that I liked (and that didn't need prior knowledge about the final appearance of the text, like the number of columns). I also wanted to do that one row overflow-x: scroll setup myself but I never figured out how to get it to start at the very right... vertical text layouts are an uphill struggle all the way. Hope you find a solution!!

thanks! i can't actually think of anything i'd write if i did get this working lol, but i'm just really curious at this point if i can make the "columns" work somehow. i hadn't tried the single-row approach before chosting, but the scroll actually seems to be starting at the right for me just fine with writing-mode: vertical-rl; width: 100%; height: 30rem; overflow-x: scroll;, at least in desktop Firefox? so, nice to know i've always got that option at least (assuming other browsers also do the right thing with those rules)