Drastically improves the look & feel of Mastodon. Can be used with other themes that only change colors.
Mastodon Modern by Freeplay
Imported from https://codeberg.org/Freeplay/UserStyles/raw/branch/main/mastodon/modern.user.css
Mirrored from https://codeberg.org/Freeplay/Mastodon-Modern/raw/branch/main/modern.user.css

Details
AuthorFreeplay
LicenseNo License
CategoryMastodon
Created
Updated
Size71 kB
Statistics
Learn how we calculate statistics in the FAQ.
Failed to fetch stats.
Description
Notes
See progress updates here!
Learn more about Mastodon & The Fediverse
View on Codeberg, along with plain CSS to add to your own instance!
Source code
Source code has over 10K characters, so we truncated it. You can inspect the full source code on install link.
////////////////////////////////////////////////////////////////// 🦊
// //
// !!! MAKE SURE TO ADD YOUR SERVER URL USING THE STEPS BELOW !!! //
// 1. Install the style //
// 2. Click "Edit" in the left sidebar //
// 3. Click "Settings" in the left sidebar //
// 4. Paste your server's URL in the //
// "Custom included sites" textbox like this: //
// *//DOMAIN HERE/* //
// 5. Click "Save" //
// //
////////////////////////////////////////////////////////////////////
/* Update 1.7.0
- New navbar design for when logged out, uses less space
- fix sidebar height (footer had too much bottom padding)
- fix multiple images in gallery being cut off
- style hashtags bar
- fixes
*/
/* ==UserStyle==
@name Mastodon Modern
@version 1.7.1
@description Drastically improves the look & feel of Mastodon
@homepageURL https://codeberg.org/Freeplay/Mastodon-Modern
@supportURL https://codeberg.org/Freeplay/Mastodon-Modern/issues
@preprocessor stylus
-- AUTHOR STUFF --
@namespace Freeplay
@author Freeplay (https://freeplay.codeberg.page/)
==/UserStyle== */
@-moz-document domain("mastodon.coffee"), domain("socel.net"), domain("brands.town"), domain("mstdn.social"), domain("social.vivaldi.net"), domain("masto.ai"), domain("mastodon.art"), domain("tech.lgbt"), domain("mastodon.social"), domain("mastodon.online"), domain("mastodon.lol"), domain("floss.social"), domain("mas.to"), domain("c.im"), domain("nerdculture.de"), domain("maly.io"), domain("corteximplant.com"), domain("queer.party"), domain("fosstodon.org"), domain("meow.social"), domain("raru.re"), domain("ani.work"), domain("kolektiva.social"), domain("home.social"), domain("mstdn.plus"), domain("mastodon.sdf.org"), domain("toot.community"), domain("sfba.social"), domain("hachyderm.io"), domain("mindly.social"), domain("mastodon.cloud"), domain("bark.lgbt"), domain("wetdry.world"), domain("md.ilyamikcoder.com"), domain("techhub.social"), domain("mastodon.world"), domain("toot.io") {
/ { // This is just so I can easily collapse everything, shouldn't affect compiled code
responsiveW1 = 1320px
responsiveW2 = 1175px
mobileW = 890px
transBounce1 = .2s cubic-bezier(0,0,0,1.1)
statuses-list = ".focusable, .entry, .statuses-grid__item .detailed-status, .trends__item, .story, .account-card, .scrollable :not(.focusable) > .account, .timeline-hint"
media = ".media-gallery, .video-player, .status-card.horizontal.interactive, .status-card, .audio-player, .picture-in-picture-placeholder"
/:root {
--tl-width 750px
--radius 12px
--radius-round 24px
--hover-color rgba(170,170,170, 0.07)
--elevated-color rgba(150,150,200,0.1)
--border-color rgba(120,120,200, 0.2)
--border-color-2 rgba(120,120,120, 1)
--shadow 0 10px 40px -10px rgba(0,0,0,0.15)
--shadow-low 0 8px 16px -10px rgba(0,0,0,0.4)
--shadow-med 0 8px 60px -30px rgba(0,0,0,0.1)
// --accent // not applied everywhere, just for if you have custom color scheme and want to match it
}
:not(body):not(.scrollable) {
&::-webkit-scrollbar {
width 6px
margin-block 10px
&-track {
background none
}
&-thumb {
border-radius 100px
transition background-color .2s
}
}
&:not(:hover) {
&::-webkit-scrollbar-thumb {
background none
padding-block 10px
}
}
}
fa() {
font: normal normal normal 14px/1 FontAwesome;
}
compactStatuses() {
.scrollable:not(.scrollable--flex) {
padding 0px !important
padding-bottom 40vh !important
&::before {
content ""
position absolute
inset 0
background-color inherit
z-index -1
}
.account-timeline__header {
margin 0px !important
}
}
{statuses-list} {
border-radius 0
&::before {
border-radius 0 !important
}
&::after {
inset-inline 0 !important
}
}
[class*="explore__"] {
> * {
border-radius var(--radius) !important
}
}
.detailed-status__wrapper {
margin 0 !important
}
.status__action-bar {
margin-bottom 0px
gap 0
margin-inline-end 0 !important
:not(i):not(.status__action-bar-spacer) {
display flex
flex-grow 9999
justify-content center !important
max-width 55px
min-width max-content
}
> .icon-button:first-child {
margin-inline-start -8px !important
}
}
.status__action-bar, .detailed-status__action-bar, .picture-in-picture__footer {
flex-wrap wrap
}
}
.rtl {
textarea {
text-align right
}
}
a, button, label {
user-select none
}
.button--block {
font-weight 700
}
.unhandled-link, .mention {
span {
text-decoration none !important
}
&:not(:focus):not(:hover) {
span {
text-decoration underline !important
}
}
}
input, .input-copy, select, textarea,
.compose-form__upload-thumbnail, .button,
button:not(.column-header__button), video, .privacy-dropdown__dropdown, .react-toggle-track,
.reply-indicator, .compose-form__warning {
border-radius var(--radius) !important
}
button, .focusable, a, .media-gallery__item-thumbnail {
&:focus-visible {
box-shadow inset 0 0 0 2px #dc7b18
outline 2px #dc7b18 solid
outline-offset -2px
}
}
*:not(.radio-button__input):not(input) {
font-display swap !important
}
:not(.radio-button__input):not(span) {
border-color var(--border-color) !important
}
.setting-text {
padding-inline 10px
}
@media (prefers-reduced-motion: no-preference) {
body:not(.reduce-motion) {
.load-more, .setting-toggle, .column-header__back-button, .column-back-button,
.trends__item, .story, .account__avatar, .button,
.media-gallery__item, .column-link, select, .status-card, .audio-player, .account {
transition transform .4s cubic-bezier(0,0,0,3), background .2s !important
&:active, &:focus-visible {
transform scale(.99)
transition transform .4s cubic-bezier(0,0,0,1) !important
}
}
.column-header__button, .column-header__buttons > .column-header__back-button,
.react-toggle-track, .icon-button, .floating-action-button {
transition transform .4s cubic-bezier(0,0,0,4) !important
&:active {
transform scale(.95)
transition transform .4s cubic-bezier(0,0,0,1) !important
}
}
.status__content__spoiler-link {
span {
display inline-block
transition transform .4s cubic-bezier(0,0,0,4) !important
}
&:active span {
transition transform .4s cubic-bezier(0,0,0,1) !important
transform translateY(1px)
}
}
}
.reduce-motion * {
animation-duration 0s !important
}
@keyframes bounceIn {
0% { transform: scale(1.1); opacity: 0 }
30% { transform: scale(.99); opacity: 1 }
60% { transform: scale(1.005); opacity: 1 }
100% { transform: scale(1); opacity: 1 }
}
@keyframes slideUp {
from {
transform translateY(20px)
}
}
@keyframes slideUpFade {
from {
transform translateY(20px)
filter opacity(0)
}
}
@keyframes slideDowFade {
from {
transform translateY(-20px)
filter opacity(0)
}
}
@keyframes slideUpBig {
from {
transform translateY(50vh)
}
}
@keyframes fadeUp {
from {
transform translateY(10px)
opacity 0
}
}
@keyframes scaleIn {
from {
transform scale(.98)
opacity 0
}
}
@keyframes fadeLeft {
from {
transform: translateX(20px) opacity(0)
}
}
@keyframes rainbow {
to {
filter hue-rotate(360deg)
}
}
}
.account__avatar, #profile_page_avatar, .account__avatar-composite, .account-card__title__avatar img {
border-radius 30% !important
}
.detailed-status__action-bar,
.column-header__collapsible-inner,
.audio-player, .search__input {
border 0 !important
}
.dropdown-menu, .dropdown-animation {
border-radius var(--radius)
animation scaleIn .2s cubic-bezier(0,0,0,1.1)
}
.dropdown-menu__container__list {
overflow hidden auto
border-radius var(--radius)
max-height 70vh
}
.dropdown-menu__item {
overflow hidden
a {
padding .7em 1em !important
transition background-color .2s, color .2s
min-width 150px
}
}
.dropdown-menu__separator {
margin 0 !important
}
.interaction-modal {
border-radius var(--radius)
overflow-y auto
}
.interaction-modal__choices {
gap 10px
display flex
flex-wrap wrap
.interaction-modal__choices__choice {
max-height 50vh
overflow-y auto
// background-color var(--elevated-color)
border 1px solid var(--border-color)
flex 1 0 270px
border-radius var(--radius)
transition background .2s
position relative
}
}
.compare-history-modal {
margin-block 20px
}
.compare-history-modal__container {
overflow hidden auto
}
.columns-area__panels {
--top 5px
}
@media (min-width responsiveW2) {
.columns-area__panels {
padding-inline 10px
padding-top var(--top)
box-sizing border-box
transition padding .4s
--top 20px
}
}
@media (min-width responsiveW1) {
.columns-area__panels {
--top 30px
}
}
#mastodon {
// LEFT COLUMN
.compose-panel {
margin-top 0
overflow-y auto
margin-top calc(0px - var(--top))
padding-top var(--top)
padding-bottom 20px
box-sizing border-box
// min-height 100vh !important
max-height unset !important
height 100%
}
.search {
margin-inline 5px
border-radius var(--radius)
label {
// padding-inline 20px
box-sizing border-box
}
input {
border-radius var(--radius-round) !important
padding-inline-start 20px !important
padding-inline-end 40px !important
}
.search__icon > i {
margin-inline 5px
}
/.search__popout {
border-radius var(--radius)
animation scaleIn .2s
box-shadow var(--shadow-low)
margin-top 10px
margin-inline 4px
width calc(100%...