Skip to content

Mastodon Modern by Freeplay

Imported from https://codeberg.org/Freeplay/UserStyles/raw/branch/main/mastodon/modern.user.css

Mirrored from https://git.gay/freeplay/Mastodon-Modern/raw/branch/waf/modern.user.css

Screenshot of Mastodon Modern

Details

AuthorFreeplay

LicenseCC BY-SA 4.0

CategoryMastodon

Created

Updated

Size65 kB

Statistics

Learn how we calculate statistics in the FAQ.

Failed to fetch stats.

Description

Improves the look & feel of Mastodon. Can be used with other themes that only change colors.

Notes

Source code

Source code has over 10K characters, so we truncated it. You can inspect the full source code on install link.


// 🦊 BEFORE CLICKING INSTALL:
// ---------------------------
// Add your home instance to the "Custom included sites"
// textbox in the left panel following this format:
// *://domain.tld/*

/* Update 2.0.3 (Mastodon 4.4)
- Fixed missing navigation header
- Fixed doubled-borders in the timeline
*/

/* ==UserStyle==
@name			MastoModern
@version		2.0.3
@description	Improves the look & feel of Mastodon
@homepageURL	https://git.gay/Freeplay/Mastodon-Modern
@supportURL		https://git.gay/Freeplay/Mastodon-Modern/issues
@preprocessor	stylus

@var range		tlWidth			"Timeline Width" [720, 600, 860, 20, "px"]
@var checkbox	sideHeader		"Move header to sidebar" 1
@var checkbox	navOnLeft		"Move navigation sidebar to the left" 0
@var checkbox	spaceBetween	"Move sidebars to edges" 0
@var checkbox	largerEmoji		"Larger custom emoji" 1
@var checkbox	emojiZoom		"Zoom custom emoji on hover (follows prefers-reduced-motion)" 1
@var checkbox	collapseHidden	"Collapse hidden media" 1
@var checkbox	hideClickArea	"Increase click area for hide media button" 1
@var checkbox	flatterUI		"Flatter UI" 0
@var range		borderRadius	"Border radius" [12, 0, 24, 4, "px"]
@var range		radiusRound		"Border radius round" [24, 0, 24, 4, "px"]
@var range		avatarRadius	"Avatar radius" [30, 0, 50, 10, "%"]
@var color warn  "Some options may not apply depending on the server's style defaults and how the option was implemented" #ff6b00

@namespace		Freeplay
@author			Freeplay (https://freeplay.floof.company/)
==/UserStyle== */

