Twitter.com: un-trim images on hover

Reveal cropped portions of content while post is under mouse pointer.

当前为 2021-02-28 提交的版本,查看 最新版本

  1. /* ==UserStyle==
  2. @name Twitter.com: un-trim images on hover
  3. @description Reveal cropped portions of content while post is under mouse pointer.
  4. @namespace myfonj
  5. @version 1.0.9
  6. @license CC0 - Public Domain
  7. ==/UserStyle== */
  8.  
  9. @-moz-document domain("twitter.com") {
  10. /*
  11. Twitter.com: un-trim images on hover
  12.  
  13. https://greasyfork.org/en/scripts/402913/versions/new
  14. https://userstyles.org/styles/175427/edit
  15. div[aria-label^="Timeline: "] > div > div
  16. = "post item"
  17. */
  18. /*
  19. let the spice flow. over.
  20. */
  21. div[aria-label^="Timeline: "] > div > div:hover {
  22. overflow: visible !important;
  23. z-index: 10;
  24. }
  25. div[aria-label^="Timeline: "] > div > div:hover * {
  26. overflow: visible !important;
  27. }
  28. /*
  29. directly hovered position something always above its unhovered siblings
  30. */
  31. div[aria-label^="Timeline: "] > div > div:hover *:hover {
  32. z-index: 20;
  33. }
  34. /*
  35. counters covered by box would be inaccessible, move them above and make 'em transparent ...
  36. */
  37. div[aria-label^="Timeline: "] > div > div:hover [role="group"],
  38. div[aria-label^="Timeline: "] > div > div:hover [role="link"][data-focusable="true"][href$="/media_tags"] {
  39. z-index: 30;
  40. opacity: 0;
  41. }
  42.  
  43. /* tweet actions */
  44. div[aria-label^="Timeline: "] > div > div:hover [role="group"] {
  45. outline: 20px solid rgba(0, 0, 0, 0.5);
  46. background-color: rgba(0, 0, 0, 0.5);
  47. }
  48. /*
  49. ... until hovered
  50. */
  51. div[aria-label^="Timeline: "] > div > div:hover [role="group"]:hover,
  52. div[aria-label^="Timeline: "] > div > div:hover [role="link"][data-focusable="true"][href$="/media_tags"]:hover {
  53. opacity: 1 !important;
  54. }
  55.  
  56. /*
  57. fix for external link badge text underlayed by illustration producing non-contrasting text
  58. */
  59. div[aria-label^="Timeline: "] > div > div:hover a[href^="https://t.co/"][href$="?amp=1"][target="_blank"][role="link"][data-focusable="true"][rel=" noopener noreferrer"]:hover {
  60. background-color: rgba(0, 0, 0, 0.5);
  61. }
  62. /* tweet text */
  63. div[aria-label^="Timeline: "] > div > div [style^="flex-basis"] + div [dir][lang]:hover,
  64. div[aria-label^="Timeline: "] > div > div [style^="flex-basis"]:hover + div [dir][lang] {
  65. z-index: 30;
  66. background-color: rgba(0, 0, 0, 0.5);
  67. border-left: 10px solid transparent;
  68. margin-left: -10px;
  69. }
  70. /*
  71. this is it - this *invisible* image just sits there covering div with very same image as background,
  72. "squeezed" into wrapper. so let's unleash it while invisible to gain some performace
  73. */
  74. div[aria-label^="Timeline: "] > div > div [aria-label] > img {
  75. width: auto !important;
  76. height: auto !important;
  77. max-width: calc(100vw - 20em) !important;
  78. /* too lazy to measure sidebar for now */
  79. min-width: calc(100%) !important;
  80. /* sometimes there is small pic that would otherwise downscale */
  81. outline: 3px solid black;
  82. z-index: 100 !important;
  83. }
  84. /*
  85. tadaa, real pic an all its glory. most probably bigger
  86. */
  87. div[aria-label^="Timeline: "] > div > div:hover [aria-label] > img {
  88. opacity: 1 !important;
  89. }
  90. div[aria-label^="Timeline: "] > div > div:hover [aria-label] > img:hover {
  91. box-shadow: rgba(217, 217, 217, 0.2) 0px 0px 10px, rgba(217, 217, 217, 0.25) 0px 3px 6px 3px;
  92. }
  93.  
  94. /* 2020-06 - avatars in timeline started to follow same principle, so became hover "jumpy"
  95. since we are zooming them in detail popups anyway, just be dirty and brutal for now
  96. N.B. beautiful selector for picking avatar "cell" is sometimes [style="flex-basis: 49px;"]
  97. but pixel value changes across devices (or what)
  98. */
  99. [href^="/"][role="link"][aria-hidden="true"][tabindex="-1"] img, /* in notifications */
  100. div[aria-label^="Timeline: "]:not(#\0) [style^="flex-basis: "][style$="px;"] img {
  101. display: none !important;
  102. outline: 1px solid red !important;
  103. }
  104.  
  105. /*
  106. Increase size of avatar pictures in hover popup
  107. this is hell to debug, so please dont't judge
  108. the popup has bottom/top according relative placement in viewport
  109. */
  110.  
  111.  
  112. [style*="left: "] a[role="link"][tabindex="-1"][aria-hidden="true"],
  113. [style*="left: "] a[role="link"][tabindex="-1"][aria-hidden="true"] * {
  114. min-height: 12em !important;
  115. min-width: 12em !important;
  116. margin: 0 !important;
  117. padding: 0 !important;
  118. background-size: contain;
  119. }
  120.  
  121.  
  122. /*
  123. fix video player controls
  124. since it is serious mess, lets adore the emphemeral structure I had to sieve trough:
  125. */
  126. /*
  127. // for ilustration, where it begins. from here it is just classes copied from devtools
  128. (unreliable I assume) and some hand copied attributes
  129. html
  130. > body>
  131. > div#react-root
  132. > div.css-1dbjc4n.r-13awgt0.r-12vffkv
  133. > div.css-1dbjc4n.r-13awgt0.r-12vffkv
  134. > div.css-1dbjc4n.r-18u37iz.r-13qz1uu.r-417010
  135. > main.css-1dbjc4n.r-1habvwh.r-16xksha.r-1wbh5a2
  136. > div.css-1dbjc4n.r-150rngu.r-16y2uox.r-1wbh5a2.r-33ulu8
  137. > div.css-1dbjc4n.r-aqfbo4.r-16y2uox
  138. > div.css-1dbjc4n.r-1oszu61.r-1niwhzg.r-18u37iz.r-16y2uox.r-1wtj0ep.r-2llsf.r-13qz1uu
  139. > div.css-1dbjc4n.r-yfoy6g.r-18bvks7.r-1ljd8xs.r-13l2t4g.r-1phboty.r-1jgb5lz.r-11wrixw.r-61z16t.r-1ye8kvj.r-13qz1uu.r-184en5c
  140. > div.css-1dbjc4n
  141. > div.css-1dbjc4n
  142. > div.css-1dbjc4n.r-16y2uox
  143. > div.css-1dbjc4n.r-1jgb5lz.r-1ye8kvj.r-13qz1uu
  144. > div.css-1dbjc4n
  145. > section.css-1dbjc4n
  146. > div.css-1dbjc4n[aria-label^="Timeline: "]:not([REM="yup, this is the timeline"])
  147. > div[style^="position: relative; min-height: "][style$="px;"]
  148. > div[style^="position: absolute; width: 100%; transform: translateY("][style$="px); transition: opacity 0.3s ease-out 0s;"]:not([REM="THIS IS ACTUAL POST WRAPPER"])
  149. > div.css-1dbjc4n.r-1ila09b.r-qklmqi.r-1adg3ll.r-1ny4l3l
  150. > div.css-1dbjc4n
  151. > article.css-1dbjc4n.r-1loqt21.r-18u37iz.r-1ny4l3l.r-o7ynqc.r-6416eg
  152. > div.css-1dbjc4n.r-eqz5dr.r-16y2uox.r-1wbh5a2
  153. > div.css-1dbjc4n.r-16y2uox.r-1wbh5a2.r-1ny4l3l.r-1udh08x.r-1yt7n81.r-ry3cjt
  154. > div.css-1dbjc4n
  155. > div.css-1dbjc4n.r-18u37iz
  156. > div.css-1dbjc4n.r-1iusvr4.r-16y2uox.r-1777fci.r-1mi0q7o
  157. > div.css-1dbjc4n
  158. > div.css-1dbjc4n
  159. > div[class]:only-child
  160. > div[class]:only-child
  161. > div[class]:only-child
  162. > div[class]:only-child
  163. |
  164. _______________________________________________________________/
  165. / from here on just "reliable" attributes and pseudo-structure
  166. |
  167. > div[style="padding-bottom: 56.25%;"]:first-child
  168. + div:last-child
  169. > div[data-testid="placementTracking"]
  170. > div[data-testid="videoPlayer"]
  171. > div
  172. > div[style="padding-bottom: 56.25%;"]:first-child
  173. + div:last-child
  174. > div[style="height: 100%; position: relative; transform: translateZ(0px); width: 100%;"]
  175. > div[style="height: 100%; position: absolute; width: 100%;"]:not([class]):first-child
  176. > div[style="position: relative; width: 100%; height: 100%; background-color: transparent; overflow: hidden;"]
  177. > video:not([REM="OMG, here is the video"])
  178. + div:not([style]):last-child
  179. > div:not([class]):only-child
  180. > div:first-child:not([REM="this is the bugger I couldn't push under the video controls"])
  181. + div:not([class])
  182. + div:not([class])
  183. + div:not([class])
  184. > div[style="transition-duration: 250ms; transition-property: opacity, height; transition-timing-function: ease; will-change: opacity; opacity: 1;"]
  185. > div[class]
  186. > div[style="background-image: linear-gradient(transparent, rgba(0, 0, 0, 0.77));"]
  187. > div:first-child:not([REM="this is progress / seeker wrapper"])
  188. + div:last-child:not([REM="this is video controls wrapper"])
  189. */
  190.  
  191. div[style^="padding-bottom: "][style$="%;"]:first-child
  192. + div:last-child
  193. > div[data-testid="placementTracking"]
  194. > div[data-testid="videoPlayer"]
  195. > div
  196. > div[style^="padding-bottom: "][style$="%;"]:first-child
  197. + div:last-child
  198. > div[style="height: 100%; position: relative; transform: translateZ(0px); width: 100%;"]
  199. > div[style="height: 100%; position: absolute; width: 100%;"]:not([class]):first-child
  200. + div:not([style]):last-child
  201. > div:not([class]):only-child
  202. > div:first-child:not([REM="this is the bugger I couldn't push under the video controls"])
  203. {
  204. z-index: 0;
  205. }
  206. /*
  207. [:shivers:]
  208. */
  209. }