mourningdove/htdocs/scss/components/icon-browser.scss

339 lines
9.9 KiB
SCSS
Raw Normal View History

2026-05-24 01:03:05 +00:00
@import "foundation/base";
.icon-browser {
// POSITIONING FIXES:
// Foundation's "reveal" component assumes pages never scroll sideways, lol.
// The icon browser JS fixes the left position, but we also need to handle
// the centering at desktop widths. (By default it uses auto-margins for
// centering, but that's not reliable once left != 0.)
// Override the default (100px) gap between top of viewport and top of
// modal, bc we want it to be 0 on mobile. (This isn't the "real" top
// property, it's just a hint to the reveal-modal js.)
top: 0;
// On mobile, the modal's width is 100vw and we don't need to center
// On tablet+, the modal's width is 80%, so 10% margin on each side:
@media #{$medium-up} {
margin: 4vh 10% 0; // Restore a gap at the top, too.
}
// Modal's max width is 70em, so from min-width: (1.25 * 70em) we use math:
@media only screen and (min-width: 87.5em) {
margin: 4vh calc( (100% - 70em) / 2 ) 0;
}
// And then there's the height. On desktop/tablet, we want to fit the whole
// modal on screen and keep the controls in view, with the icon grid
// scrolling independently. Only bother with this on browsers w/ non-buggy
// flexbox; on old browsers it can just act like it does on mobile.
@media #{$medium-up} {
// @supports will hide this from IE11, which thinks it can flex but kinda can't.
@supports (display: flex) {
.icon-browser-flex-wrapper {
display: flex;
flex-direction: column;
max-height: calc(93vh - 3.75rem); // outer container has 1.875rem padding
// This should usually leave 3vw gap at bottom, to reassure you that
// you're seeing the whole thing and/or leave room for the
// horizontal scrollbar.
}
.icon-browser-content {
overflow-y: auto;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
}
}
}
// Not necessary on site skin, but necessary in most journal styles.
box-sizing: border-box;
* {
box-sizing: border-box;
}
#js-icon-browser-search {
width: 8em; // don't stretch to 100% on site skin
flex-grow: 1;
@media (pointer: coarse) {
font-size: 16px; // dramatic woodchuck repellent
}
}
.icon-browser-content {
padding: 4px; // don't clip tops/sides off the box shadows
}
li {
@include single-transition(background-color);
}
hr {
display: block;
width: 100%;
border-style: solid;
border-width: 1px 0 0;
}
.top-controls {
// @supports will hide this from IE11, which thinks it can flex but kinda can't.
@supports (display: flex) {
display: flex;
flex-direction: row-reverse;
flex-wrap: wrap;
align-items: center;
justify-content: space-around;
}
& > * {
// for no-flex browsers
display: inline-block;
margin-right: 2em;
@supports (display: flex) {
margin-right: .4rem;
margin-left: .4rem;
}
margin-top: 0;
margin-bottom: 1rem;
white-space: nowrap;
}
// Override ultra-fluffy Foundation styling for fieldsets, we don't have
// space for that nonsense.
fieldset {
padding: .3em .8em .6em;
}
}
// Stash the options toggles out of the way on mobile
#icon-browser-options-visibility {
display: none;
}
@media #{$small-only} {
#icon-browser-options-visibility {
display: block;
}
&:not(.show-options) {
.top-controls fieldset {
display: none;
}
}
&.show-options {
#icon-browser-options-visibility img {
transform: rotate(90deg);
}
}
}
// Make the toggle button summarize the current options
.icon-browser-options-summary-small {display: none;}
.icon-browser-options-summary-no-meta {display: none;}
.icon-browser-options-summary-keyword {display: none;}
&.small-icons {
.icon-browser-options-summary-large {display: none;}
.icon-browser-options-summary-small {display: inline;}
}
&.no-meta {
.icon-browser-options-summary-meta {display: none;}
.icon-browser-options-summary-no-meta {display: inline;}
}
&.keyword-order {
.icon-browser-options-summary-date {display: none;}
.icon-browser-options-summary-keyword {display: inline;}
}
p.icon-browser-help {
font-size: smaller;
margin-bottom: 1rem;
}
// Style reset for icon/keyword buttons
button {
display: block;
border: none;
margin: 0;
padding: 0;
background: none;
border-radius: initial;
box-shadow: none;
color: inherit;
text-align: inherit;
font-size: inherit;
font-weight: inherit;
text-decoration: inherit;
line-height: inherit;
}
// Hack: We wrap buttons in a dummy 'a' element to grab an appropriate color
// for controls, so we can fit in on journal styles while still being
// accessible.
a.color-wrapper {
display: block;
text-decoration: none;
}
// Styles specifically for keyword buttons
.keyword {
display: block;
width: 100%;
cursor: pointer;
text-decoration: none;
border-width: 1px;
border-style: solid;
margin: 0 0 .2em;
padding: calc(.1em + 2px) calc(.3em + 2px); // Don't change size when border changes
line-height: 1.5;
transition-duration: 300ms;
transition-timing-function: ease-out;
transition-property: color, background-color;
}
a.active .keyword {
// Journal styles don't know about site skins' "a.active" controls so
// they don't do the inverted colors thing. But border thickness will do
// in a pinch.
border-width: 3px;
padding: .1em .3em;
}
.icon-browser-item-meta {
word-wrap: break-word;
overflow-wrap: break-word;
min-width: 0; // makes children shrinkable by grid/flex
font-size: smaller;
}
&.no-meta {
.icon-browser-item-meta {
display: none;
}
}
// The image is wrapped in a dummy "a" element, so we can use inherit to
// grab a color that fits the journal style.
.th.active {
border-color: inherit;
}
// Main grid
.js-icon-browser-icon-grid {
list-style: none;
padding: 0;
padding-bottom: 3rem;
margin: 0;
display: grid;
grid-auto-flow: row dense;
grid-template-columns: repeat(auto-fill, 110px);
justify-content: center;
grid-column-gap: 1rem;
grid-row-gap: 1rem;
li {
list-style: none;
margin: 0;
// Basic fallback styles for old browsers:
display: inline-block;
width: 150px;
vertical-align: top;
padding-bottom: 1rem;
padding-right: 1rem;
// Cool browsers can ignore all that.
@supports (display: grid) {
width: auto;
vertical-align: initial;
padding: 0;
}
}
}
// Per-item grid
.icon-browser-item {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 108px 1fr;
grid-row-gap: .5em;
grid-column-gap: .5em;
}
// Icons sit on the ground, centered.
.icon-browser-icon-image {
align-self: end;
justify-self: center;
// Fallback for non-grid browsers
margin-bottom: .5em;
@supports (display: grid) {
margin-bottom: 0;
}
}
// Large + notext: get rid of extra vertical gap
&.no-meta {
.icon-browser-item {
grid-row-gap: 0;
}
}
// Small + text: Bigger cell width, icon beside text.
&.small-icons {
.js-icon-browser-icon-grid {
grid-template-columns: repeat(auto-fill, 180px);
}
.icon-browser-item {
grid-template-columns: 58px 1fr;
grid-template-rows: 1fr;
}
// Icon aligns w/ start of text.
.icon-browser-icon-image {
align-self: start;
}
}
// small + notext: shrink main grid, item grid adjusts fine.
&.small-icons.no-meta {
.js-icon-browser-icon-grid {
grid-template-columns: repeat(auto-fill, 58px);
}
// Icons can sit on the ground again.
.icon-browser-item {
grid-template-rows: minmax(58px, 1fr);
}
.icon-browser-icon-image {
align-self: end;
justify-self: center;
}
}
.icon-browser-icon-image {
a {
cursor: pointer; // since it has no href.
// Don't save useless space below the image:
display: block;
line-height: 0;
}
img {
max-width: 100%;
height: auto;
// Foundation's .th thumbnail class sets images to display: inline-block
// instead of inline, which makes border-box sizing affect their
// height/width attributes. So without this, a 100 x 100 icon will
// display as 92 x 92.
box-sizing: content-box;
}
}
&.small-icons {
.icon-browser-icon-image img {
max-width: 58px; // 50px icon plus borders
max-height: 58px;
width: auto;
// ...but once we're shrinking images anyway, reliable sizing
// becomes more important than pixel-for-pixel dimensions.
box-sizing: border-box;
}
}
}