@-moz-document domain("mastodon.social"), domain("mastodon.online"), domain("mstdn.social"), domain("tech.lgbt"), domain("meow.social"), domain("corteximplant.com"), domain("bark.lgbt"), domain("yiff.life"), domain("furry.engineer"), domain("aus.social"), domain("infosec.exchange"), domain("ohai.social"), domain("eldritch.cafe"), domain("octodon.social"), domain("donphan.social"), domain("peoplemaking.games"), domain("toot.cat"), domain("vt.social") {
/ {
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, .scrollable :not(.focusable) > .account:not(.account--minimal), .timeline-hint"
media = ".media-gallery, .video-player, .status-card.horizontal.interactive, .status-card, .audio-player, .picture-in-picture-placeholder"

:root {
	--tl-width tlWidth
	if tlWidth == 860 {
		--tl-width 100%
	}
	if !largerEmoji {
		--emoji-size 1.2em
	}
	if largerEmoji {
		--emoji-size 2em
	}
	
	--avatar-size 46px
	--radius borderRadius
	--radius-round radiusRound
	--panel-radius var(--radius)
	--hover-color rgba(170,170,170, 0.07)
	--elevated-color rgba(150,150,200,0.1)
	--elevated-tint rgba(200,200,240,0.07)
	--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 24px -16px rgba(0,0,0,0.2)
	--shadow-med 0 8px 60px -30px rgba(0,0,0,0.1)
	--column-shadow 0 8px 24px 12px rgba(0,0,0,0.02)
	--background-border-color var(--border-color)
	if flatterUI {
		--column-shadow 0
		--elevated-tint 0
	}
	
	// --accent  // not applied everywhere, just for if you have custom color scheme and want to match it
}

desktop() {
	@media (min-width mobileW) {
		.layout-single-column {
			{block}
		}
	}
}
@media (max-width mobileW - 1) {
	:root {
		--panel-radius 0px
	}
}
.layout-multiple-columns {
	--panel-radius 0px
}

//// BODY
body {
	font-display swap !important
	if !flatterUI {
		&:not(.admin)::before {
			content ""
			position fixed
			inset 0
			background rgba(0,0,0,0.06)
			z-index -1
		}
	}
}

//// GLOBAL
/ {
	p {
		line-height 1.5
	}
	input {
		text-align start
	}
	.button--block {
		font-weight bold
	}
	.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,
	:not(.notification__filter-bar) > button:not(.column-header__button), video, .privacy-dropdown__dropdown, .react-toggle-track,
	.reply-indicator, .compose-form__warning {
		border-radius var(--radius)
	}
	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(span) {
		border-color var(--border-color) !important
	}

	.nothing-here
	.column-inline-form,
	.scrollable,
	.detailed-status__action-bar,
	.column-back-button, .column-header__collapsible.collapsed, .column-header__collapsible-inner,
	.audio-player, .search__input {
		border 0 !important
	}
	.account__section-headline, .notification__filter-bar,
	.column-header {
		border-inline 0
	}
	
	.account__section-headline, .notification__filter-bar
	.column > .scrollable {
		background none
	}
	
	.account__avatar, #profile_page_avatar, .account__avatar-composite, .account-card__title__avatar img {
		border-radius avatarRadius 
		flex none
	}

	: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
			}
		}
	}
}
// ANIMATIONS
/ {
	@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, opacity .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), background .2s !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 slideDownFade {
			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)
			}
		}
	}
}

//// ALL COLUMNS
/ {
	.columns-area__panels {
		--top 5px
		gap 0
		if navOnLeft {
			flex-direction row-reverse
		}
		if spaceBetween {
			justify-content space-between
		}
	}
	@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
		}
		if spaceBetween {
			.columns-area__panels {
				--top 10px
			}
			.columns-area__panels__main {
				margin-top 20px !important
			}
		}
	}
}

// LEFT COLUMN
/ {
	.columns-area__panels__pane--compositional {
		@media (min-width responsiveW1) {
			if spaceBetween {
				.columns-area__panels__pane__inner::before {
					content ""
					position absolute
					inset -100px -11px
					border-inline 1px solid var(--border-color)
					z-index -1
				}
			}
		}
		
	}
	
	// COMPOSE
	.compose-panel {
		overflow-y auto
		margin-top calc(0px - var(--top))
		padding-top var(--top)
		padding-bottom 20px
		padding-inline 10px
		box-sizing border-box
		max-height unset !important
		height 100%
		> * {
			padding-inline 0
		}
		> .navigation-bar {
			padding-top 0 !important
		}
		.search, /.drawer .search {
			margin-bottom 25px
		}
	}
	.compose-form__uploads {
		padding 0
		margin-block 0 !important
		margin-inline 12px
		width unset
	}
	.search {
		border-radius var(--radius)
		margin-inline -5px
		label {
			// padding-inline 20px
			box-sizing border-box
		}
		input {
			border-radius var(--radius-round) !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% - 8px)
		}
	}
	.navigation-bar {
		.icon-button {
			width auto !important
			height auto !important
			padding 8px
		}
	}
	.compose-form {
		min-height unset
		overflow unset
		gap 15px
		flex 1 0 auto !important
		> * {
			margin 0 !important
		}
		> [aria-hidden="true"] {
			display none
		}
		> .navigation-bar {
			margin-top 10px
		}
		.reply-indicator {
			position relative
			transition min-height .1s
		}
		.reply-indicator__display-name {
			padding 0
		}
		.spoiler-input__border {
			display none
		}
		#cw-spoiler-input {
			padding-inline 12px
		}
		.compose-form__autosuggest-wrapper, .autosuggest-textarea__textarea { 
			border-radius var(--radius) var(--radius) 0 0 !important
			border-bottom 0
		}
		.compose-for...

Reviews

No reviews yet.