Source code

Revision control

Copy as Markdown

Other Tools

@use 'sass:math';
/* stylelint-disable max-nesting-depth */
$top-sites-size: $grid-unit-small;
$top-sites-border-radius: 8px;
$top-sites-icon-border-radius: 4px;
$rich-icon-size: 96px;
$default-icon-wrapper-size: 32px;
$default-icon-size: 32px;
$default-icon-offset: 6px;
$half-base-gutter: math.div($base-gutter, 2);
$hover-transition-duration: 150ms;
$letter-fallback-color: $white;
.top-sites-list {
list-style: none;
margin: 0 (-$half-base-gutter);
padding: 0;
a {
text-decoration: none;
}
&:not(.dnd-active) {
.top-site-outer:is(.active, :focus, :hover) {
background: var(--newtab-element-hover-color);
}
}
// Two columns
@media (max-width: $break-point-medium) {
> :nth-child(2n+1) {
@include context-menu-open-middle;
}
> :nth-child(2n) {
@include context-menu-open-left;
}
}
// Four columns
@media (min-width: $break-point-medium) and (max-width: $break-point-large) {
:nth-child(4n) {
@include context-menu-open-left;
}
}
@media (min-width: $break-point-medium) and (max-width: $break-point-medium + $card-width) {
:nth-child(4n+3) {
@include context-menu-open-left;
}
}
// Six columns
@media (min-width: $break-point-large) and (max-width: $break-point-large + 2 * $card-width) {
:nth-child(6n) {
@include context-menu-open-left;
}
}
@media (min-width: $break-point-large) and (max-width: $break-point-large + $card-width) {
:nth-child(6n+5) {
@include context-menu-open-left;
}
}
// Eight columns
@media (min-width: $break-point-widest) and (max-width: $break-point-widest + 2 * $card-width) {
:nth-child(8n) {
@include context-menu-open-left;
}
}
@media (min-width: $break-point-widest) and (max-width: $break-point-widest + $card-width) {
:nth-child(8n+7) {
@include context-menu-open-left;
}
}
.hide-for-narrow {
display: none;
}
@media (min-width: $break-point-medium) {
.hide-for-narrow {
display: inline-block;
}
}
@media (min-width: $break-point-large) {
.hide-for-narrow {
display: none;
}
}
@media (min-width: $break-point-widest) {
.hide-for-narrow {
display: inline-block;
}
}
}
// container for drop zone
.top-site-outer {
width: 120px;
border-radius: 8px;
display: inline-block;
margin-block-end: 16px;
// container for context menu
.top-site-inner {
position: relative;
> a {
padding: 20px $half-base-gutter 4px;
color: inherit;
display: block;
outline: none;
}
}
&:is(:hover) {
.context-menu-button {
opacity: 1;
}
}
// Necessary for when navigating by a keyboard, having the context
// menu open should display the "…" button. This style is a clone
// of the `:active` state for `.context-menu-button`
&.active {
.context-menu-button {
opacity: 1;
background-color: var(--newtab-button-active-background);
}
}
.context-menu-button {
background-image: url('chrome://global/skin/icons/more.svg');
background-color: var(--newtab-button-background);
border: 0;
border-radius: 4px;
cursor: pointer;
fill: var(--newtab-button-text);
-moz-context-properties: fill;
height: 20px;
width: 20px;
inset-inline-end: 3px;
opacity: 0;
position: absolute;
top: -20px;
transition: opacity 200ms;
&:hover {
background-color: var(--newtab-button-hover-background);
&:active {
background-color: var(--newtab-button-active-background);
}
}
&:focus-visible {
background-color: var(--newtab-button-focus-background);
border-color: var(--newtab-button-focus-border);
opacity: 1;
}
}
.tile {
border-radius: $top-sites-border-radius;
box-shadow: $shadow-card;
background-color: var(--newtab-background-color-secondary);
justify-content: center;
margin: 0 auto;
height: $top-sites-size;
width: $top-sites-size;
cursor: pointer;
position: relative;
// For letter fallback
align-items: center;
color: var(--newtab-text-secondary-color);
display: flex;
font-size: 32px;
font-weight: 200;
text-transform: uppercase;
.icon-wrapper {
border-radius: 4px;
width: 48px;
height: 48px;
overflow: hidden;
position: relative;
display: flex;
align-items: center;
justify-content: center;
&.letter-fallback::before {
content: attr(data-fallback);
text-transform: uppercase;
display: flex;
align-items: center;
justify-content: center;
font-size: 64px;
font-weight: 800;
transform: rotate(-10deg);
top: 6px;
position: relative;
color: $letter-fallback-color;
}
}
}
// Some common styles for all icons (rich and default) in top sites
.top-site-icon {
background-color: var(--newtab-background-color-secondary);
background-position: center center;
background-repeat: no-repeat;
border-radius: $top-sites-icon-border-radius;
position: absolute;
}
.rich-icon {
background-size: cover;
height: 100%;
inset-inline-start: 0;
top: 0;
width: 100%;
}
.default-icon,
.search-topsite {
background-size: $default-icon-size;
height: $default-icon-wrapper-size;
width: $default-icon-wrapper-size;
// for corner letter fallback
align-items: center;
display: flex;
font-size: 20px;
justify-content: center;
&[data-fallback]::before {
content: attr(data-fallback);
}
}
.search-topsite {
background-size: 16px;
background-color: var(--newtab-primary-action-background);
border-radius: $default-icon-wrapper-size;
-moz-context-properties: fill;
fill: var(--newtab-primary-element-text-color);
box-shadow: $shadow-card;
transition-duration: $hover-transition-duration;
transition-property: background-size, bottom, inset-inline-end, height, width;
height: 32px;
width: 32px;
bottom: -$default-icon-offset;
inset-inline-end: -$default-icon-offset;
}
&.placeholder {
.tile {
box-shadow: $shadow-card;
cursor: default;
}
&.add-button {
.tile {
background-color: var(--button-background-color);
.icon-wrapper {
background-image: url('chrome://global/skin/icons/plus-20.svg');
background-size: cover;
background-repeat: no-repeat;
height: 20px;
width: 20px;
fill: var(--icon-color);
-moz-context-properties: fill;
}
}
}
}
.title {
color: var(--newtab-text-primary-color);
padding-top: 8px;
font: caption;
text-align: center;
position: relative;
.icon {
margin-inline-end: 2px;
fill: var(--newtab-text-primary-color);
}
span {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.sponsored-label {
color: var(--newtab-text-secondary-color);
font-size: 0.9em;
}
&:not(.sponsored) .sponsored-label {
visibility: hidden;
}
}
// We want all search shortcuts to have a white background in case they have transparency.
&.search-shortcut {
.rich-icon {
background-color: $white;
}
}
.edit-button {
background-image: url('chrome://global/skin/icons/edit.svg');
}
&.dragged {
.tile {
*,
&::before {
display: none;
}
}
.title {
visibility: hidden;
}
}
}
.edit-topsites-wrapper {
.top-site-inner > .top-site-button > .tile {
border: 1px solid var(--newtab-border-color);
}
.modal {
box-shadow: $shadow-secondary;
left: 0;
margin: 0 auto;
max-height: calc(100% - 40px);
position: fixed;
right: 0;
top: 40px;
width: $wrapper-default-width;
@media (min-width: $break-point-medium) {
width: $wrapper-max-width-medium;
}
@media (min-width: $break-point-large) {
width: $wrapper-max-width-large;
}
}
}
.topsite-form {
$form-width: 300px;
$form-spacing: 32px;
.section-title {
font-size: 16px;
margin: 0 0 16px;
}
.form-input-container {
max-width: $form-width + 3 * $form-spacing + $rich-icon-size;
margin: 0 auto;
padding: $form-spacing;
.top-site-outer {
pointer-events: none;
}
}
.search-shortcuts-container {
max-width: 700px;
margin: 0 auto;
padding: $form-spacing;
> div {
margin-inline-end: -39px;
}
.top-site-outer {
margin-inline-start: 0;
margin-inline-end: 39px;
}
}
.top-site-outer {
padding: 0;
margin: 24px 0 0;
margin-inline-start: $form-spacing;
}
.fields-and-preview {
display: flex;
}
label {
font-size: $section-title-font-size;
}
.form-wrapper {
width: 100%;
.field {
position: relative;
.icon-clear-input {
position: absolute;
transform: translateY(-50%);
top: 50%;
inset-inline-end: 8px;
}
}
.url {
input:dir(ltr) {
padding-right: 32px;
}
input:dir(rtl) {
padding-left: 32px;
&:not(:placeholder-shown) {
direction: ltr;
text-align: right;
}
}
}
.enable-custom-image-input {
display: inline-block;
font-size: 13px;
margin-top: 4px;
cursor: pointer;
}
.custom-image-input-container {
margin-top: 4px;
.loading-container {
width: 16px;
height: 16px;
overflow: hidden;
position: absolute;
transform: translateY(-50%);
top: 50%;
inset-inline-end: 8px;
}
// This animation is derived from Firefox's tab loading animation
.loading-animation {
@keyframes tab-throbber-animation {
100% { transform: translateX(-960px); }
}
@keyframes tab-throbber-animation-rtl {
100% { transform: translateX(960px); }
}
width: 960px;
height: 16px;
-moz-context-properties: fill;
fill: var(--newtab-primary-action-background);
animation: tab-throbber-animation 1.05s steps(60) infinite;
&:dir(rtl) {
animation-name: tab-throbber-animation-rtl;
}
}
}
input {
&[type='text'] {
background-color: var(--newtab-background-color-secondary);
border: $input-border;
margin: 8px 0;
padding: 0 8px;
height: 32px;
width: 100%;
font-size: 15px;
&[disabled] {
border: $input-border;
box-shadow: none;
opacity: 0.4;
}
}
}
.invalid {
input {
&[type='text'] {
border: $input-error-border;
box-shadow: $input-error-boxshadow;
}
}
}
.error-tooltip {
animation: fade-up-tt 450ms;
background: var(--newtab-status-error);
border-radius: 2px;
color: $white;
inset-inline-start: 3px;
padding: 5px 12px;
position: absolute;
top: 44px;
z-index: 1;
// tooltip caret
&::before {
background: var(--newtab-status-error);
bottom: -8px;
content: '.';
height: 16px;
inset-inline-start: 12px;
position: absolute;
text-indent: -999px;
top: -7px;
transform: rotate(45deg);
white-space: nowrap;
width: 16px;
z-index: -1;
}
}
}
.actions {
justify-content: flex-end;
button {
margin-inline-start: 10px;
margin-inline-end: 0;
}
}
@media (max-width: $break-point-medium) {
.fields-and-preview {
flex-direction: column;
.top-site-outer {
margin-inline-start: 0;
}
}
}
// prevent text selection of keyword label when clicking to select
.title {
user-select: none;
}
// CSS styled checkbox
[type='checkbox']:not(:checked),
[type='checkbox']:checked {
inset-inline-start: -9999px;
position: absolute;
}
[type='checkbox']:not(:checked) + label,
[type='checkbox']:checked + label {
cursor: pointer;
display: block;
position: relative;
}
$checkbox-offset: -8px;
[type='checkbox']:not(:checked) + label::before,
[type='checkbox']:checked + label::before {
background: var(--newtab-background-color);
border: $input-border;
border-radius: $border-radius;
content: '';
height: 21px;
left: $checkbox-offset;
position: absolute;
top: $checkbox-offset;
width: 21px;
z-index: 1;
[dir='rtl'] & {
left: auto;
right: $checkbox-offset;
}
}
// checkmark
[type='checkbox']:not(:checked) + label::after,
[type='checkbox']:checked + label::after {
background: url('chrome://global/skin/icons/check.svg') no-repeat center center;
content: '';
height: 21px;
left: $checkbox-offset;
position: absolute;
top: $checkbox-offset;
width: 21px;
-moz-context-properties: fill;
fill: var(--newtab-primary-action-background);
z-index: 2;
[dir='rtl'] & {
left: auto;
right: $checkbox-offset;
}
}
// when selected, highlight the tile
[type='checkbox']:checked + label {
.tile {
box-shadow: $shadow-focus;
}
}
// checkmark changes
[type='checkbox']:not(:checked) + label::after {
opacity: 0;
}
[type='checkbox']:checked + label::after {
opacity: 1;
}
// accessibility
[type='checkbox']:checked:focus + label::before,
[type='checkbox']:not(:checked):focus + label::before {
border: 1px dotted var(--newtab-primary-action-background);
}
}
// used for tooltips below form element
@keyframes fade-up-tt {
0% {
opacity: 0;
transform: translateY(15px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
// used for TopSites impression wrapper
.topsite-impression-observer {
position: absolute;
top: 0;
width: 100%;
height: 100%;
pointer-events: none;
}