discourse/app/assets/stylesheets/common/base/_topic-list.scss
Kris 14dfe55fdb
DEV: remove use of body:has() in CSS (#40841)
`body:has()` ends up checking the whole document, which isn't ideal! we
don't actually need them in either of these cases

in the case of the topic-replies-toggle-wrapper we can use a general
sibling selector, and for the presence alignment, the progress bar only
shows up at `<= 924px` anyway
2026-06-12 14:13:05 -04:00

972 lines
18 KiB
SCSS
Vendored

@use "lib/viewport";
:root {
--category-header-logo-size: 3rem;
--category-description-width: 760px;
--category-header-border: 1px solid var(--content-border-color);
--discovery-heading-description-color: var(--primary-800);
}
// shared banner treatment used above the discovery topic list
// .category-heading, .tag-info
.discovery-heading {
gap: 0 var(--space-4);
margin-bottom: var(--space-6);
padding: var(--space-4);
border: var(--category-header-border);
border-radius: var(--d-border-radius);
}
.category-heading {
max-width: 100%;
&.--has-logo {
display: flex;
}
&__logo.category-logo.aspect-image {
height: var(--category-header-logo-size);
width: var(--category-header-logo-size);
margin-top: calc(1rem - 1cap);
flex-shrink: 0;
}
&__description {
margin: 0;
line-height: var(--line-height-large);
font-size: var(--font-0);
color: var(--discovery-heading-description-color);
max-width: var(--category-description-width);
}
&__content {
flex-grow: 1;
}
&__content .badge-category__wrapper {
font-size: var(--font-up-3);
}
&__content .badge-category__name {
font-weight: bold;
color: var(--primary);
}
@include viewport.until(sm) {
p {
font-size: var(--font-up-1);
margin-bottom: 0.75em;
}
}
}
.category-logo.aspect-image {
--max-height: 150px;
width: auto;
max-height: var(--max-height);
max-width: 100%;
height: auto;
img {
width: calc(var(--max-height) * var(--aspect-ratio));
max-width: 100%;
height: inherit;
max-height: var(--max-height);
}
}
.topic-list.shared-drafts {
margin-bottom: var(--space-6);
}
#header-list-area {
background: var(--d-content-background);
}
// Topic list body
.topic-list-item.visited,
.latest-topic-list-item.visited,
.category-topic-link.visited {
background-color: var(--topic-list-item-background-color--visited);
a.title:not(.badge-notification) {
color: var(--title-color--read);
font-weight: var(--topic-title-font-weight--visited);
}
}
.topic-list-item {
background-color: var(--topic-list-item-background-color);
.post-excerpt {
margin-top: var(--space-2);
margin-bottom: var(--space-2);
font-size: var(--font-down-2);
word-break: break-word;
// special exception case because this class gets applied where it shouldn't, example in excerpts in bookmark pages
.only-emoji {
width: 1em;
height: 1em;
margin-block: 0;
}
}
}
.topic-list-main-link {
font-size: var(--d-topic-list-title-font-size);
a.title {
word-break: break-word;
color: var(--title-color);
font-weight: var(--topic-title-font-weight);
}
.anon & {
a.title:visited:not(.badge-notification) {
color: var(--title-color--read);
}
}
a.title.visited:not(.badge-notification) {
color: var(--title-color--read);
}
}
.sticky-header .topic-list-header {
position: sticky;
top: var(--header-offset, 60px);
background: var(--d-topic-list-header-background-color);
z-index: 2;
}
.bulk-select-topics-dropdown {
display: flex;
align-items: center;
gap: var(--space-1) var(--space-2);
.select-kit.single-select.dropdown-select-box .select-kit-row {
.texts .name {
font-weight: normal;
}
.icons {
font-size: var(--font-down-2);
margin-right: var(--space-3);
position: relative;
top: 0.15em;
}
}
}
.bulk-select-topics-actions {
display: flex;
gap: var(--space-2);
}
.topic-list {
width: 100%;
border-collapse: collapse;
.alert {
margin-bottom: 0;
font-size: var(--font-0);
}
.spinner {
margin-top: 40px;
}
> .topic-list-body > .topic-list-item {
&.excerpt-expanded .star {
vertical-align: top;
margin-top: 2px;
}
&.last-visit {
border-bottom: none;
}
.topic-list-separator {
text-align: center;
}
&.bulk-selecting {
@include user-select(none);
cursor: pointer;
}
&.bulk-selected {
background: var(--tertiary-low);
}
}
.topic-list-item-separator {
border: none;
.topic-list-data {
border-top: 1px solid var(--danger-medium);
line-height: 0em;
padding: 0;
text-align: center;
}
.topic-list-data span {
position: relative; // Chrome needs this, otherwise the line is above the text
background-color: var(--secondary);
color: var(--danger-medium);
padding: 0 var(--space-2);
font-size: var(--font-down-1);
}
}
.topic-list-data {
line-height: var(--line-height-medium);
text-align: left;
vertical-align: middle;
}
.btn-flat .d-icon {
color: currentcolor;
}
td {
color: var(--metadata-color);
font-size: var(--font-0);
}
.main-link {
@extend .topic-list-main-link;
.raw-topic-link > * {
// important to prevent clicks registering on non-link elements and resulting in a full page reload
pointer-events: none;
}
// we have a custom focus indicator via .selected
// we can remove the native one
.title:focus {
outline: none;
}
.title:focus-visible {
outline: none;
}
}
.unread-indicator {
&.read {
display: none;
}
.d-icon {
vertical-align: middle;
font-size: var(--font-down-5);
}
}
.link-bottom-line {
font-size: var(--font-down-1);
display: flex;
flex-wrap: wrap;
align-items: center;
margin-top: var(--d-topic-list-metadata-top-space);
gap: 0 var(--space-2);
line-height: var(--line-height-large);
a.discourse-tag.box {
padding-top: 0;
padding-bottom: 0;
}
.discourse-tag.box {
margin-right: var(--space-1);
}
.participant-group-wrapper {
display: flex;
flex-wrap: wrap;
gap: var(--space-2);
.participant-group {
padding: 0.1em 0.3em;
border: 1px solid var(--content-border-color);
border-radius: 0.25em;
min-width: 3em;
@include ellipsis;
> a {
display: flex;
align-items: center;
height: 1.25em;
color: var(--primary-high);
font-size: var(--font-down-1);
.mobile-view & {
height: 1.1em;
}
.d-icon {
margin-right: 5px;
font-size: var(--font-down-1);
}
}
}
}
}
.topic-excerpt {
display: block;
font-size: var(--font-down-1);
margin-top: var(--space-1);
color: var(--excerpt-color);
overflow-wrap: break-word;
line-height: var(--line-height-large);
padding-right: var(--space-1);
}
.topic-list-data.num {
text-align: center;
font-size: var(--d-topic-list-data-font-size);
a {
color: inherit;
}
.badge-posts {
font-weight: 700;
color: inherit;
display: inline-block;
@include viewport.from(sm) {
padding: var(--space-3) var(--space);
}
}
}
.num.activity {
a {
padding: 15px 5px;
span.relative-date {
pointer-events: none;
}
}
}
}
.topic-list-bottom {
margin: var(--space-5) 0;
@include viewport.until(sm) {
margin-bottom: 0;
}
@include viewport.from(sm) {
.dismiss-container-bottom {
float: right;
}
}
}
.heatmap-high,
.heatmap-high a,
.heatmap-high .d-icon,
.heatmap-high .d-button-label {
color: #fe7a15 !important;
}
.heatmap-med,
.heatmap-med a,
.heatmap-med .d-icon,
.heatmap-med .d-button-label {
color: #cf7721 !important;
}
.heatmap-low,
.heatmap-low a,
.heatmap-low .d-icon,
.heatmap-low .d-button-label {
color: #9b764f !important;
}
.topic-list .heatmap-high {
font-weight: bold;
}
.loading .topic-list {
border: 0;
box-shadow: none;
.topic-list-item {
background-color: transparent;
}
}
#list-area {
background: var(--d-content-background);
margin-bottom: 100px;
.empty-topic-list {
padding: 10px;
}
.unseen {
background-color: transparent;
padding: 0;
border: 0;
color: var(--danger-medium);
font-size: var(--font-0);
cursor: default;
}
.show-more {
&.has-topics {
@include d-animation(float-down, 250ms, ease-in-out);
@include viewport.from(md) {
position: absolute;
z-index: z("base");
width: fit-content;
left: 0;
right: 0;
margin: auto;
font-size: var(--font-down-1-rem);
.alert {
border-radius: var(--d-border-radius-large);
}
}
}
.alert {
align-items: center;
justify-content: center;
gap: 0.5em;
margin: 0 auto;
padding: var(--space-2) var(--space-4);
&.loading {
color: var(--primary-medium);
cursor: default;
}
}
}
@include viewport.from(sm) {
h2 {
margin: var(--space-5) 0 var(--space-3);
}
.top-lists {
h2 {
cursor: pointer;
margin: 5px 0 10px;
}
.period-chooser .select-kit-body {
width: 275px;
}
}
}
}
.d-icon-thumbtack.unpinned {
transform: rotate(180deg);
}
.table-heading {
border-bottom: var(--d-table-border-top-height) solid
var(--table-border-color);
}
// This is not what we want:
//
// This is an overly-long topic title that would break just right
// *
//
// Instead, we want the line to break like this:
//
// This is an overly-long topic title that would break just
// right *
.topic-post-badges {
white-space: nowrap;
align-self: center;
line-height: var(--line-height-medium);
}
#topic-list-heading {
line-height: var(--line-height-medium);
margin-bottom: var(--space-2);
}
@include viewport.from(sm) {
.topic-list {
@include topic-list-icons;
margin: var(--d-topic-list-margin-y) var(--d-topic-list-margin-x)
var(--d-topic-list-margin-bottom);
.topic-list-header {
font-size: var(--d-topic-list-header-font-size);
}
.topic-list-header .topic-list-data {
padding: var(--d-topic-list-header-data-padding-y)
var(--d-topic-list-header-data-padding-x);
color: var(--d-topic-list-header-text-color);
}
.topic-list-data {
padding: var(--d-topic-list-data-padding-y)
var(--d-topic-list-data-padding-x);
&:first-of-type {
padding-inline-start: var(--d-topic-list-data-padding-inline-start);
}
&:last-of-type {
padding-inline-end: var(--d-topic-list-data-padding-inline-end);
}
th & {
border-bottom: 3px solid var(--primary-low);
}
}
button.bulk-select {
padding: 0;
margin-right: var(--space-2);
line-height: var(--line-height-large);
}
.topic-list-data.bulk-select {
padding: 0;
width: 30px;
text-align: center;
label {
margin: 0;
padding: var(--space-3) var(--space-2);
cursor: pointer;
}
+ .main-link {
padding-left: 0;
}
}
$td-posters-height: 29px; // min-height of td with avatar glow
$td-posters-more-lh: $td-posters-height - 4;
.posters {
// we know there are up to 5 avatars of fixed size
// will be overridden by media width queries on narrow displays to 1 avatar's width
width: 146px;
img.avatar {
height: var(--d-topic-list-avatar-size);
width: var(--d-topic-list-avatar-size);
}
> a {
float: left;
margin-right: 4px;
&:last-of-type {
margin-right: 0;
}
&.posters-more-count {
cursor: default;
color: var(--primary-med-or-secondary-med);
line-height: $td-posters-more-lh;
font-size: var(--font-down-1);
}
}
@include viewport.until(md) {
@include hide-posters;
}
@include viewport.until(lg) {
.has-sidebar-page & {
@include hide-posters;
}
}
}
td.topic-list-data.posters {
height: $td-posters-height;
}
.posters a:first-child .avatar.latest:not(.single) {
box-shadow: 0 0 3px 1px rgb(var(--tertiary-rgb), 0.35);
border: 1px solid rgb(var(--tertiary-rgb), 0.5);
position: relative;
left: -2px;
}
.likes {
width: var(--d-topic-list-likes-views-posts-width);
}
.views {
width: var(--d-topic-list-likes-views-posts-width);
@include viewport.until(md) {
display: none;
}
.has-sidebar-page & {
@include viewport.until(lg) {
display: none;
}
}
}
.posts {
width: var(--d-topic-list-likes-views-posts-width);
}
.post-actions {
clear: both;
width: auto;
color: var(--primary-med-or-secondary-med);
text-align: left;
font-size: var(--font-down-1);
margin-top: 5px;
.fa {
margin-right: 2px;
}
a {
color: var(--primary-med-or-secondary-med);
margin-right: 3px;
line-height: var(--line-height-large);
}
}
.activity {
width: 4em;
&:lang(zh_CN) {
width: 5.3em;
}
}
.age {
width: 4em;
}
.with-year {
white-space: nowrap;
}
}
.dismiss-container-top {
display: flex;
justify-content: flex-end;
}
.bulk-select-topics {
display: inline-flex;
flex-wrap: wrap;
gap: var(--space-2);
align-items: end;
margin-left: -5px;
}
}
.topic-replies-toggle-wrapper {
padding: 0 var(--nav-horizontal-padding);
@include viewport.until(sm) {
border-bottom: 1px solid var(--primary-low);
width: 100%;
display: flex;
justify-content: center;
z-index: 1; // making sure the underline offset is on top of the topiclist
position: relative;
}
.topics-replies-toggle {
background: none;
border: none;
line-height: var(--line-height-large);
padding: var(--space-2);
position: relative;
font-size: var(--font-down-1-rem);
@include viewport.until(sm) {
flex-grow: 1;
padding: 0.75em;
}
&.active {
@include nav-active;
@include viewport.until(sm) {
&::after {
height: 1px;
bottom: -1px;
}
}
}
&:hover {
@include nav-hover;
}
}
}
@include viewport.between(sm, lg) {
.topic-list {
.topic-list-data {
font-size: var(--font-0);
}
}
.topic-list-header {
font-size: var(--font-down-1);
}
.container.list-container {
position: relative;
padding: 0 var(--list-container-padding-x);
}
.container.list-container.--categories {
padding: 0 var(--list-container-categories-padding-x);
}
.container.list-container.--topic-list {
padding: 0 var(--list-container-topiclist-padding-x);
}
}
@include viewport.until(sm) {
.fade.in {
opacity: 1;
}
.list-container .full-width {
margin-left: 0;
}
td .main-link {
width: 78%;
display: inline-block;
}
.topic-list {
&-body {
border-width: 1px;
.topic-replies-toggle-wrapper ~ .topic-list & {
border-width: 0;
}
}
.num.posts-map {
font-size: var(--font-up-2);
padding: 0;
> button,
> a {
padding: 0;
}
}
.num.activity a {
padding: 0;
}
// so the topic excerpt is full width
// as the containing div is 80%
.topic-excerpt {
display: block;
padding-right: 0;
width: 120%;
}
.topic-excerpt-more {
color: var(--tertiary);
}
.right {
margin-left: 55px;
}
.topic-list-data {
padding: 7px 0;
max-width: 300px;
}
.main-link {
line-height: var(--line-height-medium);
position: relative;
font-size: var(--font-up-1);
a.title {
color: var(--primary);
padding: 0;
overflow-wrap: break-word;
}
.topic-statuses {
a {
line-height: 0.8;
color: var(--primary-medium);
}
}
}
.badge-notification,
.category-topic-link td.num .badge-notification {
position: relative;
display: inline-block;
top: -1px;
font-size: var(--font-0);
line-height: var(--line-height-small);
padding: 0.15em 0.4em 0.2em 0.4em;
.d-icon {
color: var(--secondary);
}
&.new-topic::before {
margin-right: 0;
}
&.new-topic {
padding: 0;
}
}
.category-topic-link td.num .badge-notification {
&.unread-posts {
color: var(--secondary);
}
}
.topic-item-stats {
position: relative;
display: flex;
align-items: baseline;
margin-top: 0.5em;
z-index: z("base");
span.relative-date {
vertical-align: text-top;
}
.num.activity {
margin-left: auto;
font-size: var(--font-down-1);
}
.category a {
max-width: 160px;
}
.num .d-icon {
color: var(--primary-medium);
}
}
.topic-item-stats__category-tags {
margin-right: 0.5em;
max-width: 90%;
line-height: var(--line-height-medium);
.badge-category__wrapper {
vertical-align: bottom;
margin-right: 0.5em;
max-width: 100%;
}
.badge-wrapper,
.discourse-tag {
// disabling clicks because these targets are too small on mobile
pointer-events: none;
}
.discourse-tags {
display: inline;
vertical-align: bottom;
}
.badge-wrapper {
max-width: 100%;
vertical-align: bottom;
}
}
.age {
white-space: nowrap;
a {
color: var(--primary-medium);
}
}
}
.dropdown-toggle:active,
.open .dropdown-toggle {
outline: 0;
}
.topic-list-header {
display: none;
}
.topic-list.sticky-header {
.topic-list-header {
display: table-header-group;
position: sticky;
z-index: z("base") + 2;
top: var(--header-offset);
background: var(--secondary);
tr {
display: flex;
align-items: center;
border: none;
}
.topic-list-data {
display: none;
&.bulk-select {
display: inline-block;
}
&.default {
display: flex;
.bulk-select-topic-dropdown__count {
display: none;
}
}
}
button.bulk-select {
padding-left: 0.85em; // visual alignment
}
}
}
.bulk-select-topics {
display: flex;
flex-wrap: wrap;
padding-left: 0.85em;
gap: 0.5em;
font-size: var(--font-down-1);
.select-kit-collection {
font-size: var(--font-up-1);
}
}
}