markup.css (17118B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 :root { 6 --markup-hidden-attr-color: light-dark(var(--grey-70), var(--grey-30)); 7 --markup-hidden-punctuation-color: light-dark(var(--grey-50), var(--grey-40)); 8 --markup-pseudoclass-disk-color: #e9c600; 9 --markup-hidden-tag-color: light-dark(var(--grey-50), var(--grey-45)); 10 --markup-outline: light-dark(var(--theme-splitter-color), var(--theme-selection-background)); 11 --markup-drag-line: light-dark(var(--grey-40), var(--grey-55)); 12 --markup-drop-line: light-dark(var(--blue-55), var(--blue-50)); 13 --markup-overflow-causing-background-color: light-dark(rgba(128, 0, 215, 0.15), rgba(148, 0, 255, 0.38)); 14 --markup-new-attr-size: 2ch; 15 --markup-new-attr-focused-margin-inline: 1ch 2px; 16 --markup-selected-focus-visible-non-highlighted-color: light-dark(var(--theme-body-color), var(--theme-text-color-strong)); 17 18 &[forced-colors-active] { 19 --markup-hidden-attr-color: GrayText; 20 --markup-hidden-punctuation-color: GrayText; 21 --markup-hidden-tag-color: GrayText; 22 /* In regular mode, this variable relies on --theme-body-color, which is already set 23 to CanvasText for HCM, BUT: we still need to force it here because of Bug 1917523 */ 24 --markup-selected-focus-visible-non-highlighted-color: CanvasText; 25 --markup-drag-line: GrayText; 26 --markup-drop-line: SelectedItem; 27 } 28 } 29 30 * { 31 padding: 0; 32 margin: 0; 33 } 34 35 :root { 36 -moz-control-character-visibility: visible; 37 } 38 39 body { 40 user-select: none; 41 } 42 43 /* Force height and width (possibly overflowing) from inline elements. 44 * This allows long overflows of text or input fields to still be styled with 45 * the container, rather than the background disappearing when scrolling */ 46 #root { 47 float: left; /* The markup view should always be LTR */ 48 min-width: 100%; 49 box-sizing: border-box; 50 51 & > ul[role="tree"] { 52 /* Reserve extra space (in addition to the indent size) for DOM mutation 53 * breakpoint and pseudo icons. */ 54 padding-inline-start: 6px; 55 outline-offset: -2px; 56 } 57 } 58 59 /* Reset the global rotation of the icon done for RTL layout. 60 Markup view is always LTR */ 61 #root .theme-twisty:not(.open):dir(rtl), 62 #root .theme-twisty:not([open]):-moz-locale-dir(rtl) { 63 transform: rotate(-90deg); 64 } 65 66 /* Don't display a parent-child outline for the root elements */ 67 #root > ul > li > .children { 68 background: none; 69 } 70 71 html.dragging { 72 overflow-x: hidden; 73 } 74 75 body.dragging .tag-line { 76 cursor: grabbing; 77 } 78 79 #root-wrapper:after { 80 content: ""; 81 display: block; 82 clear: both; 83 position: relative; 84 } 85 86 .html-editor { 87 display: none; 88 position: absolute; 89 z-index: 2; 90 91 /* Use the same margin/padding trick used by .child tags to ensure that 92 * the editor covers up any content to the left (including expander arrows 93 * and hover effects). */ 94 margin-left: -1000em; 95 padding-left: 1000em; 96 } 97 98 .html-editor-inner { 99 border: solid 0.1px; 100 flex: 1 1 auto; 101 102 /* Keep the editor away from the markup view floating scrollbars */ 103 margin-inline-end: 12px; 104 } 105 106 .html-editor iframe { 107 height: 100%; 108 width: 100%; 109 border: none; 110 margin: 0; 111 padding: 0; 112 } 113 114 .children { 115 list-style: none; 116 padding: 0; 117 margin: 0; 118 } 119 120 /* Tags are organized in a UL/LI tree and indented thanks to a left padding. 121 * A very large padding is used in combination with a slightly smaller margin 122 * to make sure childs actually span from edge-to-edge. */ 123 .child { 124 margin-left: -10000px; 125 padding-left: 10011px; 126 } 127 128 /* Normally this element takes space in the layout even if it's position: relative 129 * by adding height: 0 we let surrounding elements to fill the blank space */ 130 .child.dragging { 131 position: relative; 132 pointer-events: none; 133 opacity: 0.7; 134 z-index: 1; 135 height: 0; 136 137 :root[forced-colors-active] & { 138 opacity: 1; 139 z-index: 2; 140 } 141 } 142 143 /* Indicates a tag-line in the markup-view as being an active drop target by 144 * drawing a horizontal line where the dragged element would be inserted if 145 * dropped here */ 146 .tag-line.drop-target::before, 147 .tag-line.drag-target::before { 148 content: ""; 149 position: absolute; 150 top: -1px; 151 height: 2px; 152 /* Offset these by 1000px to make sure they cover the full width of the view */ 153 width: calc(100% + 1000px); 154 left: -1000px; 155 background-color: var(--markup-drag-line); 156 } 157 158 .tag-line.drop-target::before { 159 background-color: var(--markup-drop-line); 160 } 161 162 /* In case the indicator is put on the closing .tag-line, the indentation level 163 * will become misleading, so we push it forward to match the indentation level */ 164 ul.children + .tag-line::before { 165 margin-left: 14px; 166 } 167 168 /* A tag line should have a height of 16px, with a line-height of 14px, 169 * (assuming a font-size of 11px). */ 170 .tag-line { 171 font-size: var(--theme-code-font-size); 172 min-height: 1.2727em; 173 line-height: 1.2727em; 174 padding-block: 1px; 175 position: relative; 176 cursor: default; 177 } 178 179 /* Change selected line style when editing an attribute */ 180 .tag-line[selected]:has(.styleinspector-propertyeditor:focus) .theme-selected { 181 background-color: var(--theme-body-alternate-emphasized-background); 182 color: unset; 183 184 /* revert the icon to the color it has when the line doesn't have the "selection" background */ 185 & ~ .theme-twisty { 186 fill: var(--theme-icon-dimmed-color); 187 } 188 } 189 190 .tag-line[selected] + .children, 191 .tag-line[selected] ~ .tag-line { 192 background-image: linear-gradient(to top, var(--markup-outline), var(--markup-outline)); 193 background-position: 0 0; 194 background-repeat: no-repeat; 195 background-size: 1.5px 100%; 196 padding-left: 8px; 197 margin-left: -8px; 198 } 199 200 .tag-line[selected] + .children { 201 background-position-y: 2px; 202 } 203 204 .tag-line[selected] ~ .tag-line { 205 background-position-y: -2px; 206 /* Unset transition-property to prevent the markup outline from horizontal shifting */ 207 transition-property: none; 208 } 209 210 /** 211 * Positioning the mutation marker on the viewport's left edge: 212 * - left: walk back the indentation level up 213 * - margin-left: walk back the #root's 6px padding-left 214 * (plus hide the leftmost 2px of the icon outside the viewport) 215 */ 216 .markup-tag-mutation-marker { 217 display: none; 218 position: absolute; 219 top: 2px; 220 left: calc(var(--markup-level, 1) * -11px); 221 margin-left: -8px; 222 height: 12px; 223 width: 12px; 224 background-image: url(chrome://devtools/content/debugger/images/markup-breakpoint.svg); 225 background-repeat: no-repeat; 226 background-size: 12px 12px; 227 background-position: right center; 228 -moz-context-properties: fill, stroke; 229 fill: var(--blue-50); 230 fill-opacity: 1; 231 opacity: 1; 232 stroke: none; 233 z-index: 2; 234 } 235 236 .markup-tag-mutation-marker.has-mutations { 237 display: block; 238 } 239 240 .markup-tag-mutation-marker.has-mutations.mutation-breakpoint-disabled { 241 opacity: 0.6; 242 } 243 244 .tag-line[selected] .markup-tag-mutation-marker.mutation-breakpoint-disabled { 245 fill: #fff; 246 stroke: none; 247 } 248 249 .tag-line[selected] .markup-tag-mutation-marker { 250 stroke: #fff; 251 } 252 253 .html-editor-container { 254 position: relative; 255 min-height: 200px; 256 } 257 258 /* This extra element placed in each tag is positioned absolutely to cover the 259 * whole tag line and is used for background styling (when a selection is made 260 * or when the tag is flashing) */ 261 .tag-line .tag-state { 262 position: absolute; 263 left: -1000em; 264 right: 0; 265 top: 0; 266 height: 100%; 267 z-index: 0; 268 } 269 270 .tag-line .tag-hover:not(.theme-selected) { 271 background: var(--theme-selection-background-hover); 272 z-index: -1; 273 } 274 275 .expander { 276 display: inline-block; 277 vertical-align: top; 278 width: 14px; 279 height: 16px; 280 margin: -1px 0 -1px -14px; 281 /* Make sure the expander still appears above the tag-state */ 282 position: relative; 283 z-index: 1; 284 } 285 286 .child.collapsed .child, 287 .child.collapsed .children { 288 display: none; 289 } 290 291 .child > .tag-line:first-child .close { 292 display: none; 293 } 294 295 .child.collapsed > .tag-line:first-child .close { 296 display: inline; 297 } 298 299 .child.collapsed > .tag-line ~ .tag-line { 300 display: none; 301 } 302 303 .child.collapsed .close { 304 display: inline; 305 } 306 307 .expandable.collapsed .markup-expand-badge { 308 cursor: pointer; 309 display: inline-block; 310 vertical-align: top; 311 box-sizing: border-box; 312 height: 16px; 313 margin: -1px 0; 314 padding: 3px 2px; 315 } 316 317 .expandable.collapsed .markup-expand-badge::before { 318 /* Display an ellipsis character in collapsed nodes that can be expanded. */ 319 content: ""; 320 background-color: var(--badge-interactive-background-color); 321 background-image: url(chrome://devtools/skin/images/more.svg); 322 background-repeat: no-repeat; 323 background-position: center; 324 background-size: 8px; 325 border: 1px solid var(--badge-interactive-border-color); 326 color: var(--badge-interactive-color); 327 fill: currentColor; 328 display: block; 329 width: 12px; 330 height: 8px; 331 line-height: 8px; 332 border-radius: 3px; 333 -moz-context-properties: fill; 334 } 335 336 .expandable.collapsed .markup-expand-badge:focus::before, 337 .expandable.collapsed .markup-expand-badge:hover::before { 338 background-color: var(--badge-hover-interactive-background-color); 339 color: var(--badge-hover-interactive-color); 340 } 341 342 /* Hide HTML void elements (img, hr, br, …) closing tag when the element is not 343 * expanded (it can be if it has pseudo-elements attached) */ 344 .child.collapsed > .tag-line .void-element .close { 345 display: none; 346 } 347 348 .tag-line .tag-state.overflow-causing-highlighted:not(.theme-selected) { 349 background-color: var(--markup-overflow-causing-background-color); 350 } 351 352 /* Also display a small dot next to the overflow badge with the color of the 353 scroll badge. This makes us not rely solely on color to convey a state change, 354 as well as handle High Contrast Mode where the distinct background isn't visible */ 355 .tag-state.overflow-causing-highlighted ~ .editor .inspector-badge.overflow-badge::before { 356 content: ""; 357 display: inline-block; 358 width: 1ch; 359 aspect-ratio: 1 / 1; 360 margin-inline-end: 4px; 361 border-radius: 50%; 362 background-color: var(--badge-scrollable-active-background-color); 363 /* Use an outline to avoid impacting the layout more */ 364 outline: 1px solid var(--badge-scrollable-active-color); 365 /* Opt out of forced colors so the dot is visible in High Contrast Mode */ 366 forced-color-adjust: none; 367 } 368 369 .closing-bracket { 370 pointer-events: none; 371 } 372 373 .newattr { 374 /* Place the new attr "button" over the ">" char */ 375 width: 1ch; 376 margin-inline-end: -1ch; 377 378 /* Make the button 1 char wide (it's easier to do it with a pseudo element as the element 379 is inline and we don't want to mess the vertical alignment) */ 380 &::before { 381 content: "\00a0" / ""; 382 } 383 384 &:focus-visible { 385 margin-inline: var(--markup-new-attr-focused-margin-inline); 386 background-image: url("chrome://devtools/skin/images/add.svg"); 387 background-repeat: no-repeat; 388 background-size: 90%; 389 background-position: center; 390 -moz-context-properties: fill; 391 fill: var(--theme-icon-color); 392 393 /* When focused, make the button 2 chars wide */ 394 &::before { 395 content: "\00a0\00a0" / ""; 396 } 397 } 398 } 399 400 .attr-value .link { 401 text-decoration: underline; 402 } 403 404 .attr-value button.select-node { 405 display: inline-block; 406 vertical-align: middle; 407 height: 15px; 408 width: 15px; 409 /* small spacing between attribute name and the icon */ 410 margin-inline-start: 2px; 411 /* prevent the icon from impacting node height */ 412 margin-block-start: -2px; 413 padding: 0; 414 border: none; 415 background: url("chrome://devtools/skin/images/open-inspector.svg") no-repeat; 416 fill: var(--theme-icon-color); 417 -moz-context-properties: fill; 418 /* consistenty with the other buttons in the markup view */ 419 cursor: pointer; 420 421 &:is(:hover, :focus) { 422 fill: var(--theme-icon-checked-color); 423 } 424 425 [role="treeitem"][aria-selected="true"] & { 426 fill: var(--theme-selection-color); 427 } 428 } 429 430 .flash-out { 431 transition: 432 background, 433 color 0.5s; 434 } 435 436 .editor { 437 /* Make sure the editor still appears above the tag-state */ 438 position: relative; 439 z-index: 1; 440 } 441 442 .editor.comment:not(.doctype) { 443 color: var(--theme-highlight-green); 444 /* opt-out of forced color so comments gets a distinct color. This is safe as 445 --theme-highlight-green has a High Contrast specific declaration. */ 446 forced-color-adjust: none; 447 } 448 449 .editor.text { 450 display: inline-block; 451 } 452 453 .editor.text pre, 454 .editor.comment pre { 455 font: inherit; 456 457 /* In the Markup view, the background color is set on .theme-selected, which is not 458 an ancestor of those <pre>, so we get backplating which doesn't play well with the 459 selected color. So for those, force the SelectedItem background color */ 460 :root[forced-colors-active] .tag-line[selected] & { 461 background-color: SelectedItem; 462 } 463 } 464 465 /* Only override the color on non High Contrast dark theme so we can keep the inherited 466 colors in HCM */ 467 :root.theme-dark:not([forced-colors-active]) .editor.text pre { 468 color: var(--theme-text-color-strong); 469 } 470 471 .more-nodes { 472 padding-left: 16px; 473 } 474 475 .styleinspector-propertyeditor { 476 vertical-align: top; 477 border: none; 478 479 &.newattr-input { 480 margin-inline: var(--markup-new-attr-focused-margin-inline); 481 /* Apply the same size as the new attr button so we don't shift the layout when dislaying the input */ 482 min-width: var(--markup-new-attr-size); 483 } 484 } 485 486 .reveal-link { 487 cursor: pointer; 488 background: url("chrome://devtools/skin/images/reveal.svg") no-repeat; 489 display: inline-block; 490 width: 16px; 491 height: 8px; 492 493 -moz-context-properties: stroke; 494 stroke: currentColor; 495 } 496 497 /* Draw a circle next to nodes that have a pseudo class lock. 498 Center vertically with the 1.4em line height on .tag-line */ 499 .child.pseudoclass-locked::before { 500 content: ""; 501 background: var(--markup-pseudoclass-disk-color); 502 border-radius: 50%; 503 width: 6px; 504 height: 6px; 505 margin-top: 5px; 506 left: 8px; 507 position: absolute; 508 z-index: 1; 509 } 510 511 .not-displayed { 512 color: var(--markup-hidden-punctuation-color); 513 } 514 515 .not-displayed :is(.attr-name, .attr-value) { 516 color: var(--markup-hidden-attr-color); 517 } 518 519 .not-displayed .tag { 520 color: var(--markup-hidden-tag-color); 521 } 522 523 @layer markup-base { 524 .tag { 525 color: var(--theme-highlight-blue); 526 } 527 .attr-name { 528 color: var(--theme-highlight-red); 529 } 530 .attr-value { 531 color: var(--theme-highlight-purple); 532 } 533 .pseudo { 534 color: var(--theme-highlight-blue); 535 } 536 537 /* In High Contrast Mode, we need to override all the colors so we can properly handle 538 the selected + focused-visible style */ 539 :root[forced-colors-active] :is(.tag, .pseudo) { 540 color: SelectedItem; 541 } 542 543 :root[forced-colors-active] .attr-name { 544 color: CanvasText; 545 } 546 547 :root[forced-colors-active] .attr-value { 548 /* opt-out of forced color so attribute values gets a distinct color. This is safe as 549 --theme-highlight-blue has a High Contrast specific declaration. */ 550 forced-color-adjust: none; 551 color: var(--theme-highlight-blue); 552 } 553 } 554 555 /* Make focusable elements stand out a bit more when they're focused */ 556 .tag-line :is( 557 [editable], 558 /* tag is not always editable (e.g. for `html`, `DOCTYPE`, …), but is always focusable */ 559 .tag 560 ):focus-visible { 561 border-radius: 2px; 562 outline: var(--theme-focus-outline); 563 outline-offset: var(--theme-outline-offset); 564 } 565 566 /* Selected nodes in the tree should have light selected text (unless there's an active 567 inplace editor input). 568 theme-selected doesn't work in this case since the text is a 569 sibling of the class, not a child. */ 570 .tag-line[selected]:not(:has(.styleinspector-propertyeditor:focus)) :is(.editor, .editor.comment, .editor :is(.attr-name, .attr-value, .tag, .pseudo)) { 571 color: var(--theme-selection-color); 572 573 & :is([editable], .tag):focus-visible { 574 /* When an editable item in the markup view is focused, we want to make it stand out 575 Since the node is selected, we have a blue background on the whole node, so we set 576 the default body background, and set the original color we have when the line is 577 not selected. 578 This is done by using revert-layer, so we'll get colors set in <@layer markup-base>, 579 and not the one set in this rule's parent rule. 580 */ 581 color: revert-layer; 582 background-color: var(--theme-body-background); 583 584 outline-offset: 2px; 585 586 /* Better style for attributes spanning multiple lines */ 587 box-decoration-break: clone; 588 mix-blend-mode: lighten; 589 .theme-dark & { 590 mix-blend-mode: darken; 591 } 592 593 /* We also need to take care of items that don't have their color set in <@layer markup-base> */ 594 &:not(.attr-name, .attr-value, .tag, .pseudo) { 595 color: var(--markup-selected-focus-visible-non-highlighted-color); 596 } 597 598 & * { 599 color: revert-layer; 600 } 601 } 602 } 603 604 /* Selected nodes being flashed in the tree should have dark selected text. Here we target 605 nodes with theme-selected text colors and apply a dark, accessible text color for when 606 the yellow flashing background is applied. */ 607 .tag-line[selected] :is(.theme-selected.theme-bg-contrast ~ .editor, .theme-selected ~ .editor .theme-fg-contrast) { 608 color: var(--theme-contrast-color) !important; 609 } 610 611 /* Applicable to the DOCTYPE */ 612 .doctype { 613 font-style: italic; 614 }