diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8d7f15c84b..42c800222d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,8 @@ You should also include the user name that made the change.
 ### Improvements
 - MkPageHeaderをごっそり変えた
   * モバイルではヘッダーは上下に分割され、下段にタブが表示されるように
+  * iconOnlyのタブ項目がアクティブな場合にはタイトルを表示するように
+  * メインタイムラインではタイトルを表示しない
 - ユーザーページのノート一覧をタブとして分離
 
 ### Bugfixes
diff --git a/packages/frontend/src/components/global/MkPageHeader.vue b/packages/frontend/src/components/global/MkPageHeader.vue
index efe054fd6b..877beb7642 100644
--- a/packages/frontend/src/components/global/MkPageHeader.vue
+++ b/packages/frontend/src/components/global/MkPageHeader.vue
@@ -1,8 +1,8 @@
 <template>
 <div v-if="show" ref="el" :class="[$style.root]" :style="{ background: bg }">
-	<div :class="[$style.upper, { [$style.slim]: narrow, [$style.thin]: thin_ }]" @click="onClick">
-		<div v-if="(narrow && !hideTitle)" :class="$style.buttonsLeft">
-			<MkAvatar v-if="props.displayMyAvatar && $i" :class="$style.avatar" :user="$i" :link="true"/>
+	<div :class="[$style.upper, { [$style.slim]: narrow, [$style.thin]: thin_ }]">
+		<div v-if="narrow && (props.displayMyAvatar || !hideTitle)" :class="$style.buttonsLeft">
+			<MkAvatar v-if="props.displayMyAvatar && $i" :class="$style.avatar" :user="$i" :link="true" />
 		</div>
 		<template v-if="metadata">
 			<div v-if="!hideTitle" :class="$style.titleContainer">
@@ -17,11 +17,23 @@
 					</div>
 				</div>
 			</div>
-			<div v-if="!narrow || hideTitle" :class="$style.tabs" @wheel="ev => onTabWheel(ev)">
+			<div v-if="!narrow || hideTitle" :class="$style.tabs" @wheel="onTabWheel">
 				<div :class="$style.tabsInner">
-					<button v-for="tab in tabs" :ref="(el) => tabRefs[tab.key] = (el as HTMLElement)" v-tooltip.noDelay="tab.title" class="_button" :class="[$style.tab, { [$style.active]: tab.key != null && tab.key === props.tab }]" @mousedown="(ev) => onTabMousedown(tab, ev)" @click="(ev) => onTabClick(tab, ev)">
-						<i v-if="tab.icon" :class="[$style.tabIcon, tab.icon]"></i>
-						<span v-if="!tab.iconOnly" :class="$style.tabTitle">{{ tab.title }}</span>
+					<button v-for="t in tabs" :ref="(el) => tabRefs[t.key] = (el as HTMLElement)" v-tooltip.noDelay="t.title" class="_button" :class="[$style.tab, { [$style.active]: t.key != null && t.key === props.tab }]" @mousedown="(ev) => onTabMousedown(t, ev)" @click="(ev) => onTabClick(t, ev)">
+						<div :class="$style.tabInner">
+							<i v-if="t.icon" :class="[$style.tabIcon, t.icon]"></i>
+							<div v-if="!t.iconOnly" :class="$style.tabTitle">{{ t.title }}</div>
+							<Transition
+								v-else
+								@enter="enter"
+								@after-enter="afterEnter"
+								@leave="leave"
+								@after-leave="afterLeave"
+								mode="in-out"
+							>
+								<div v-if="t.key === tab" :class="$style.tabTitle">{{ t.title }}</div>
+							</Transition>
+						</div>
 					</button>
 				</div>
 				<div ref="tabHighlightEl" :class="$style.tabHighlight"></div>
@@ -34,7 +46,7 @@
 		</div>
 	</div>
 	<div v-if="(narrow && !hideTitle) && hasTabs" :class="[$style.lower, { [$style.slim]: narrow, [$style.thin]: thin_ }]">
-		<div :class="$style.tabs" @wheel="ev => onTabWheel(ev)">
+		<div :class="$style.tabs" @wheel="onTabWheel">
 			<div :class="$style.tabsInner">
 				<button v-for="tab in tabs" :ref="(el) => tabRefs[tab.key] = (el as HTMLElement)" v-tooltip.noDelay="tab.title" class="_button" :class="[$style.tab, { [$style.active]: tab.key != null && tab.key === props.tab }]" @mousedown="(ev) => onTabMousedown(tab, ev)" @click="(ev) => onTabClick(tab, ev)">
 					<i v-if="tab.icon" :class="[$style.tabIcon, tab.icon]"></i>
