_TopSites.scss (19360B)
1 @use 'sass:math'; 2 3 /* stylelint-disable max-nesting-depth */ 4 5 $top-sites-size: $grid-unit-small; 6 $rich-icon-size: 96px; 7 $default-icon-wrapper-size: 40px; 8 $default-icon-size: 40px; 9 $default-icon-offset: 6px; 10 $half-base-gutter: math.div($base-gutter, 2); 11 $hover-transition-duration: 150ms; 12 $letter-fallback-color: $white; 13 $calculated-max-width-medium: $break-point-medium + $card-width; 14 $calculated-max-width-large: $break-point-large + $card-width; 15 $calculated-max-width-twice-large: $break-point-large + 2 * $card-width; 16 $calculated-max-width-widest: $break-point-widest + $card-width; 17 $calculated-max-width-twice-widest: $break-point-widest + 2 * $card-width; 18 19 .top-sites-list { 20 &:not(.dnd-active) { 21 .top-site-outer:is(.active, :focus, :hover) { 22 @include wallpaper-contrast-fix; 23 24 // Ideally this would just match button --button-background-color-hover. 25 // However, --button-background-color-hover uses currentColor. 26 // We cannot change the shortcut's color to match, 27 // so we just use --button-text-color-hover directly. 28 background: color-mix(in srgb, var(--button-text-color-hover) 14%, transparent); 29 30 .tile { 31 box-shadow: 0 2px 8px 0 var(--newtab-section-card-box-shadow-color); 32 } 33 34 .icon-pin-small { 35 opacity: 1; 36 } 37 38 .lightWallpaper &, 39 .darkWallpaper & { 40 background: color-mix(in srgb, var(--button-text-color-hover) 14%, transparent); 41 42 @media (prefers-contrast) { 43 background-color: var(--background-color-box); 44 } 45 } 46 } 47 } 48 49 list-style: none; 50 margin: 0 calc(var(--space-large) * -1); 51 padding: 0; 52 display: grid; 53 grid-template-columns: repeat(3, auto); 54 justify-content: center; // Center shortcuts when fewer than max number of sites per row 55 row-gap: var(--space-small); 56 57 @media (min-width: $break-point-layout-variant) { 58 grid-template-columns: repeat(6, auto); 59 } 60 61 @media (min-width: $break-point-widest) { 62 grid-template-columns: repeat(8, auto); 63 } 64 65 a { 66 text-decoration: none; 67 } 68 69 // Two columns 70 @media (max-width: $break-point-medium) { 71 > :nth-child(2n+1) { 72 @include context-menu-open-middle; 73 } 74 75 > :nth-child(2n) { 76 @include context-menu-open-left; 77 } 78 } 79 80 // Four columns 81 @media (min-width: $break-point-medium) and (max-width: $break-point-large) { 82 :nth-child(4n) { 83 @include context-menu-open-left; 84 } 85 } 86 87 @media (min-width: $break-point-medium) and (max-width: $calculated-max-width-medium) { 88 :nth-child(4n+3) { 89 @include context-menu-open-left; 90 } 91 } 92 93 // Six columns 94 @media (min-width: $break-point-large) and (max-width: $calculated-max-width-twice-large) { 95 :nth-child(6n) { 96 @include context-menu-open-left; 97 } 98 } 99 100 @media (min-width: $break-point-large) and (max-width: $calculated-max-width-large) { 101 :nth-child(6n+5) { 102 @include context-menu-open-left; 103 } 104 } 105 106 // Eight columns 107 @media (min-width: $break-point-widest) and (max-width: $calculated-max-width-twice-widest) { 108 :nth-child(8n) { 109 @include context-menu-open-left; 110 } 111 } 112 113 @media (min-width: $break-point-widest) and (max-width: $calculated-max-width-widest) { 114 :nth-child(8n+7) { 115 @include context-menu-open-left; 116 } 117 } 118 119 .hide-for-narrow { 120 display: none; 121 } 122 123 @media (min-width: $break-point-medium) { 124 .hide-for-narrow { 125 display: none; 126 } 127 } 128 129 @media (min-width: $break-point-large) { 130 .hide-for-narrow { 131 display: none; 132 } 133 } 134 135 @media (min-width: $break-point-widest) { 136 .hide-for-narrow { 137 display: inline-block; 138 } 139 } 140 } 141 142 .discovery-stream.ds-layout.ds-layout-topsites { 143 display: flex; 144 justify-content: center; 145 146 .top-sites-list { 147 padding-block-start: 0; 148 } 149 } 150 151 // container for drop zone 152 .top-site-outer { 153 width: 120px; 154 // Compact layout spacing migrated from .thumbs-ui-compact 155 margin-block-end: var(--space-medium); 156 border-radius: var(--border-radius-large); 157 display: inline-block; 158 159 .top-site-inner { 160 position: relative; 161 162 > a { 163 padding: var(--space-large) var(--space-large) var(--space-xsmall); 164 color: inherit; 165 display: block; 166 outline: none; 167 } 168 } 169 170 &:hover, &:focus { 171 .context-menu-button { 172 opacity: 1; 173 transition: opacity 200ms; 174 175 @include wallpaper-contrast-fix; 176 } 177 178 .tile { 179 background-color: var(--newtab-background-color-secondary); 180 } 181 182 .icon-pin-small { 183 opacity: 1; 184 } 185 } 186 187 &:not(:hover, :active, .active) { 188 @include wallpaper-contrast-fix; 189 } 190 191 &.active .context-menu-button { 192 opacity: 1; 193 background-color: var(--newtab-button-active-background); 194 } 195 196 .tile { 197 background: var(--newtab-background-card); 198 border-radius: var(--border-radius-large); 199 box-shadow: $shadow-card; 200 height: calc(var(--size-item-large) * 2); 201 width: calc(var(--size-item-large) * 2); 202 margin: 0 auto; 203 position: relative; 204 display: flex; 205 align-items: center; 206 justify-content: center; 207 text-transform: uppercase; 208 font-size: var(--font-size-xxlarge); 209 color: var(--newtab-contextual-text-secondary-color); 210 cursor: pointer; 211 212 .icon-wrapper { 213 border-radius: var(--border-radius-small); 214 width: $default-icon-wrapper-size; 215 height: $default-icon-wrapper-size; 216 display: flex; 217 align-items: center; 218 justify-content: center; 219 overflow: hidden; 220 position: relative; 221 222 &.letter-fallback { 223 border-radius: var(--border-radius-circle); 224 225 &::before { 226 content: attr(data-fallback); 227 font-size: var(--font-size-xlarge); 228 transform: none; 229 position: static; 230 } 231 } 232 } 233 234 .top-site-icon { 235 background-color: transparent; 236 border-radius: var(--border-radius-medium); 237 background-position: center; 238 background-repeat: no-repeat; 239 position: absolute; 240 } 241 } 242 243 .context-menu-button { 244 background-image: url('chrome://global/skin/icons/more.svg'); 245 border: 0; 246 border-radius: var(--border-radius-small); 247 cursor: pointer; 248 fill: var(--newtab-button-text); 249 -moz-context-properties: fill; 250 height: var(--size-item-medium); 251 width: var(--size-item-medium); 252 inset-inline-end: 0; 253 inset-block-start: var(--space-medium); 254 position: absolute; 255 opacity: 0; 256 257 &:hover { 258 background-color: var(--newtab-button-hover-background); 259 260 &:active { 261 background-color: var(--newtab-button-active-background); 262 } 263 } 264 265 &:focus-visible { 266 background-color: var(--newtab-button-focus-background); 267 outline: var(--focus-outline); // Backup for when wallpaper is not set 268 opacity: 1; 269 270 .lightWallpaper &, 271 .darkWallpaper & { 272 &::after { 273 content: ''; 274 position: absolute; 275 inset: 0; 276 border-radius: var(--border-radius-small); 277 outline: var(--focus-outline); 278 color-scheme: initial; // Override wallpaper-contrast-fix for focus outline color 279 } 280 } 281 } 282 } 283 284 .context-menu { 285 inset-block-start: calc(var(--space-large) + var(--space-xlarge)); 286 } 287 288 .icon-pin-small { 289 inset-block-start: var(--space-small); 290 inset-inline-start: var(--space-small); 291 opacity: 0; 292 position: absolute; 293 } 294 295 .top-site-button { 296 padding: var(--space-large) var(--space-large) var(--space-small); 297 298 &:focus + div .context-menu-button { 299 opacity: 1; 300 } 301 302 &:focus .tile { 303 .lightWallpaper &, 304 .darkWallpaper & { 305 outline: var(--focus-outline); 306 color-scheme: initial; 307 } 308 } 309 } 310 311 .title { 312 color: var(--newtab-contextual-text-primary-color); 313 padding-block-start: var(--space-small); 314 font: caption; 315 text-align: center; 316 position: relative; 317 318 .icon { 319 margin-inline-end: var(--space-xxsmall); 320 fill: currentColor; 321 } 322 323 .sponsored-label { 324 color: var(--newtab-contextual-text-secondary-color); 325 font-size: var(--font-size-xsmall); 326 } 327 328 &:not(.sponsored) .sponsored-label { 329 display: none; 330 } 331 332 .search-topsite { 333 margin-inline-end: var(--space-xxsmall); 334 fill: currentColor; 335 background-size: var(--icon-size-xsmall); 336 height: var(--icon-size-xsmall); 337 width: var(--icon-size-xsmall); 338 background-position: center; 339 background-repeat: no-repeat; 340 background-color: transparent; 341 position: static; 342 display: inline-block; 343 color: var(--icon-color); 344 box-shadow: none; 345 } 346 } 347 348 .rich-icon { 349 background-size: cover; 350 height: 100%; 351 width: 100%; 352 position: absolute; 353 inset-inline-start: 0; 354 inset-block-start: 0; 355 } 356 357 .default-icon, 358 .search-topsite { 359 background-size: $default-icon-size; 360 height: $default-icon-wrapper-size; 361 width: $default-icon-wrapper-size; 362 align-items: center; 363 display: flex; 364 justify-content: center; 365 font-size: var(--font-size-xlarge); 366 367 &[data-fallback]::before { 368 content: attr(data-fallback); 369 } 370 } 371 372 .search-topsite { 373 background-image: url('chrome://global/skin/icons/search-glass.svg'); 374 background-size: 16px; 375 background-color: var(--newtab-primary-action-background); 376 border-radius: var(--border-radius-circle); 377 -moz-context-properties: fill; 378 fill: var(--newtab-primary-element-text-color); 379 box-shadow: $shadow-card; 380 transition: background-size $hover-transition-duration, 381 bottom $hover-transition-duration, 382 inset-inline-end $hover-transition-duration, 383 height $hover-transition-duration, 384 width $hover-transition-duration; 385 height: 32px; 386 width: 32px; 387 // Bug 1967304 - $variable 388 inset-block-end: -$default-icon-offset; // stylelint-disable-line declaration-property-value-disallowed-list 389 inset-inline-end: -$default-icon-offset; // stylelint-disable-line declaration-property-value-disallowed-list 390 } 391 392 &.placeholder { 393 .tile { 394 box-shadow: $shadow-card; 395 cursor: default; 396 } 397 } 398 399 &.add-button { 400 .tile { 401 background-color: var(--button-background-color); 402 403 .icon-wrapper { 404 background-image: url('chrome://global/skin/icons/plus-20.svg'); 405 background-size: cover; 406 background-repeat: no-repeat; 407 height: 20px; 408 width: 20px; 409 fill: var(--icon-color); 410 -moz-context-properties: fill; 411 } 412 } 413 414 &:hover { 415 .tile { 416 background-color: var(--newtab-background-color-secondary); 417 color-scheme: initial; 418 } 419 } 420 } 421 422 &.search-shortcut { 423 .rich-icon { 424 background-color: $white; 425 } 426 } 427 428 .edit-button { 429 background-image: url('chrome://global/skin/icons/edit.svg'); 430 } 431 432 &.dragged { 433 .tile { 434 *, 435 &::before { 436 display: none; 437 } 438 } 439 440 .title { 441 visibility: hidden; 442 } 443 } 444 } 445 446 // Preserve shortcuts-refresh variant from compact thumbs UI 447 .shortcuts-refresh { 448 .top-site-outer { 449 margin-block-end: 0; 450 } 451 } 452 453 .edit-topsites-wrapper { 454 .top-site-inner > .top-site-button > .tile { 455 border: 1px solid var(--border-color); 456 } 457 458 .modal { 459 box-shadow: $shadow-secondary; 460 inset-inline-start: 0; 461 margin: 0 auto; 462 max-height: calc(100% - 40px); 463 position: fixed; 464 inset-inline-end: 0; 465 inset-block-start: var(--space-xxlarge); 466 width: $wrapper-default-width; 467 468 @media (min-width: $break-point-medium) { 469 width: $wrapper-max-width-medium; 470 } 471 472 @media (min-width: $break-point-large) { 473 width: $wrapper-max-width-large; 474 } 475 } 476 } 477 478 .topsite-form { 479 $form-width: 300px; 480 $form-spacing: 32px; 481 482 .section-title { 483 font-size: inherit; 484 margin: 0 0 var(--space-large); 485 } 486 487 .form-input-container { 488 max-width: $form-width + 3 * $form-spacing + $rich-icon-size; 489 margin: 0 auto; 490 padding: var(--space-xxlarge); 491 492 .top-site-outer { 493 pointer-events: none; 494 } 495 } 496 497 .search-shortcuts-container { 498 max-width: 700px; 499 margin: 0 auto; 500 padding: var(--space-xxlarge); 501 502 > div { 503 margin-inline-end: calc(var(--space-xxlarge) * -1); 504 } 505 506 .top-site-outer { 507 margin-inline-start: 0; 508 margin-inline-end: var(--space-xxlarge); 509 } 510 } 511 512 .top-site-outer { 513 padding: 0; 514 margin: var(--space-xlarge) 0 0; 515 margin-inline-start: var(--space-xxlarge); 516 } 517 518 .fields-and-preview { 519 display: flex; 520 } 521 522 label { 523 font-size: $section-title-font-size; 524 } 525 526 .form-wrapper { 527 width: 100%; 528 529 .field { 530 position: relative; 531 532 .icon-clear-input { 533 position: absolute; 534 transform: translateY(-50%); 535 inset-block-start: 50%; 536 inset-inline-end: var(--space-small); 537 } 538 } 539 540 .url { 541 input:dir(ltr) { 542 padding-inline-end: var(--space-xxlarge); 543 } 544 545 input:dir(rtl) { 546 padding-inline-start: var(--space-xxlarge); 547 548 &:not(:placeholder-shown) { 549 direction: ltr; 550 text-align: end; 551 } 552 } 553 } 554 555 .enable-custom-image-input { 556 display: inline-block; 557 font-size: var(--font-size-small); 558 margin-block-start: var(--space-xsmall); 559 cursor: pointer; 560 } 561 562 .custom-image-input-container { 563 margin-block-start: var(--space-xsmall); 564 565 .loading-container { 566 width: 16px; 567 height: 16px; 568 overflow: hidden; 569 position: absolute; 570 transform: translateY(-50%); 571 inset-block-start: 50%; 572 inset-inline-end: var(--space-small); 573 } 574 575 // This animation is derived from Firefox's tab loading animation 576 // See https://searchfox.org/mozilla-central/rev/b29daa46443b30612415c35be0a3c9c13b9dc5f6/browser/themes/shared/tabs.inc.css#208-216 577 .loading-animation { 578 @keyframes tab-throbber-animation { 579 100% { transform: translateX(-960px); } 580 } 581 582 @keyframes tab-throbber-animation-rtl { 583 100% { transform: translateX(960px); } 584 } 585 586 width: 960px; 587 height: 16px; 588 -moz-context-properties: fill; 589 fill: var(--newtab-primary-action-background); 590 background-image: url('chrome://browser/skin/tabbrowser/loading.svg'); 591 animation: tab-throbber-animation 1.05s steps(60) infinite; 592 593 &:dir(rtl) { 594 animation-name: tab-throbber-animation-rtl; 595 } 596 } 597 } 598 599 input { 600 &[type='text'] { 601 background-color: var(--newtab-background-color-secondary); 602 border: 1px solid var(--border-color-interactive); 603 margin: var(--space-small) 0; 604 padding: 0 var(--space-small); 605 height: 32px; 606 width: 100%; 607 font-size: inherit; 608 609 &[disabled] { 610 border: 1px solid var(--border-color-interactive-disabled); 611 box-shadow: none; 612 opacity: 0.4; 613 } 614 } 615 } 616 617 .invalid { 618 input { 619 &[type='text'] { 620 border: 1px solid var(--outline-color-error); 621 box-shadow: $input-error-boxshadow; 622 } 623 } 624 } 625 626 .error-tooltip { 627 animation: fade-up-tt 450ms; 628 background: var(--newtab-status-error); 629 border-radius: var(--border-radius-small); 630 color: $white; 631 inset-inline-start: var(--space-xxsmall); 632 padding: var(--space-xsmall) var(--space-medium); 633 position: absolute; 634 inset-block-start: var(--space-xxlarge); 635 z-index: 1; 636 637 // tooltip caret 638 &::before { 639 background: var(--newtab-status-error); 640 inset-block-end: calc(var(--space-small) * -1); 641 content: '.'; 642 height: 16px; 643 inset-inline-start: var(--space-medium); 644 position: absolute; 645 text-indent: -999px; 646 inset-block-start: calc(var(--space-small) * -1); 647 transform: rotate(45deg); 648 white-space: nowrap; 649 width: 16px; 650 z-index: -1; 651 } 652 } 653 } 654 655 .actions { 656 justify-content: flex-end; 657 658 button { 659 margin-inline-start: var(--space-small); 660 margin-inline-end: 0; 661 } 662 } 663 664 @media (max-width: $break-point-medium) { 665 .fields-and-preview { 666 flex-direction: column; 667 668 .top-site-outer { 669 margin-inline-start: 0; 670 } 671 } 672 } 673 674 // prevent text selection of keyword label when clicking to select 675 .title { 676 user-select: none; 677 } 678 679 // CSS styled checkbox 680 [type='checkbox']:not(:checked), 681 [type='checkbox']:checked { 682 inset-inline-start: -9999px; // stylelint-disable-line declaration-property-value-disallowed-list 683 position: absolute; 684 } 685 686 [type='checkbox']:not(:checked) + label, 687 [type='checkbox']:checked + label { 688 cursor: pointer; 689 display: block; 690 position: relative; 691 } 692 693 $checkbox-offset: calc(var(--space-small) * -1); 694 695 [type='checkbox']:not(:checked) + label::before, 696 [type='checkbox']:checked + label::before { 697 background: var(--newtab-background-color); 698 border: 1px solid var(--border-color); 699 border-radius: var(--border-radius-small); 700 content: ''; 701 height: 21px; 702 inset-inline-start: calc(var(--space-small) * -1); 703 position: absolute; 704 inset-block-start: calc(var(--space-small) * -1); 705 width: 21px; 706 z-index: 1; 707 708 [dir='rtl'] & { 709 inset-inline-start: auto; 710 inset-inline-end: calc(var(--space-small) * -1); 711 } 712 } 713 714 // checkmark 715 [type='checkbox']:not(:checked) + label::after, 716 [type='checkbox']:checked + label::after { 717 background: url('chrome://global/skin/icons/check.svg') no-repeat center center; 718 content: ''; 719 height: 21px; 720 inset-inline-start: calc(var(--space-small) * -1); 721 position: absolute; 722 inset-block-start: calc(var(--space-small) * -1); 723 width: 21px; 724 -moz-context-properties: fill; 725 fill: var(--newtab-primary-action-background); 726 z-index: 2; 727 728 [dir='rtl'] & { 729 inset-inline-start: auto; 730 inset-inline-end: calc(var(--space-small) * -1); 731 } 732 } 733 734 // when selected, highlight the tile 735 [type='checkbox']:checked + label { 736 .tile { 737 box-shadow: $shadow-focus; 738 } 739 } 740 741 // checkmark changes 742 [type='checkbox']:not(:checked) + label::after { 743 opacity: 0; 744 } 745 746 [type='checkbox']:checked + label::after { 747 opacity: 1; 748 } 749 750 // accessibility 751 [type='checkbox']:checked:focus + label::before, 752 [type='checkbox']:not(:checked):focus + label::before { 753 border: 1px dotted var(--newtab-primary-action-background); 754 } 755 } 756 757 .top-sites-list, 758 .fields-and-preview { 759 .top-site-outer { 760 .top-site-button { 761 display: flex; 762 flex-direction: column; 763 justify-content: center; 764 align-items: center; 765 } 766 767 .title { 768 .title-label { 769 display: block; 770 overflow: hidden; 771 text-overflow: ellipsis; 772 -webkit-line-clamp: 2; 773 white-space: wrap; 774 word-break: break-word; 775 min-height: 2lh; 776 width: 100px; 777 padding: 0 var(--space-xsmall); 778 } 779 780 &.sponsored .title-label { 781 -webkit-line-clamp: 1; 782 min-height: 1lh; 783 } 784 } 785 } 786 } 787 788 // used for tooltips below form element 789 @keyframes fade-up-tt { 790 0% { 791 opacity: 0; 792 transform: translateY(15px); 793 } 794 795 100% { 796 opacity: 1; 797 transform: translateY(0); 798 } 799 } 800 801 // used for TopSites impression wrapper 802 .topsite-impression-observer { 803 position: absolute; 804 inset-block-start: 0; 805 width: 100%; 806 height: 100%; 807 pointer-events: none; 808 }