diff --git a/packages/frontend/src/components/MkAutocomplete.vue b/packages/frontend/src/components/MkAutocomplete.vue
index b184e4489..0c32b337e 100644
--- a/packages/frontend/src/components/MkAutocomplete.vue
+++ b/packages/frontend/src/components/MkAutocomplete.vue
@@ -1,34 +1,34 @@
 <template>
-<div ref="rootEl" class="swhvrteh _popup _shadow" :style="{ zIndex }" @contextmenu.prevent="() => {}">
-	<ol v-if="type === 'user'" ref="suggests" class="users">
-		<li v-for="user in users" tabindex="-1" class="user" @click="complete(type, user)" @keydown="onKeydown">
-			<img class="avatar" :src="user.avatarUrl"/>
-			<span class="name">
+<div ref="rootEl" :class="$style.root" class="_popup _shadow" :style="{ zIndex }" @contextmenu.prevent="() => {}">
+	<ol v-if="type === 'user'" ref="suggests" :class="$style.list">
+		<li v-for="user in users" tabindex="-1" :class="$style.item" @click="complete(type, user)" @keydown="onKeydown">
+			<img :class="$style.avatar" :src="user.avatarUrl"/>
+			<span :class="$style.userName">
 				<MkUserName :key="user.id" :user="user"/>
 			</span>
-			<span class="username">@{{ acct(user) }}</span>
+			<span>@{{ acct(user) }}</span>
 		</li>
-		<li tabindex="-1" class="choose" @click="chooseUser()" @keydown="onKeydown">{{ i18n.ts.selectUser }}</li>
+		<li tabindex="-1" :class="$style.item" @click="chooseUser()" @keydown="onKeydown">{{ i18n.ts.selectUser }}</li>
 	</ol>
-	<ol v-else-if="hashtags.length > 0" ref="suggests" class="hashtags">
-		<li v-for="hashtag in hashtags" tabindex="-1" @click="complete(type, hashtag)" @keydown="onKeydown">
+	<ol v-else-if="hashtags.length > 0" ref="suggests" :class="[$style.list, $style.hashtags]">
+		<li v-for="hashtag in hashtags" tabindex="-1" :class="$style.item" @click="complete(type, hashtag)" @keydown="onKeydown">
 			<span class="name">{{ hashtag }}</span>
 		</li>
 	</ol>
-	<ol v-else-if="emojis.length > 0" ref="suggests" class="emojis">
-		<li v-for="emoji in emojis" :key="emoji.emoji" tabindex="-1" @click="complete(type, emoji.emoji)" @keydown="onKeydown">
-			<div class="emoji">
+	<ol v-else-if="emojis.length > 0" ref="suggests" :class="$style.list">
+		<li v-for="emoji in emojis" :key="emoji.emoji" :class="$style.item" tabindex="-1" @click="complete(type, emoji.emoji)" @keydown="onKeydown">
+			<div :class="$style.emoji">
 				<MkEmoji :emoji="emoji.emoji"/>
 			</div>
 			<!-- eslint-disable-next-line vue/no-v-html -->
-			<span v-if="q" class="name" v-html="sanitizeHtml(emoji.name.replace(q, `<b>${q}</b>`))"></span>
+			<span v-if="q" :class="$style.emojiName" v-html="sanitizeHtml(emoji.name.replace(q, `<b>${q}</b>`))"></span>
 			<span v-else v-text="emoji.name"></span>
-			<span v-if="emoji.aliasOf" class="alias">({{ emoji.aliasOf }})</span>
+			<span v-if="emoji.aliasOf" :class="$style.emojiAlias">({{ emoji.aliasOf }})</span>
 		</li>
 	</ol>
-	<ol v-else-if="mfmTags.length > 0" ref="suggests" class="mfmTags">
-		<li v-for="tag in mfmTags" tabindex="-1" @click="complete(type, tag)" @keydown="onKeydown">
-			<span class="tag">{{ tag }}</span>
+	<ol v-else-if="mfmTags.length > 0" ref="suggests" :class="$style.list">
+		<li v-for="tag in mfmTags" tabindex="-1" :class="$style.item" @click="complete(type, tag)" @keydown="onKeydown">
+			<span>{{ tag }}</span>
 		</li>
 	</ol>
 </div>