@@ -102,7 +114,7 @@ const preventDrag = (ev: TouchEvent) => {
 	ev.stopPropagation();
 };
 
-const onClick = () => {
+const top = () => {
 	if (el) {
 		scrollToTop(el as HTMLElement, { behavior: 'smooth' });
 	}
@@ -115,14 +127,17 @@ function onTabMousedown(tab: Tab, ev: MouseEvent): void {
 	}
 }
 
-function onTabClick(tab: Tab, ev: MouseEvent): void {
-	if (tab.onClick) {
+function onTabClick(t: Tab, ev: MouseEvent): void {
+	if (t.key === props.tab) {
+		top();
+	} else if (t.onClick) {
 		ev.preventDefault();
 		ev.stopPropagation();
-		tab.onClick(ev);
+		t.onClick(ev);
 	}
-	if (tab.key) {
-		emit('update:tab', tab.key);
+
+	if (t.key) {
+		emit('update:tab', t.key);
 	}
 }
 
@@ -160,6 +175,27 @@ function onTabWheel(ev: WheelEvent) {
 	return false;
 }
 
+function enter(el: HTMLElement) {
+	const elementWidth = el.getBoundingClientRect().width;
+	el.style.width = '0';
+	el.offsetWidth; // reflow
+	el.style.width = elementWidth + 'px';
+	setTimeout(renderTab, 70);
+}
+function afterEnter(el: HTMLElement) {
+	el.style.width = '';
+	nextTick(renderTab);
+}
+function leave(el: HTMLElement) {
+	const elementWidth = el.getBoundingClientRect().width;
+	el.style.width = elementWidth + 'px';
+	el.offsetWidth; // reflow
+	el.style.width = '0';
+}
+function afterLeave(el: HTMLElement) {
+	el.style.width = '';
+}
+
 onMounted(() => {
 	calcBg();
 	globalEvents.on('themeChanged', calcBg);
@@ -220,7 +256,8 @@ onUnmounted(() => {
 		margin-left: auto;
 	}
 	.tabs:not(:first-child) {
-		margin-left: 16px;
+		padding-left: 16px;
+		mask-image: linear-gradient(90deg, rgba(0,0,0,0), rgb(0,0,0) 16px, rgb(0,0,0) 100%);
 	}
 	.tabs:last-child {
 		margin-right: auto;
@@ -404,6 +441,7 @@ onUnmounted(() => {
 	height: 100%;
 	font-weight: normal;
 	opacity: 0.7;
+	transition: opacity 0.2s ease;
 
 	&:hover {
 		opacity: 1;
@@ -414,8 +452,18 @@ onUnmounted(() => {
 	}
 }
 
+.tabInner {
+	display: flex;
+	align-items: center;
+}
+
 .tabIcon + .tabTitle {
 	margin-left: 8px;
+} 
+
+.tabTitle {
+	overflow: hidden;
+	transition: width 0.15s ease-in-out;
 }
 
 .tabHighlight {
@@ -424,7 +472,7 @@ onUnmounted(() => {
 	height: 3px;
 	background: var(--accent);
 	border-radius: 999px;
-	transition: all 0.2s ease;
+	transition: width 0.15s ease, left 0.15s ease;
 	pointer-events: none;
 }
 </style>
diff --git a/packages/frontend/src/pages/timeline.vue b/packages/frontend/src/pages/timeline.vue
index 057409484c..6ff700ee62 100644
--- a/packages/frontend/src/pages/timeline.vue
+++ b/packages/frontend/src/pages/timeline.vue
@@ -22,7 +22,7 @@
 </template>
 
 <script lang="ts" setup>
-import { defineAsyncComponent, computed, watch } from 'vue';
+import { defineAsyncComponent, computed, watch, provide } from 'vue';
 import XTimeline from '@/components/MkTimeline.vue';
 import MkPostForm from '@/components/MkPostForm.vue';
 import { scroll } from '@/scripts/scroll';
@@ -33,6 +33,8 @@ import { instance } from '@/instance';
 import { $i } from '@/account';
 import { definePageMetadata } from '@/scripts/page-metadata';
 
+provide('shouldOmitHeaderTitle', true);
+
 const XTutorial = defineAsyncComponent(() => import('./timeline.tutorial.vue'));
 
 const isLocalTimelineAvailable = ($i == null && instance.policies.ltlAvailable) || ($i != null && $i.policies.ltlAvailable);