1$top-sites-size: $grid-unit; 2$top-sites-border-radius: 4px; 3$top-sites-title-height: 30px; 4$top-sites-vertical-space: 8px; 5$screenshot-size: cover; 6$rich-icon-size: 96px; 7$default-icon-wrapper-size: 42px; 8$default-icon-size: 32px; 9$default-icon-offset: 6px; 10$half-base-gutter: $base-gutter / 2; 11$hover-transition-duration: 150ms; 12 13.top-sites { 14 // Take back the margin from the bottom row of vertical spacing as well as the 15 // extra whitespace below the title text as it's vertically centered. 16 margin-bottom: $section-spacing - ($top-sites-vertical-space + $top-sites-title-height / 3); 17} 18 19.top-sites-list { 20 list-style: none; 21 margin: 0 (-$half-base-gutter); 22 padding: 0; 23 24 // Two columns 25 @media (max-width: $break-point-medium) { 26 > :nth-child(2n+1) { 27 @include context-menu-open-middle; 28 } 29 30 > :nth-child(2n) { 31 @include context-menu-open-left; 32 } 33 } 34 35 // Four columns 36 @media (min-width: $break-point-medium) and (max-width: $break-point-large) { 37 :nth-child(4n) { 38 @include context-menu-open-left; 39 } 40 } 41 @media (min-width: $break-point-medium) and (max-width: $break-point-medium + $card-width) { 42 :nth-child(4n+3) { 43 @include context-menu-open-left; 44 } 45 } 46 47 // Six columns 48 @media (min-width: $break-point-large) and (max-width: $break-point-large + 2 * $card-width) { 49 :nth-child(6n) { 50 @include context-menu-open-left; 51 } 52 } 53 @media (min-width: $break-point-large) and (max-width: $break-point-large + $card-width) { 54 :nth-child(6n+5) { 55 @include context-menu-open-left; 56 } 57 } 58 59 // Eight columns 60 @media (min-width: $break-point-widest) and (max-width: $break-point-widest + 2 * $card-width) { 61 :nth-child(8n) { 62 @include context-menu-open-left; 63 } 64 } 65 @media (min-width: $break-point-widest) and (max-width: $break-point-widest + $card-width) { 66 :nth-child(8n+7) { 67 @include context-menu-open-left; 68 } 69 } 70 71 .hide-for-narrow { 72 display: none; 73 } 74 75 @media (min-width: $break-point-medium) { 76 .hide-for-narrow { 77 display: inline-block; 78 } 79 } 80 81 @media (min-width: $break-point-large) { 82 .hide-for-narrow { 83 display: none; 84 } 85 } 86 87 @media (min-width: $break-point-widest) { 88 .hide-for-narrow { 89 display: inline-block; 90 } 91 } 92 93 li { 94 margin: 0 0 $top-sites-vertical-space; 95 } 96 97 &:not(.dnd-active) { 98 .top-site-outer:-moz-any(.active, :focus, :hover) { 99 .tile { 100 @include fade-in; 101 } 102 103 @include context-menu-button-hover; 104 } 105 } 106} 107 108// container for drop zone 109.top-site-outer { 110 padding: 0 $half-base-gutter; 111 display: inline-block; 112 113 // container for context menu 114 .top-site-inner { 115 position: relative; 116 117 > a { 118 color: inherit; 119 display: block; 120 outline: none; 121 122 &:-moz-any(.active, :focus) { 123 .tile { 124 @include fade-in; 125 } 126 } 127 } 128 } 129 130 @include context-menu-button; 131 132 .tile { // sass-lint:disable-block property-sort-order 133 border-radius: $top-sites-border-radius; 134 box-shadow: inset $inner-box-shadow, var(--newtab-card-shadow); 135 cursor: pointer; 136 height: $top-sites-size; 137 position: relative; 138 width: $top-sites-size; 139 140 // For letter fallback 141 align-items: center; 142 color: var(--newtab-text-secondary-color); 143 display: flex; 144 font-size: 32px; 145 font-weight: 200; 146 justify-content: center; 147 text-transform: uppercase; // sass-lint:disable-line no-disallowed-properties 148 transition: box-shadow $hover-transition-duration; 149 150 &::before { 151 content: attr(data-fallback); 152 } 153 } 154 155 .screenshot { 156 background-color: $white; 157 background-position: top left; 158 background-size: $screenshot-size; 159 border-radius: $top-sites-border-radius; 160 box-shadow: inset $inner-box-shadow; 161 height: 100%; 162 left: 0; 163 opacity: 0; 164 position: absolute; 165 top: 0; 166 transition: opacity 1s; 167 width: 100%; 168 169 &.active { 170 opacity: 1; 171 } 172 } 173 174 // Some common styles for all icons (rich and default) in top sites 175 .top-site-icon { 176 background-color: var(--newtab-topsites-background-color); 177 background-position: center center; 178 background-repeat: no-repeat; 179 border-radius: $top-sites-border-radius; 180 box-shadow: var(--newtab-topsites-icon-shadow); 181 position: absolute; 182 } 183 184 .rich-icon { 185 background-size: cover; 186 height: 100%; 187 inset-inline-start: 0; 188 top: 0; 189 width: 100%; 190 } 191 192 .default-icon, 193 .search-topsite { 194 background-size: $default-icon-size; 195 bottom: -$default-icon-offset; 196 height: $default-icon-wrapper-size; 197 inset-inline-end: -$default-icon-offset; 198 width: $default-icon-wrapper-size; 199 200 // for corner letter fallback 201 align-items: center; 202 display: flex; 203 font-size: 20px; 204 justify-content: center; 205 206 &[data-fallback]::before { 207 content: attr(data-fallback); 208 } 209 } 210 211 .search-topsite { 212 background-image: url('#{$image-path}glyph-search-16.svg'); 213 background-size: 26px; 214 background-color: $blue-60; 215 border-radius: $default-icon-wrapper-size; 216 -moz-context-properties: fill; 217 fill: $white; 218 box-shadow: var(--newtab-card-shadow); 219 transition-duration: $hover-transition-duration; 220 transition-property: background-size, bottom, inset-inline-end, height, width; 221 } 222 223 &:hover .search-topsite { 224 $hover-icon-wrapper-size: $default-icon-wrapper-size + 4; 225 $hover-icon-offset: -$default-icon-offset - 3; 226 227 background-size: 28px; 228 border-radius: $hover-icon-wrapper-size; 229 bottom: $hover-icon-offset; 230 height: $hover-icon-wrapper-size; 231 inset-inline-end: $hover-icon-offset; 232 width: $hover-icon-wrapper-size; 233 } 234 235 // We want all search shortcuts to have a white background in case they have transparency. 236 &.search-shortcut { 237 .rich-icon { 238 background-color: $white; 239 } 240 } 241 242 .title { 243 color: var(--newtab-topsites-label-color); 244 font: message-box; 245 height: $top-sites-title-height; 246 line-height: $top-sites-title-height; 247 text-align: center; 248 width: $top-sites-size; 249 position: relative; 250 251 .icon { 252 fill: var(--newtab-icon-tertiary-color); 253 inset-inline-start: 0; 254 position: absolute; 255 top: 10px; 256 } 257 258 span { 259 height: $top-sites-title-height; 260 display: block; 261 overflow: hidden; 262 text-overflow: ellipsis; 263 white-space: nowrap; 264 } 265 266 &.pinned { 267 span { 268 padding: 0 13px; 269 } 270 } 271 } 272 273 .edit-button { 274 background-image: url('#{$image-path}glyph-edit-16.svg'); 275 } 276 277 &.placeholder { 278 .tile { 279 box-shadow: inset $inner-box-shadow; 280 } 281 282 .screenshot { 283 display: none; 284 } 285 } 286 287 &.dragged { 288 .tile { 289 background: $grey-20; 290 box-shadow: none; 291 292 *, 293 &::before { 294 display: none; 295 } 296 } 297 298 .title { 299 visibility: hidden; 300 } 301 } 302} 303 304.edit-topsites-wrapper { 305 .modal { 306 box-shadow: $shadow-secondary; 307 left: 0; 308 margin: 0 auto; 309 max-height: calc(100% - 40px); 310 position: fixed; 311 right: 0; 312 top: 40px; 313 width: $wrapper-default-width; 314 315 @media (min-width: $break-point-medium) { 316 width: $wrapper-max-width-medium; 317 } 318 319 @media (min-width: $break-point-large) { 320 width: $wrapper-max-width-large; 321 } 322 } 323} 324 325.topsite-form { 326 $form-width: 300px; 327 $form-spacing: 32px; 328 329 .section-title { 330 font-size: 16px; 331 margin: 0 0 16px; 332 } 333 334 .form-input-container { 335 max-width: $form-width + 3 * $form-spacing + $rich-icon-size; 336 margin: 0 auto; 337 padding: $form-spacing; 338 339 .top-site-outer { 340 pointer-events: none; 341 } 342 } 343 344 .search-shortcuts-container { 345 max-width: 700px; 346 margin: 0 auto; 347 padding: $form-spacing; 348 349 > div { 350 margin-inline-end: -39px; 351 } 352 353 .top-site-outer { 354 margin-inline-start: 0; 355 margin-inline-end: 39px; 356 } 357 } 358 359 .top-site-outer { 360 padding: 0; 361 margin: 24px 0 0; 362 margin-inline-start: $form-spacing; 363 } 364 365 .fields-and-preview { 366 display: flex; 367 } 368 369 label { 370 font-size: $section-title-font-size; 371 } 372 373 .form-wrapper { 374 width: 100%; 375 376 .field { 377 position: relative; 378 379 .icon-clear-input { 380 position: absolute; 381 transform: translateY(-50%); 382 top: 50%; 383 inset-inline-end: 8px; 384 } 385 } 386 387 .url { 388 input:dir(ltr) { 389 padding-right: 32px; 390 } 391 392 input:dir(rtl) { 393 padding-left: 32px; 394 395 &:not(:placeholder-shown) { 396 direction: ltr; 397 text-align: right; 398 } 399 } 400 } 401 402 .enable-custom-image-input { 403 display: inline-block; 404 font-size: 13px; 405 margin-top: 4px; 406 cursor: pointer; 407 } 408 409 .custom-image-input-container { 410 margin-top: 4px; 411 412 .loading-container { 413 width: 16px; 414 height: 16px; 415 overflow: hidden; 416 position: absolute; 417 transform: translateY(-50%); 418 top: 50%; 419 inset-inline-end: 8px; 420 } 421 422 // This animation is derived from Firefox's tab loading animation 423 // See https://searchfox.org/mozilla-central/rev/b29daa46443b30612415c35be0a3c9c13b9dc5f6/browser/themes/shared/tabs.inc.css#208-216 424 .loading-animation { 425 @keyframes tab-throbber-animation { 426 100% { transform: translateX(-960px); } 427 } 428 429 @keyframes tab-throbber-animation-rtl { 430 100% { transform: translateX(960px); } 431 } 432 433 width: 960px; 434 height: 16px; 435 -moz-context-properties: fill; 436 fill: $blue-50; 437 background-image: url('chrome://browser/skin/tabbrowser/loading.svg'); 438 animation: tab-throbber-animation 1.05s steps(60) infinite; 439 440 &:dir(rtl) { 441 animation-name: tab-throbber-animation-rtl; 442 } 443 } 444 } 445 446 input { 447 &[type='text'] { 448 background-color: var(--newtab-textbox-background-color); 449 border: $input-border; 450 margin: 8px 0; 451 padding: 0 8px; 452 height: 32px; 453 width: 100%; 454 font-size: 15px; 455 456 &:focus { 457 border: $input-border-active; 458 box-shadow: var(--newtab-textbox-focus-boxshadow); 459 } 460 461 &[disabled] { 462 border: $input-border; 463 box-shadow: none; 464 opacity: 0.4; 465 } 466 } 467 } 468 469 .invalid { 470 input { 471 &[type='text'] { 472 border: $input-error-border; 473 box-shadow: $input-error-boxshadow; 474 } 475 } 476 } 477 478 .error-tooltip { 479 animation: fade-up-tt 450ms; 480 background: $red-60; 481 border-radius: 2px; 482 color: $white; 483 inset-inline-start: 3px; 484 padding: 5px 12px; 485 position: absolute; 486 top: 44px; 487 z-index: 1; 488 489 // tooltip caret 490 &::before { 491 background: $red-60; 492 bottom: -8px; 493 content: '.'; 494 height: 16px; 495 inset-inline-start: 12px; 496 position: absolute; 497 text-indent: -999px; 498 top: -7px; 499 transform: rotate(45deg); 500 white-space: nowrap; 501 width: 16px; 502 z-index: -1; 503 } 504 } 505 } 506 507 .actions { 508 justify-content: flex-end; 509 510 button { 511 margin-inline-start: 10px; 512 margin-inline-end: 0; 513 } 514 } 515 516 @media (max-width: $break-point-medium) { 517 .fields-and-preview { 518 flex-direction: column; 519 520 .top-site-outer { 521 margin-inline-start: 0; 522 } 523 } 524 } 525 526 // prevent text selection of keyword label when clicking to select 527 .title { 528 -moz-user-select: none; 529 } 530 531 // CSS styled checkbox 532 [type='checkbox']:not(:checked), 533 [type='checkbox']:checked { 534 inset-inline-start: -9999px; 535 position: absolute; 536 } 537 538 [type='checkbox']:not(:checked) + label, 539 [type='checkbox']:checked + label { 540 cursor: pointer; 541 display: block; 542 position: relative; 543 } 544 545 $checkbox-offset: -8px; 546 547 [type='checkbox']:not(:checked) + label::before, 548 [type='checkbox']:checked + label::before { 549 background: var(--newtab-background-color); 550 border: $input-border; 551 border-radius: $border-radius; 552 content: ''; 553 height: 21px; 554 left: $checkbox-offset; 555 position: absolute; 556 top: $checkbox-offset; 557 width: 21px; 558 z-index: 1; 559 560 [dir='rtl'] & { 561 left: auto; 562 right: $checkbox-offset; 563 } 564 } 565 566 // checkmark 567 [type='checkbox']:not(:checked) + label::after, 568 [type='checkbox']:checked + label::after { 569 background: url('chrome://global/skin/icons/check.svg') no-repeat center center; // sass-lint:disable-line no-url-domains 570 content: ''; 571 height: 21px; 572 left: $checkbox-offset; 573 position: absolute; 574 top: $checkbox-offset; 575 width: 21px; 576 -moz-context-properties: fill; 577 fill: var(--newtab-link-primary-color); 578 z-index: 2; 579 580 [dir='rtl'] & { 581 left: auto; 582 right: $checkbox-offset; 583 } 584 } 585 586 // when selected, highlight the tile 587 [type='checkbox']:checked + label { 588 .tile { 589 box-shadow: 0 0 0 2px var(--newtab-link-primary-color); 590 } 591 } 592 593 // checkmark changes 594 [type='checkbox']:not(:checked) + label::after { 595 opacity: 0; 596 } 597 598 [type='checkbox']:checked + label::after { 599 opacity: 1; 600 } 601 602 // accessibility 603 [type='checkbox']:checked:focus + label::before, 604 [type='checkbox']:not(:checked):focus + label::before { 605 border: 1px dotted var(--newtab-link-primary-color); 606 } 607} 608 609//used for tooltips below form element 610@keyframes fade-up-tt { 611 0% { 612 opacity: 0; 613 transform: translateY(15px); 614 } 615 616 100% { 617 opacity: 1; 618 transform: translateY(0); 619 } 620} 621