mirror of https://github.com/requarks/wiki
parent
50adab2eac
commit
7ea92a982b
@ -0,0 +1,300 @@
|
|||||||
|
/*
|
||||||
|
THE PRINTED PAGE
|
||||||
|
================
|
||||||
|
|
||||||
|
What the page view and the version view become on paper. This file is the app SHELL's half of it --
|
||||||
|
the chrome a page is drawn in. Two other places hold the rest, each because the rules there have to
|
||||||
|
sit next to the ones they override: `_page-contents.scss` typesets the article, over the content
|
||||||
|
palette declared at the top of that same file, and `SiteBanner.vue` handles the banner, for the
|
||||||
|
cascade reason set out at the foot of this file.
|
||||||
|
|
||||||
|
Two problems, and they are different ones.
|
||||||
|
|
||||||
|
The first is that the shell IS a viewport. `WLayout` is `height: 100vh; overflow: hidden`, and the
|
||||||
|
article scrolls inside `.page-container-scrl` rather than the window -- which is what keeps the
|
||||||
|
header, the sidebar and the action rail still while a reader scrolls. On paper that means exactly one
|
||||||
|
screenful is printed and the rest of the page is clipped away with nothing to say it happened. So
|
||||||
|
every fixed height and every scroll container has to be unwound back into normal flow before
|
||||||
|
anything else here is worth doing.
|
||||||
|
|
||||||
|
The second is that most of what is on screen is not the document. Someone printing a page wants the
|
||||||
|
page: its title, where it sits, when it was last written to, and its contents. The navigation, the
|
||||||
|
contents column, the action rail, the footer and the floating buttons are how they GOT here, not
|
||||||
|
what they are taking away.
|
||||||
|
|
||||||
|
`!important` throughout, deliberately, and it is not laziness: what these rules overrule is inline
|
||||||
|
styles (both views write `height: 100%` on the article column in the markup) and scoped rules from
|
||||||
|
single-file components, which carry a data attribute and so outrank a plain class whatever the order.
|
||||||
|
A print stylesheet that loses those fights prints a blank sheet and gives no clue why.
|
||||||
|
|
||||||
|
Colours are the exception -- there `!important` would be the wrong tool, because the rules being
|
||||||
|
beaten are per-theme ones written as `.body--dark .page-header-title`. Naming both theme classes
|
||||||
|
matches that specificity, and `app.scss` loads this file last so the tie goes to print.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
/* ---------------------------------------------------------------------------
|
||||||
|
THE SHEET
|
||||||
|
--------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
The margin the content gets.
|
||||||
|
|
||||||
|
Nothing here draws a running header or a page number: the browser prints its own -- title, URL,
|
||||||
|
date, page count -- outside this margin, and they are the reader's to keep or turn off in the print
|
||||||
|
dialog. CSS could only compete with them, and not well, since no engine this app targets fills a
|
||||||
|
page margin box with the document's own URL.
|
||||||
|
*/
|
||||||
|
@page {
|
||||||
|
margin: 16mm 14mm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------
|
||||||
|
THE SHELL STOPS BEING A VIEWPORT
|
||||||
|
--------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
height: auto !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
/* -> Every layout paints `body` in the dark theme; on paper the sheet is the ground */
|
||||||
|
background: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The shell's grid becomes a stack.
|
||||||
|
|
||||||
|
Its three columns exist to seat the drawers beside the page, and both drawers are gone below -- but
|
||||||
|
that is not enough on its own: a grid item is stretched to its track, and the track is sized off a
|
||||||
|
viewport height that means nothing here.
|
||||||
|
*/
|
||||||
|
.w-layout--page,
|
||||||
|
.w-layout--container {
|
||||||
|
display: block !important;
|
||||||
|
height: auto !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
And every box between the shell and the article gives up whatever it was doing to make one screenful
|
||||||
|
fit -- the flex column, the claimed height, the scroll container. What is left is blocks in normal
|
||||||
|
flow, which is the only arrangement that can run over a page break.
|
||||||
|
*/
|
||||||
|
.w-page-container,
|
||||||
|
.w-page,
|
||||||
|
.page-container,
|
||||||
|
.page-container-scrl,
|
||||||
|
.page-container-body,
|
||||||
|
.w-scroll-area {
|
||||||
|
display: block !important;
|
||||||
|
height: auto !important;
|
||||||
|
min-height: 0 !important;
|
||||||
|
max-height: none !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
flex: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The article column's own padding goes: `@page` above is the margin now, and a second one inside it
|
||||||
|
only narrows the measure. `--content-bleed` is the padding this one is reaching back through (see
|
||||||
|
`_page-contents.scss`), so the print block there zeroes it to match -- left at 1rem the rule under
|
||||||
|
the page title would overhang the text by exactly the padding that is no longer there.
|
||||||
|
*/
|
||||||
|
.page-container-body {
|
||||||
|
/*
|
||||||
|
Sides only, so the article keeps the full measure -- but not the top.
|
||||||
|
|
||||||
|
`.page-contents > :first-child` has its top margin zeroed, since on screen the column's own
|
||||||
|
padding is the space above the article. With that padding gone the first block sat against the
|
||||||
|
header's rule, and a page opening on an h1 -- which is most of them -- put 22pt of display type
|
||||||
|
hard against a line drawn 2px thick. This is the margin that block would otherwise have brought
|
||||||
|
with it.
|
||||||
|
*/
|
||||||
|
padding: 1.25rem 0 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------
|
||||||
|
WHAT DOES NOT GO ON PAPER
|
||||||
|
--------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Navigation, the contents column, the action rail, the relation buttons under the article, the
|
||||||
|
footer, and every button that floats over the page -- all of them ways to go somewhere else, which
|
||||||
|
is the one thing a sheet of paper cannot do. The relations are the one that reads as content rather
|
||||||
|
than chrome, and they are not: they are the next page and the previous one, drawn as buttons.
|
||||||
|
|
||||||
|
The last five are the transient overlays, and they are here because printing is not a moment anyone
|
||||||
|
prepares for: a tooltip is on screen the instant the Print button is clicked, and Ctrl+P works just
|
||||||
|
as well with a dialog open. Each would otherwise print over the first page.
|
||||||
|
*/
|
||||||
|
.w-header,
|
||||||
|
.w-drawer,
|
||||||
|
.w-drawer-scrim,
|
||||||
|
.page-sidebar,
|
||||||
|
.page-sidebar-scrim,
|
||||||
|
.page-actions,
|
||||||
|
.page-header-actions,
|
||||||
|
.page-relations,
|
||||||
|
.w-footer,
|
||||||
|
.w-page-scroller,
|
||||||
|
.corner-btn,
|
||||||
|
.w-tooltip,
|
||||||
|
.w-menu,
|
||||||
|
.w-notifications,
|
||||||
|
.w-loading,
|
||||||
|
.w-dialog-backdrop,
|
||||||
|
.w-dialog-viewport {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------
|
||||||
|
WHAT DOES, FLATTENED
|
||||||
|
--------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
The title bar keeps the title, the description and the page's icon, and loses the gradient it sits
|
||||||
|
in. Its 95px is a measurement for a bar in a window; here it is a heading, so it takes the height of
|
||||||
|
what is in it and stays with the page it names.
|
||||||
|
*/
|
||||||
|
.page-header {
|
||||||
|
height: auto;
|
||||||
|
break-after: avoid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
And the words sit closer to the rule under them.
|
||||||
|
|
||||||
|
The 16px below the title column is pitched for a bar in a window, where the gradient it sits on is
|
||||||
|
what ends the header and the space is how the title is given room inside it. On paper the rule ends
|
||||||
|
the header, so the space under the words is doing nothing but pushing the article down the sheet.
|
||||||
|
Halved rather than dropped: the description still needs to clear the line under it.
|
||||||
|
|
||||||
|
Reached through `:has()` because the column is a stack of layout utilities and the two things in it
|
||||||
|
are the only stable names in the markup -- the same column, class for class, in both headers.
|
||||||
|
*/
|
||||||
|
.page-header > div:has(> .page-header-title) {
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -> Same: the trail says where this page lives, which is no use on the sheet before it */
|
||||||
|
.page-breadcrumbs {
|
||||||
|
break-after: avoid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The home crumb becomes the site's own mark.
|
||||||
|
|
||||||
|
On screen that first crumb is a house because it is a BUTTON -- the way back to the root of the
|
||||||
|
wiki. Nothing on a sheet of paper goes anywhere, so what is left is a house standing at the head of
|
||||||
|
a path for no reason. The favicon in its place answers the question a printout actually raises,
|
||||||
|
which is which wiki this page was printed from, and it does it in the width the house was already
|
||||||
|
taking.
|
||||||
|
|
||||||
|
Matched on `data-icon` rather than on the crumb's position: `WIcon` writes the reference it drew
|
||||||
|
onto every branch it renders, so this says "the home icon" instead of "whatever is first", and it
|
||||||
|
stops matching by itself if that crumb ever stops being a house.
|
||||||
|
|
||||||
|
Drawn as a background on the link rather than swapped in the markup, because the swap is a
|
||||||
|
statement about paper and nothing else -- `WBreadcrumbs` is a shared component and this is not a
|
||||||
|
behaviour worth giving it a prop for. `print-color-adjust` because a background is exactly what a
|
||||||
|
print dialog drops by default, and the whole point here is that the mark appears.
|
||||||
|
|
||||||
|
1.25em is the house's own size: `.w-breadcrumbs__el-icon` sets 125%, so the glyph draws at 1.25em
|
||||||
|
of the bar's text. The crumb carries no label, so it needs no margin either.
|
||||||
|
*/
|
||||||
|
.page-breadcrumbs [data-icon='la:home'] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.page-breadcrumbs .w-breadcrumbs__el:has([data-icon='la:home'])::before {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
width: 1.25em;
|
||||||
|
height: 1.25em;
|
||||||
|
background-image: url('/_site/current/favicon');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
background-size: contain;
|
||||||
|
print-color-adjust: exact;
|
||||||
|
-webkit-print-color-adjust: exact;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The indigo frame the version view draws down both sides and along the bottom goes.
|
||||||
|
|
||||||
|
On screen it is a surround sized to the window and drawn once, and it is how that view says a
|
||||||
|
snapshot is being read. On paper there is no window to frame: it becomes a 5px band of colour down
|
||||||
|
the edge of every sheet, saying what the bar at the top of the first one has already said in words
|
||||||
|
-- which is why that bar keeps a heavier rule here than the page view's.
|
||||||
|
*/
|
||||||
|
.page-version {
|
||||||
|
border-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ink on paper, whichever theme the screen was in.
|
||||||
|
|
||||||
|
Without this a page printed from the dark theme comes out with a white title on white paper -- the
|
||||||
|
header and the bars paint their own foregrounds per theme, and hiding their backgrounds is what
|
||||||
|
leaves the foreground stranded. Both theme classes are named because that is the specificity those
|
||||||
|
rules were written at.
|
||||||
|
*/
|
||||||
|
.body--light,
|
||||||
|
.body--dark {
|
||||||
|
.page-breadcrumbs {
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
background: none;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The version view's bar keeps a heavier rule than the page view's, which is the one piece of
|
||||||
|
emphasis worth the ink here: on screen it is indigo against grey chrome and unmistakable, and
|
||||||
|
printed flat it would say "this is a record of a page and not the page" in the same voice as a
|
||||||
|
breadcrumb trail. A printout that reads as current when it is not is the failure this view has to
|
||||||
|
avoid.
|
||||||
|
*/
|
||||||
|
.page-breadcrumbs--version {
|
||||||
|
border-bottom: 2px solid #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
A rule closes the header, in place of the gradient and the hairline it wears on screen.
|
||||||
|
|
||||||
|
Without one the title, the description and the article's first paragraph were three blocks of
|
||||||
|
text with nothing but space between them, and the space alone did not say which of them was the
|
||||||
|
page's name -- the very thing the gradient does on screen.
|
||||||
|
|
||||||
|
A hairline, and the trail's own grey: the same line the trail draws, top and bottom of one
|
||||||
|
masthead. It was 2px, on the reasoning that twice the weight would say which of the two closes
|
||||||
|
the block -- but a rule the full width of the sheet is the widest mark on it, and weight there
|
||||||
|
buys emphasis nobody asked for. The space around it does that work instead.
|
||||||
|
|
||||||
|
1px is also the only width that survives the trip. On paper it is an absolute 1/96in whatever the
|
||||||
|
printer's resolution, but a print PREVIEW is rasterised at the display's scale factor, and on a
|
||||||
|
fractionally-scaled screen 2px lands on 2.5 or 3 device pixels and reads as a bar rather than a
|
||||||
|
rule. A hairline is the one weight both media agree on.
|
||||||
|
*/
|
||||||
|
.page-header {
|
||||||
|
background: none;
|
||||||
|
border-top: 0;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header-title {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
.page-header-subtitle {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The site banner is the third place with print rules of its own, and the reason is the cascade
|
||||||
|
rather than tidiness: `SiteBanner.vue` ships its styles in the page view's own lazily-imported
|
||||||
|
chunk, which the browser adds AFTER this stylesheet. A rule here would tie with it on specificity
|
||||||
|
and lose on order, so the banner's print treatment sits in that component -- and what it does
|
||||||
|
there, in one line, is keep the notice and drop the ink.
|
||||||
|
*/
|
||||||
|
}
|
||||||
Loading…
Reference in new issue