YouTube layout fix

Forces 6 videos per row, adjusts text sizes, adds spacing, fixes truncation, applies specific alignments based on user tuning.

当前为 2025-04-06 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name YouTube layout fix
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.74
  5. // @description Forces 6 videos per row, adjusts text sizes, adds spacing, fixes truncation, applies specific alignments based on user tuning.
  6. // @author Kalakaua
  7. // @match *://www.youtube.com/
  8. // @match *://www.youtube.com/feed/subscriptions*
  9. // @match *://www.youtube.com/watch*
  10. // @grant GM_addStyle
  11. // @run-at document-start
  12. // @license MIT
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18. // --- FINAL ADJUSTABLE VALUES (User Prefs) ---
  19. const commentTextScale = 1.15;
  20. const commentMetaScale = 1.1;
  21.  
  22. // === Grid Text Sizes (Home/Subs Feed) ===
  23. const gridTitleScale = 1.12;
  24. const gridChannelScale = 1.0;
  25. const gridMetadataScale = 1.7;
  26.  
  27. // === Grid Internal Spacing ===
  28. const gridChannelMarginTop = "-2px"; // Space ABOVE channel name line
  29. const gridMetaMarginTop = "-2px"; // Space ABOVE views/date line
  30.  
  31. // === Sidebar Text Sizes ===
  32. const sidebarTitleScale = 1.05;
  33. const sidebarChannelNameScale = 1.0;
  34. const sidebarViewsDateScale = 1.65;
  35.  
  36. // === Watch Page Owner Text Size ===
  37. const watchOwnerChannelScale = 2.1;
  38.  
  39. // === Watch Page Top Row Spacing ===
  40. const watchTopRowMarginTop = "-4px";
  41. const watchSubCountMarginTop = "-3.5px";
  42.  
  43. // === Sidebar Badge Styling ===
  44. const sidebarBadgeScale = 0.85;
  45. const sidebarBadgeMarginTop = "2px";
  46. const sidebarBadgeMarginBottom = "0px";
  47.  
  48. // --- Grid Layout Spacing ---
  49. const gridEdgePadding = "24px";
  50. const gridItemHorizontalMargin = "6px";
  51. const gridItemBottomMargin = "24px";
  52.  
  53. // === Sidebar Title Spacing ===
  54. const sidebarTitleMarginBottom = "6px";
  55.  
  56. // === Grid Badge Spacing ===
  57. const gridBadgeMarginLeft = -5;
  58.  
  59. // --- END OF ADJUSTABLE VALUES ---
  60.  
  61.  
  62. const css = `
  63. /* --- 6 VIDEOS PER ROW (via Item Width) & EDGE SPACING --- */
  64. ytd-browse[page-subtype="home"] #contents.ytd-rich-grid-renderer,
  65. ytd-browse[page-subtype="subscriptions"] #contents.ytd-rich-grid-renderer {
  66. padding-left: ${gridEdgePadding} !important;
  67. padding-right: ${gridEdgePadding} !important;
  68. box-sizing: border-box !important;
  69. }
  70. ytd-browse[page-subtype="home"] ytd-rich-item-renderer,
  71. ytd-browse[page-subtype="subscriptions"] ytd-rich-item-renderer {
  72. margin-left: ${gridItemHorizontalMargin} !important;
  73. margin-right: ${gridItemHorizontalMargin} !important;
  74. margin-bottom: ${gridItemBottomMargin} !important;
  75. max-width: calc(100% / 6 - ${gridItemHorizontalMargin} * 2 - 0.01px) !important;
  76. overflow: hidden;
  77. }
  78.  
  79.  
  80. /* --- ADJUST TEXT SIZES --- */
  81. :root {
  82. /* Grid Specific */
  83. --gm-grid-title-size: ${gridTitleScale}em;
  84. --gm-grid-channel-size: ${gridChannelScale}em;
  85. --gm-grid-metadata-size: ${gridMetadataScale}em;
  86. /* Comment Specific */
  87. --gm-comment-text-size: ${commentTextScale}em;
  88. --gm-comment-meta-size: ${commentMetaScale}em;
  89. /* Sidebar Specific */
  90. --gm-sidebar-title-size: ${sidebarTitleScale}em;
  91. --gm-sidebar-channel-size: ${sidebarChannelNameScale}em;
  92. --gm-sidebar-viewsdate-size: ${sidebarViewsDateScale}em;
  93. --gm-sidebar-badge-size: ${sidebarBadgeScale}em;
  94. /* Watch Page Owner Specific */
  95. --gm-watch-owner-channel-size: ${watchOwnerChannelScale}em;
  96. /* Other derived */
  97. --gm-watch-title-size: 1.5rem;
  98. --gm-search-title-size: 1.0rem;
  99. }
  100.  
  101. /* === GRID VIEW (Home/Subs) - Final Styles === */
  102. #video-title.ytd-rich-grid-media { /* Title */
  103. font-size: var(--gm-grid-title-size) !important;
  104. line-height: 1.2em !important;
  105. max-height: 2.4em !important;
  106. overflow: hidden;
  107. margin-bottom: 1px !important; /* Ensure minimal space below title */
  108. }
  109.  
  110. /* Channel Name Line Container */
  111. ytd-rich-grid-media #byline-container {
  112. white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important;
  113. display: flex !important; align-items: center !important;
  114. margin-top: ${gridChannelMarginTop} !important; /* ADJUSTED Space above channel */
  115. line-height: 1.2em !important; gap: 0 !important;
  116. }
  117. /* Grid Channel Name Container */
  118. ytd-rich-grid-media ytd-channel-name {
  119. font-size: var(--gm-grid-channel-size) !important; line-height: 1.25em !important;
  120. display: inline-block !important; overflow: hidden !important; text-overflow: ellipsis !important;
  121. flex-shrink: 1 !important; min-width: 0 !important;
  122. margin: 0 !important; padding: 0 !important;
  123. vertical-align: baseline !important;
  124. }
  125. /* Verified Badge */
  126. ytd-rich-grid-media ytd-channel-name ytd-badge-supported-renderer {
  127. display: inline-flex !important; align-items: center !important; justify-content: center !important;
  128. margin: 0 0 0 ${gridBadgeMarginLeft}px !important; padding: 0 !important;
  129. flex-shrink: 0 !important; line-height: 1 !important;
  130. }
  131. /* Icon DIV Container */
  132. ytd-rich-grid-media ytd-channel-name ytd-badge-supported-renderer yt-icon .yt-icon-shape > div {
  133. transform: translate(1px, -3px) !important; margin: 0 !important; padding: 0 !important; line-height: initial !important;
  134. }
  135. /* Icon element */
  136. ytd-rich-grid-media ytd-channel-name ytd-badge-supported-renderer yt-icon {
  137. margin: 0 !important; padding: 0 !important; vertical-align: initial !important;
  138. }
  139.  
  140. /* --- Metadata Line (Views/Date) --- */
  141. /* Grid metadata line container */
  142. ytd-rich-grid-media #metadata-line {
  143. line-height: 1.3em !important;
  144. margin-top: ${gridMetaMarginTop} !important; /* ADJUSTED Space above metadata */
  145. display: block !important;
  146. white-space: nowrap !important;
  147. overflow: hidden !important;
  148. text-overflow: ellipsis !important;
  149. }
  150. /* Grid Video Metadata Spans */
  151. ytd-rich-grid-media #metadata-line > span {
  152. font-size: var(--gm-grid-metadata-size) !important;
  153. line-height: 1.2em !important;
  154. display: inline !important;
  155. vertical-align: baseline !important;
  156. }
  157. /* Add space ONLY after the first span */
  158. ytd-rich-grid-media #metadata-line > span:first-of-type {
  159. margin-right: 0.5em !important;
  160. }
  161. /* REMOVE the ::after pseudo-element (bullet point) */
  162. ytd-rich-grid-media #metadata-line > span:first-of-type::after {
  163. content: none !important;
  164. }
  165.  
  166.  
  167. /* === WATCH PAGE METADATA (BELOW VIDEO) === */
  168. .title.ytd-video-primary-info-renderer h1.ytd-video-primary-info-renderer { font-size: var(--gm-watch-title-size) !important; line-height: 1.2em !important; }
  169. #top-row.ytd-watch-metadata { margin-top: ${watchTopRowMarginTop} !important; }
  170. ytd-video-owner-renderer ytd-channel-name { font-size: var(--gm-watch-owner-channel-size) !important; line-height: 1.05em !important; margin: 0 !important; padding: 0 !important; display: block !important; }
  171. #owner-sub-count.ytd-video-owner-renderer { margin-top: ${watchSubCountMarginTop} !important; margin-bottom: 0 !important; }
  172. #description-inner #description .content.ytd-video-secondary-info-renderer, .ytd-expander.ytd-video-secondary-info-renderer { font-size: 0.8em !important; line-height: 1.35em !important; }
  173. #info-text.ytd-video-primary-info-renderer { font-size: 0.8em !important; }
  174.  
  175.  
  176. /* === SIDEBAR STYLING === */
  177. ytd-compact-video-renderer h3.ytd-compact-video-renderer { margin-bottom: ${sidebarTitleMarginBottom} !important; margin-top: 0 !important; }
  178. #video-title.ytd-compact-video-renderer { font-size: var(--gm-sidebar-title-size) !important; line-height: 1.3em !important; max-height: 2.6em !important; overflow: hidden; }
  179. ytd-compact-video-renderer ytd-channel-name { font-size: var(--gm-sidebar-channel-size) !important; line-height: 1.35em !important; margin-bottom: 1px !important; }
  180. ytd-compact-video-renderer #metadata-line span.inline-metadata-item { font-size: var(--gm-sidebar-viewsdate-size) !important; line-height: 1.45em !important; }
  181. ytd-compact-video-renderer ytd-badge-supported-renderer.badges { margin-top: ${sidebarBadgeMarginTop} !important; margin-bottom: ${sidebarBadgeMarginBottom} !important; font-size: var(--gm-sidebar-badge-size) !important; line-height: 1.2 !important; }
  182.  
  183.  
  184. /* === SEARCH RESULTS === */
  185. a#video-title.ytd-video-renderer { font-size: var(--gm-search-title-size) !important; margin-bottom: 1px !important; line-height: 1.15em !important; }
  186. #metadata-line.ytd-video-meta-block { font-size: 0.75em !important; }
  187. #channel-name.ytd-video-renderer .ytd-channel-name#text, .ytd-channel-name a { font-size: 0.75em !important; }
  188. .metadata-snippet-container.ytd-video-renderer { font-size: 0.75em !important; }
  189.  
  190. /* === VIDEO PAGE: COMMENT SECTION === */
  191. yt-attributed-string#content-text.ytd-comment-view-model { font-size: var(--gm-comment-text-size) !important; line-height: 1.5em !important; }
  192. #header-author #author-text, .published-time-text.ytd-comment-renderer { font-size: var(--gm-comment-meta-size) !important; }
  193. #toolbar.ytd-comment-action-buttons-renderer { font-size: var(--gm-comment-meta-size) !important; }
  194. #header-author #author-text.ytd-comment-renderer { color: #aaa !important; }
  195.  
  196. `;
  197.  
  198. // Inject the CSS using GM_addStyle
  199. if (typeof GM_addStyle === 'function') {
  200. GM_addStyle(css);
  201. console.log("YouTube Layout Script: Final Version");
  202. } else {
  203. console.error("YouTube Layout Script: GM_addStyle is not defined.");
  204. const style = document.createElement('style');
  205. style.textContent = css;
  206. document.head.appendChild(style);
  207. }
  208.  
  209. })();