YouTube Live Borderless

Make YouTube Live Borderless

目前為 2023-01-03 提交的版本,檢視 最新版本

  1. /* ==UserStyle==
  2. @name YouTube Live Borderless
  3. @version 0.2.9
  4. @namespace github.com/cyfung1031
  5. @license MIT
  6. @description Make YouTube Live Borderless
  7. @author CY Fung
  8. @supportURL https://github.com/cyfung1031/YouTube-Live-Borderless/
  9. @compatible edge Edge [Blink] >= 105; Stylus (Beta)
  10. @compatible chrome Chrome >= 105; Stylus (Beta); Chrome 101-104 requires "enable-experimental-web-platform-features"
  11. @compatible firefox FireFox >= 103; Stylus; layout.css.has-selector.enabled = true; note: some features might not be very stable!!
  12. @compatible opera Opera >= 91; Stylus (Beta)
  13. @compatible safari Safari >= 15.4; Stylus
  14. @preprocessor stylus
  15. @var select mode-for-two-col "Mode for Two Columns" {
  16. "Expanded Panel Only (Recommended)": "expanded-panel",
  17. "Expanded Live Chat Only": "expanded-live",
  18. "Expandable Live Chat Only": "expandable-live",
  19. "Always": "always"
  20. }
  21. @var select mode-for-single-col "Mode for Single Column" {
  22. "YouTube Mobile (Recommended)": "mobile",
  23. "Normal": "normal",
  24. "Disabled": "disabled"
  25. }
  26. @var checkbox no-masthead "Hide Top Masthead Bar" 0
  27. @var number masthead-hoverable-h "MastHead Hoverable (1 = always hide)" [4, 1, 8, 1]
  28. @var range primary-content-margin "Primary Content Margin" [24, 6, 48, 6, "px"]
  29. @var checkbox no-bottom-row "Hide Primary MetaInfo Bottom Row" 0
  30. @var range video-title-size "Video Title Size" [2.0, 1.0, 3.0, 0.2, "rem"]
  31. @var range min-below-area "Minimum area below video" [120, 10, 240, 10, 'px']
  32. @var number side-panel-width "Side Panel Width" [440, 320, 640, 20, "px"]
  33. @var checkbox no-round-border "No Round Border" 1
  34. @var checkbox disable-cinematics "Disable Cinematics Effect" 0
  35. @var number chat-zoom-for-mobile "Chat Zoom for Mobile" [1.0, 0.2, 1.8, 0.05]
  36. ==/UserStyle== */
  37. /*
  38.  
  39. "Fill up Chat Area (experimental)": "chat-fill-up",
  40. @var range chrome-bottom-bar-margin "Chrome Bottom Bar Margin" [12, 6, 48, 6, "px"]
  41.  
  42. Chrome Bottom Bar Margin is 12px only due to
  43.  
  44. MU = function(a) {
  45. var b = a.u.ag()
  46. , c = a.G.getVideoData().D
  47. , d = 0;
  48. a.u.ag() && a.u.Me() && (d = (a.G.fb().getPlayerSize().width - a.G.getVideoContentRect().width) / 2);
  49. return 12 * (c ? 0 : b ? 2 : 1) + d
  50. }
  51.  
  52. */
  53.  
  54. @-moz-document url-prefix("https://www.youtube.com/watch?v=") {
  55.  
  56. dummy() {
  57. // dummy
  58. border: 0;
  59. }
  60. masthead-hoverable-height=(masthead-hoverable-h - 1) * 2px
  61.  
  62. no-masthead-w=no-masthead //
  63. chrome-bottom-bar-margin=12px // this cannot be changed
  64.  
  65. single-col-mobile=0 //
  66. if mode-for-single-col=="mobile" {
  67. single-col-mobile=1 //
  68. if no-masthead==0 {
  69. no-masthead-w=2 //
  70. }
  71. }
  72. chat-zoom-for-mobile-enable = ((chat-zoom-for-mobile < 1) or (chat-zoom-for-mobile > 1))
  73.  
  74. //
  75. contentNoMasthead() {
  76.  
  77. &,
  78. ytd-app,
  79. ytd-page-manager[class].style-scope,
  80. ytd-watch-flexy[class].style-scope {
  81. /* 0px not 0 */
  82. --ytd-masthead-height: 0px;
  83. --ytd-toolbar-height: 0px;
  84. --ytd-watch-flexy-masthead-height: 0px;
  85. }
  86.  
  87. #masthead-container {
  88. height: 0;
  89. --masthead-opacity: 0;
  90. opacity: var(--masthead-opacity) !important;
  91. transition: opacity 300ms;
  92. min-height: masthead-hoverable-height;
  93. contain: layout size style;
  94. }
  95.  
  96. #masthead-container > ytd-masthead {
  97. transform: translateY(-100%);
  98. transition: transform 300ms;
  99. }
  100.  
  101. if masthead-hoverable-height > 0 {
  102.  
  103.  
  104. #masthead-container:hover {
  105. --masthead-opacity: 1;
  106. }
  107.  
  108. #masthead-container:hover > ytd-masthead {
  109. transform: translateY(0%);
  110. }
  111.  
  112. #masthead-container::after {
  113. content: '';
  114. display: flex;
  115. width: 100%;
  116. height: masthead-hoverable-height;
  117. top: 0;
  118. z-index: 77;
  119. cursor: default;
  120. user-select: none !important;
  121. touch-action: none !important;
  122. box-sizing: border-box;
  123. padding: 0;
  124. margin: 0;
  125. }
  126. }
  127.  
  128. ytd-watch-flexy.style-scope[is-two-columns_]:not([fullscreen]):not([theater]) {
  129.  
  130. #columns.style-scope.ytd-watch-flexy,
  131. #primary.style-scope.ytd-watch-flexy,
  132. #primary-inner.style-scope.ytd-watch-flexy,
  133. #secondary.style-scope.ytd-watch-flexy,
  134. #secondary-inner.style-scope.ytd-watch-flexy {
  135. height: 100vh;
  136. max-height: 100%;
  137. }
  138. }
  139.  
  140. ytd-watch-flexy.style-scope[is-two-columns_][theater]:not([fullscreen]) {
  141.  
  142. height: 100vh;
  143. #player-theater-container.ytd-watch-flexy {
  144. flex: 77;
  145. max-height: unset;
  146. }
  147.  
  148. #player-theater-container.ytd-watch-flexy ~ #columns.style-scope.ytd-watch-flexy {
  149. overflow: visible;
  150. }
  151. }
  152.  
  153.  
  154. ytd-watch-flexy.style-scope:not([fullscreen]) {
  155.  
  156. #movie_player .html5-video-container > video[style*="top:"]:not(video[style*="top: -"]):not(video[style*="top:-"]) {
  157. top: 0 !important;
  158. }
  159. }
  160. } //
  161. contentSingleColMobile(){
  162. // html:has(ytd-watch-flexy:not([is-two-columns_]):not([fullscreen]))
  163.  
  164. #chat:not([collapsed]) {
  165. --ytd-margin-2x: 0;
  166. --ytd-margin-4x: 0;
  167. --ytd-margin-6x: 0;
  168. --ytd-margin-8x: 0;
  169. height: 100% !important;
  170. min-height: unset !important;
  171. max-height: 100vh !important;
  172.  
  173. --single-col-mobile-below-inside-display: flex;
  174.  
  175.  
  176.  
  177. if chat-zoom-for-mobile-enable {
  178.  
  179.  
  180. iframe#chatframe {
  181. iframe-transform = 'scale(%s)' % chat-zoom-for-mobile
  182. iframe-ratio = 100% / chat-zoom-for-mobile
  183. transform: iframe-transform;
  184. height: iframe-ratio;
  185. position: absolute;
  186. /* max-height: unset !important; */
  187. transform-origin: 0 0;
  188. width: iframe-ratio;
  189. }
  190.  
  191.  
  192. }
  193.  
  194.  
  195. }
  196.  
  197. &:has(#chat:not([collapsed])) {
  198.  
  199. #contentContainer.tp-yt-app-drawer[swipe-open].tp-yt-app-drawer::after {
  200.  
  201. content: unset;
  202.  
  203. }
  204.  
  205. #primary-inner.ytd-watch-flexy ytd-comments#comments.ytd-watch-flexy,
  206. #below.ytd-watch-flexy > #related.ytd-watch-flexy,
  207. #below.ytd-watch-flexy > ytd-watch-metadata.ytd-watch-flexy {
  208. display:none !important;
  209. }
  210.  
  211. #secondary.ytd-watch-flexy {
  212. display: none !important;
  213. }
  214.  
  215.  
  216.  
  217. .efyt-control-bar {
  218. position: relative;
  219. display: inline-flex;
  220. top: auto;
  221. left: auto;
  222. z-index: 99999;
  223. opacity: 0.8;
  224. transform: translate(calc(-100% + 32px), 0) !important;
  225. }
  226.  
  227. .efyt-control-bar:hover {
  228. opacity: 1.0;
  229. background: var(--yt-spec-general-background-a);
  230. transform: translate(0px, 0) !important;
  231. }
  232.  
  233. #player {
  234. margin-bottom: 0;
  235. }
  236.  
  237. #columns,
  238. #primary {
  239. padding: 0;
  240. }
  241.  
  242. #player,
  243. #player-theater-container,
  244. #player-container-outer,
  245. #player-container-inner,
  246. #player-container,
  247. #movie_player,
  248. #movie_player video {
  249. object-fit: contain;
  250. max-height: calc(100vh - 400px) !important;
  251. }
  252.  
  253. #primary-inner.ytd-watch-flexy > :not(.style-scope) {
  254. display: none !important;
  255. }
  256.  
  257.  
  258. #below > * {
  259. display: var(--single-col-mobile-below-inside-display) !important;
  260. }
  261.  
  262. #below:not(:has(#chat)) {
  263. display: none;
  264. }
  265.  
  266. ytd-watch-flexy,
  267. #columns.ytd-watch-flexy,
  268. #primary.ytd-watch-flexy,
  269. #primary-inner.ytd-watch-flexy {
  270. display: flex;
  271. flex-direction: column;
  272. margin: 0;
  273. flex: 1;
  274. }
  275.  
  276. #below {
  277. flex: 1;
  278. }
  279.  
  280. ytd-watch-flexy {
  281. height: 100vh !important;
  282. max-height: 100vh !important;
  283. }
  284.  
  285. ytd-watch-flexy[theater] #player-theater-container.ytd-watch-flexy,
  286. ytd-watch-flexy[fullscreen] #player-theater-container.ytd-watch-flexy {
  287.  
  288. min-height: unset !important;
  289. }
  290. }
  291. }
  292. contentf() {
  293.  
  294.  
  295. &:not([tabview-loaded]) {
  296.  
  297. #primary-inner.ytd-watch-flexy ytd-comments#comments.ytd-watch-flexy,
  298. #secondary-inner.ytd-watch-flexy > #related.ytd-watch-flexy {
  299. display: none !important;
  300. }
  301.  
  302. #player-theater-container {
  303. max-height: calc(100vh - 100px) !important;
  304. }
  305.  
  306. #cinematics {
  307. // contain: layout;
  308. contain: layout size style;
  309. user-select: none;
  310. touch-action: none;
  311. pointer-events: none;
  312. }
  313. }
  314.  
  315.  
  316. if no-masthead-w==2 {
  317. //
  318. } else if no-masthead-w==1 {
  319.  
  320. contentNoMasthead()
  321. }
  322.  
  323. else {
  324.  
  325. ytd-watch-flexy.style-scope[is-two-columns_]:not([theater]):not([fullscreen]) {
  326.  
  327. #secondary.style-scope.ytd-watch-flexy,
  328. #secondary-inner.style-scope.ytd-watch-flexy {
  329. height: calc(100vh - var(--ytd-toolbar-height));
  330. max-height: 100%;
  331. }
  332. }
  333. }
  334.  
  335.  
  336.  
  337. if no-bottom-row {
  338.  
  339. #bottom-row.ytd-watch-metadata {
  340. display: none !important;
  341. }
  342. }
  343.  
  344. h1.ytd-watch-metadata {
  345. font-size: video-title-size;
  346. --font-size: video-title-size;
  347. line-height: calc(var(--font-size) * 1.4);
  348. }
  349.  
  350. & {
  351. --ylb-min-below-area: min-below-area;
  352. }
  353.  
  354. ytd-watch-flexy.style-scope:not([fullscreen]) {
  355.  
  356. & {
  357. --ytd-margin-2y: var(--ytd-margin-2x);
  358. --ytd-margin-4y: var(--ytd-margin-4x);
  359. --ytd-margin-6y: var(--ytd-margin-6x);
  360. --ytd-margin-8y: var(--ytd-margin-8x);
  361. }
  362.  
  363. #columns.style-scope.ytd-watch-flexy {
  364. --ytd-margin-2x: 0;
  365. --ytd-margin-4x: 0;
  366. --ytd-margin-6x: 0;
  367. --ytd-margin-8x: 0;
  368. }
  369.  
  370. .style-scope.ytd-watch-flexy > :not(.ytd-watch-flexy),
  371. #below,
  372. #player {
  373. --ytd-margin-2x: var(--ytd-margin-2y);
  374. --ytd-margin-4x: var(--ytd-margin-4y);
  375. --ytd-margin-6x: var(--ytd-margin-6y);
  376. --ytd-margin-8x: var(--ytd-margin-8y);
  377. }
  378.  
  379. #secondary-inner.style-scope.ytd-watch-flexy {
  380. display: flex;
  381. flex-direction: column;
  382. height: 100%;
  383. }
  384.  
  385. #movie_player {
  386. position: relative;
  387. > .html5-video-container:has(video) {
  388. top: 0;
  389. bottom: 0;
  390. left: 0;
  391. right: 0;
  392. position: absolute;
  393. }
  394.  
  395. .ytp-chrome-bottom[style*="width"] {
  396. width: unset !important;
  397. left: chrome-bottom-bar-margin !important;
  398. right: chrome-bottom-bar-margin !important;
  399. }
  400.  
  401. .html5-video-container > video {
  402. width: unset !important;
  403. height: 100% !important;
  404. left: 0 !important;
  405. right: 0 !important;
  406. max-height: 100%;
  407. max-width: 100%;
  408. margin: 0 auto;
  409. }
  410.  
  411. .ytp-iv-video-content {
  412. width: 100% !important;
  413. height: 100% !important;
  414. }
  415.  
  416. /*
  417. // this is buggy; eg multiple chapter hover container; can be fixed by YouTube Video Resize Fix Only
  418. .ytp-chapter-hover-container[style*="width"] {
  419. width: 100% !important;
  420. }
  421. */
  422. }
  423.  
  424. #chat:not([collapsed]) {
  425. flex: 77;
  426. }
  427.  
  428. #right-tabs {
  429. display: flex;
  430. margin: 0 !important;
  431. flex: 1;
  432. flex-direction: column;
  433.  
  434. #material-tabs,
  435. .tab-content {
  436. outline: 0;
  437. }
  438.  
  439. .tab-content {
  440. flex: 77;
  441. }
  442. }
  443.  
  444. &[is-two-columns_] #primary-inner > *:not(#player) {
  445. padding: 0 primary-content-margin 0;
  446. }
  447.  
  448. &:not([is-two-columns_]) #primary-inner > *:not(#player) {
  449. padding: 0;
  450. }
  451.  
  452. &:not([is-two-columns_]) #primary-inner #below > *:not(ytd-live-chat-frame#chat) {
  453. padding: 0 primary-content-margin 0;
  454. }
  455.  
  456. #player-container-outer.ytd-watch-flexy {
  457. max-width: unset;
  458. }
  459. }
  460.  
  461. ytd-watch-flexy.style-scope[is-two-columns_]:not([theater]):not([fullscreen]) {
  462.  
  463.  
  464. ytd-live-chat-frame#chat:not([collapsed]) {
  465. min-height: unset;
  466. }
  467. }
  468.  
  469. if min-below-area > 0 {
  470.  
  471.  
  472. ytd-watch-flexy.style-scope[is-two-columns_]:not([theater]):not([fullscreen]) {
  473.  
  474. #player #player-container-outer.ytd-watch-flexy, // layout outside
  475. #player #player-container-inner.ytd-watch-flexy, // no effect
  476. #player #player-container.ytd-watch-flexy { // layout inside
  477. max-height: calc(100vh - var(--ytd-toolbar-height, 0px) - var(--ylb-min-below-area, 0px));
  478. }
  479. }
  480.  
  481. ytd-watch-flexy.style-scope[is-two-columns_][theater]:not([fullscreen]) {
  482.  
  483. #player-theater-container.ytd-watch-flexy {
  484. max-height: calc(100vh - var(--ytd-toolbar-height, 0px) - var(--ylb-min-below-area, 0px));
  485. }
  486. }
  487. }
  488.  
  489. else {
  490.  
  491.  
  492. ytd-watch-flexy.style-scope[is-two-columns_]:not([theater]):not([fullscreen]) {
  493.  
  494. #player #player-container-outer.ytd-watch-flexy,
  495. #player #player-container-inner.ytd-watch-flexy,
  496. #player #player-container.ytd-watch-flexy {
  497. max-height: calc(100vh - var(--ytd-toolbar-height, 0px)); // for very wide screen
  498. }
  499. }
  500.  
  501. ytd-watch-flexy.style-scope[is-two-columns_][theater]:not([fullscreen]) {
  502.  
  503. #player-theater-container.ytd-watch-flexy {
  504. max-height: calc(100vh - var(--ytd-toolbar-height, 0px)); // for 4:3 video
  505. }
  506. }
  507. }
  508.  
  509.  
  510. body.lock-scrollbar[style*="overflow"][style*="hidden"]:has(ytd-watch-flexy[is-two-columns_] #columns.ytd-watch-flexy #primary-inner.ytd-watch-flexy #player #movie_player video[src]) { // note: might not be supported by FireFox due to its bug
  511. overflow-y: unset !important;
  512. }
  513.  
  514.  
  515. ytd-watch-flexy.style-scope[is-two-columns_] #columns.ytd-watch-flexy > #secondary.ytd-watch-flexy {
  516. width: side-panel-width;
  517. }
  518.  
  519. if no-round-border {
  520.  
  521. ytd-live-chat-frame[rounded-container],
  522. ytd-live-chat-frame[rounded-container] #show-hide-button.ytd-live-chat-frame ytd-toggle-button-renderer.ytd-live-chat-frame,
  523. ytd-live-chat-frame[rounded-container] iframe.ytd-live-chat-frame,
  524. ytd-live-chat-frame[rounded-container] #show-hide-button.ytd-live-chat-frame ytd-toggle-button-renderer.ytd-live-chat-frame button.yt-spec-button-shape-next,
  525. ytd-live-chat-frame[rounded-container] #show-hide-button.ytd-live-chat-frame ytd-toggle-button-renderer.ytd-live-chat-frame button.yt-spec-button-shape-next:hover {
  526. border-radius: unset;
  527. }
  528. }
  529.  
  530. if mode-for-single-col=="chat-fill-up" {
  531.  
  532. &:has(#below > #chat:not([collapsed])):not([tabview-loaded]) { // note: might not be supported by FireFox due to its bug
  533.  
  534. #primary-inner.style-scope.ytd-watch-flexy {
  535. max-height: 100vh;
  536. display: flex;
  537. flex-direction: column;
  538. }
  539.  
  540. #below.style-scope.ytd-watch-flexy {
  541. flex-shrink: 1;
  542. overflow: auto;
  543. position: relative;
  544. padding-top: 100%;
  545. }
  546.  
  547. #below.style-scope.ytd-watch-flexy > #chat.style-scope.ytd-watch-flexy:not([collapsed]) {
  548. margin: 0;
  549. min-height: unset;
  550. height: auto;
  551. position: absolute;
  552. top: 0;
  553. bottom: 0;
  554. right: 0;
  555. left: 0;
  556. top: 0;
  557. }
  558. }
  559. }
  560.  
  561. if disable-cinematics {
  562. #cinematics.ytd-watch-flexy {
  563. display: none;
  564. }
  565. }
  566. } //
  567. contentg() {
  568. if mode-for-single-col=="disabled" {
  569. &:has(ytd-watch-flexy[is-two-columns_]){
  570. contentf()
  571. }
  572. } else {
  573. contentf()
  574. }
  575. }
  576. if mode-for-two-col == "expanded-panel" {
  577. html:has(ytd-live-chat-frame#chat:not([collapsed])):has(iframe#chatframe),
  578. /*
  579. html:has(ytd-engagement-panel-section-list-renderer[visibility="ENGAGEMENT_PANEL_VISIBILITY_EXPANDED"]:not([hidden])),
  580. html:has(.tab-content-cld:not(.tab-content-hidden)),
  581. */
  582. html[tabview-loaded]:has(ytd-watch-flexy[is-two-columns_]:not([fullscreen]):not([theater])) {
  583. contentg() //
  584. }
  585. } else if mode-for-two-col == "expanded-live" {
  586. html:has(ytd-live-chat-frame#chat:not([collapsed])):has(iframe#chatframe) {
  587. contentg() //
  588. }
  589. } else if mode-for-two-col == "expandable-live" {
  590. html:has(ytd-live-chat-frame#chat):has(iframe#chatframe) {
  591. contentg() //
  592. }
  593. } else if mode-for-two-col == "always" {
  594. html { //
  595. contentg() //
  596. }
  597. }
  598.  
  599. if single-col-mobile {
  600. html {
  601. --single-col-mobile-below-inside-display: none;
  602. }
  603. &:has(ytd-watch-flexy:not([is-two-columns_]):not([fullscreen])) {
  604.  
  605. if no-masthead-w==2 {
  606. contentNoMasthead()
  607. }
  608. contentSingleColMobile()
  609. }
  610. }
  611. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址