diff --git a/packages/frontend/src/components/MkOmit.vue b/packages/frontend/src/components/MkOmit.vue
new file mode 100644
index 0000000000..5a834c9800
--- /dev/null
+++ b/packages/frontend/src/components/MkOmit.vue
@@ -0,0 +1,72 @@
+<template>
+<div ref="content" :class="[$style.content, { [$style.omitted]: omitted }]">
+	<slot></slot>
+	<button v-if="omitted" :class="$style.fade" class="_button" @click="() => { ignoreOmit = true; omitted = false; }">
+		<span :class="$style.fadeLabel">{{ $ts.showMore }}</span>
+	</button>
+</div>
+</template>
+
+<script lang="ts" setup>
+import { nextTick, onMounted } from 'vue';
+
+const props = withDefaults(defineProps<{
+	maxHeight: number;
+}>(), {
+	maxHeight: 200,
+});
+
+let content = $ref<HTMLElement>();
+let omitted = $ref(false);
+let ignoreOmit = $ref(false);
+
+onMounted(() => {
+	const calcOmit = () => {
+		if (omitted || ignoreOmit) return;
+		omitted = content.offsetHeight > props.maxHeight;
+	};
+
+	calcOmit();
+	new ResizeObserver((entries, observer) => {
+		calcOmit();
+	}).observe(content);
+});
+</script>
+
+<style lang="scss" module>
+.content {
+	--stickyTop: 0px;
+
+	&.omitted {
+		position: relative;
+		max-height: v-bind("props.maxHeight + 'px'");
+		overflow: hidden;
+
+		> .fade {
+			display: block;
+			position: absolute;
+			z-index: 10;
+			bottom: 0;
+			left: 0;
+			width: 100%;
+			height: 64px;
+			background: linear-gradient(0deg, var(--panel), var(--X15));
+
+			> .fadeLabel {
+				display: inline-block;
+				background: var(--panel);
+				padding: 6px 10px;
+				font-size: 0.8em;
+				border-radius: 999px;
+				box-shadow: 0 2px 6px rgb(0 0 0 / 20%);
+			}
+
+			&:hover {
+				> .fadeLabel {
+					background: var(--panelHighlight);
+				}
+			}
+		}
+	}
+}
+</style>
diff --git a/packages/frontend/src/pages/user/home.vue b/packages/frontend/src/pages/user/home.vue
index e30adf4473..b629ba7a0f 100644
--- a/packages/frontend/src/pages/user/home.vue
+++ b/packages/frontend/src/pages/user/home.vue
@@ -42,8 +42,10 @@
 						<span v-for="role in user.roles" :key="role.id" v-tooltip="role.description" class="role" :style="{ '--color': role.color }">{{ role.name }}</span>
 					</div>
 					<div class="description">
-						<Mfm v-if="user.description" :text="user.description" :is-note="false" :author="user" :i="$i"/>
-						<p v-else class="empty">{{ i18n.ts.noAccountDescription }}</p>
+						<MkOmit>
+							<Mfm v-if="user.description" :text="user.description" :is-note="false" :author="user" :i="$i"/>
+							<p v-else class="empty">{{ i18n.ts.noAccountDescription }}</p>
+						</MkOmit>
 					</div>
 					<div class="fields system">
 						<dl v-if="user.location" class="field">
@@ -119,6 +121,7 @@ import MkContainer from '@/components/MkContainer.vue';
 import MkFoldableSection from '@/components/MkFoldableSection.vue';
 import MkRemoteCaution from '@/components/MkRemoteCaution.vue';
 import MkTab from '@/components/MkTab.vue';
+import MkOmit from '@/components/MkOmit.vue';
 import MkInfo from '@/components/MkInfo.vue';
 import { getScrollPosition } from '@/scripts/scroll';
 import { getUserMenu } from '@/scripts/get-user-menu';