@@ -379,113 +379,88 @@ onBeforeUnmount(() => {
 });
 </script>
 
-<style lang="scss" scoped>
-.swhvrteh {
+<style lang="scss" module>
+.root {
 	position: fixed;
 	max-width: 100%;
 	margin-top: calc(1em + 8px);
 	overflow: clip;
 	transition: top 0.1s ease, left 0.1s ease;
+}
 
-	> ol {
-		display: block;
-		margin: 0;
-		padding: 4px 0;
-		max-height: 190px;
-		max-width: 500px;
-		overflow: auto;
-		list-style: none;
+.list {
+	display: block;
+	margin: 0;
+	padding: 4px 0;
+	max-height: 190px;
+	max-width: 500px;
+	overflow: auto;
+	list-style: none;
+}
 
-		> li {
-			display: flex;
-			align-items: center;
-			padding: 4px 12px;
-			white-space: nowrap;
-			overflow: clip;
-			font-size: 0.9em;
-			cursor: default;
+.item {
+	display: flex;
+	align-items: center;
+	padding: 4px 12px;
+	white-space: nowrap;
+	overflow: clip;
+	font-size: 0.9em;
+	cursor: default;
+	user-select: none;
+	overflow: hidden;
+	text-overflow: ellipsis;
 
-			&, * {
-				user-select: none;
-			}
-
-			* {
-				overflow: hidden;
-				text-overflow: ellipsis;
-			}
-
-			&:hover {
-				background: var(--X3);
-			}
-
-			&[data-selected='true'] {
-				background: var(--accent);
-
-				&, * {
-					color: #fff !important;
-				}
-			}
-
-			&:active {
-				background: var(--accentDarken);
-
-				&, * {
-					color: #fff !important;
-				}
-			}
-		}
+	&:hover {
+		background: var(--X3);
 	}
 
-	> .users > li {
-
-		.avatar {
-			min-width: 28px;
-			min-height: 28px;
-			max-width: 28px;
-			max-height: 28px;
-			margin: 0 8px 0 0;
-			border-radius: 100%;
-		}
-
-		.name {
-			margin: 0 8px 0 0;
-		}
+	&[data-selected='true'] {
+		background: var(--accent);
+		color: #fff !important;
 	}
 
-	> .emojis > li {
-
-		.emoji {
-			flex-shrink: 0;
-			display: flex;
-			margin: 0 4px 0 0;
-			height: 24px;
-			width: 24px;
-			justify-content: center;
-			align-items: center;
-			font-size: 20px;
-
-			> img {
-				height: 24px;
-				width: 24px;
-				object-fit: scale-down;
-			}
-
-		}
-
-		.name {
-			flex-shrink: 1;
-		}
-
-		.alias {
-			flex-shrink: 9999999;
-			margin: 0 0 0 8px;
-		}
-	}
-
-	> .mfmTags > li {
-
-		.name {
-		}
+	&:active {
+		background: var(--accentDarken);
+		color: #fff !important;
 	}
 }
+
+.avatar {
+	min-width: 28px;
+	min-height: 28px;
+	max-width: 28px;
+	max-height: 28px;
+	margin: 0 8px 0 0;
+	border-radius: 100%;
+}
+
+.userName {
+	margin: 0 8px 0 0;
+}
+
+.emoji {
+	flex-shrink: 0;
+	display: flex;
+	margin: 0 4px 0 0;
+	height: 24px;
+	width: 24px;
+	justify-content: center;
+	align-items: center;
+	font-size: 20px;
+}
+
+.emojiImg {
+	height: 24px;
+	width: 24px;
+	object-fit: scale-down;
+}
+
+.emojiName {
+	flex-shrink: 1;
+}
+
+.emojiAlias {
+	flex-shrink: 9999999;
+	margin: 0 0 0 8px;
+}
 </style>