chat: the copy buttons sit on the code block, bottom right
they were sticky at the top, which put them over the first line — and on a one-line block, which is most of them in a chat, over the whole thing. absolute bottom-right inside the surface now, with `.code-surface` given the `position: relative` it never had. that omission is why a control could end up escaping to the nearest positioned ancestor and floating below the block it belongs to. `padding-bottom` on the pre to go with the existing `padding-right`: the last line is the one they overlap now, and it needs its own room the same way the first line needed it before. the trade the old comment was worried about is real but smaller than it reads: a block taller than the viewport now has its controls at the bottom rather than the top. that is where you end up after reading it anyway, and it is a worse place to be only for a block you never scroll — which is exactly the block whose first line the old position was covering.
This commit is contained in:
@@ -169,8 +169,11 @@
|
||||
.code-surface pre {
|
||||
margin: 0;
|
||||
padding: 0.75em 1em;
|
||||
/* Room for the two copy buttons, so a long first line scrolls up to them rather than under them. */
|
||||
/* Room for the copy controls, which sit absolutely at the bottom-right of the block. Horizontal so a
|
||||
long line scrolls past them rather than under them; vertical so the LAST line — the one they now
|
||||
overlap — keeps its own space. */
|
||||
padding-right: 5.5em;
|
||||
padding-bottom: 2em;
|
||||
border-radius: 0.5rem;
|
||||
background: #0d1117;
|
||||
/* Scroll, never wrap: wrapping folds `ls -la`, `git log --oneline` and any other columnar output into
|
||||
@@ -186,6 +189,12 @@
|
||||
padding-right: 10em;
|
||||
}
|
||||
|
||||
/* The positioning context for those controls. Without it they escape to the nearest positioned ancestor,
|
||||
which is how a copy button ends up floating below the block it belongs to. */
|
||||
.code-surface {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.code-surface pre code {
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
|
||||
@@ -108,17 +108,18 @@ export const CodeSurface = ({ code, lang = '', startLine = 1, maxLines, numbered
|
||||
style={{ '--line-digits': digits, '--line-offset': startLine - 1 } as CSSProperties}
|
||||
>
|
||||
{code && (
|
||||
// Sticky, not absolute, and first in the flow so it has a flow position to stick to. A block
|
||||
// taller than its scroll container — a live log tail, a 400-line read — used to carry its
|
||||
// controls off the top edge, so the output you most want to copy was the one whose copy button
|
||||
// you had to scroll back up to find. `h-0` keeps the row out of the vertical flow: it overlays
|
||||
// the top of the block rather than pushing it down, which is what the old `absolute` did.
|
||||
// Absolute, bottom-right, INSIDE the block — the controls belong to the code, so they sit on it
|
||||
// rather than after it. `.code-surface` is `position: relative` for this (prose.css).
|
||||
//
|
||||
// Bottom rather than top: a copy button over the FIRST line covers the thing you are most likely
|
||||
// to be reading, and on a one-line block — a single command, which is most of them here — it
|
||||
// covers the whole thing.
|
||||
//
|
||||
// Always visible, not hover-revealed: a control you have to discover by waving the pointer at it
|
||||
// is a control most people never find, and on touch there is no hover to find it with at all. Two
|
||||
// buttons rather than one with a modifier — the destination decides which you want (a terminal, or
|
||||
// someone else's markdown), and a modifier nobody can see is a feature nobody uses.
|
||||
<div className="sticky top-1.5 z-10 flex h-0 items-start justify-end gap-1.5 pr-1.5">
|
||||
<div className="absolute right-1.5 bottom-1.5 z-10 flex items-center gap-1.5">
|
||||
{lang && (
|
||||
<span className="rounded px-1 font-mono text-[10px] tracking-wide text-white/35 backdrop-blur-sm select-none">
|
||||
{lang}
|
||||
|
||||
Reference in New Issue
Block a user