accessibility improvements for quick format dialog (#3464)
- removed all cursor-related logic. Instead, insert a new input component each time the user wants to type. The input remain between bubbles and focusing on one will open the reference panel. Leaving the input hides the reference panel. - during drag-drop reordering, lock the editor height so that it doesn't get out of sync with the window. - removed the iframe, since it was no longer needed. - keyboard navigation: Home/End will place an input at the start/end of the editor and focus it. Tab focuses the last active input if any, or the input in the end otherwise. Shift-Tab from the editor focuses the dropdown button if it is active. Tab from the input will focus the first entry of the reference list. Tab from the reference list will focus the active input. Shift-ArrowLeft/Right from focused bubble will swap the bubble with its neighbor. ArrowDown/Up from bubble will open/close the citation dialog. - when a reference item is selected, previously active input is re-focused. - aria-properties to have voiceover, JAWS and NVDA read bubbles, inputs and reference items, as well as announce hints about available keypresses. - typing from bubble or the reference panel will refocus previously active input - different minor updates to make the functionality less janky - refactoring of refreshing and resizing of the reference panel to be more straightforward and to only do it when necessary. E.g. clicking on a bubble and closing the popover after will not rerun search and just display the old results. - some throttling logic so that two escape keypresses one after another when the itemPopover is open do not close the entire dialog - renamed variables: qfb=dialog, qfe=editor, panel=itemPopover - use short form of locator string for bubbles
This commit is contained in:
parent
5dcaf65757
commit
0007d077cc
9 changed files with 1069 additions and 597 deletions
|
@ -26,9 +26,6 @@ window.citation-dialog {
|
|||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.citation-dialog.search:not([multiline="true"]) {
|
||||
height: 32px !important;
|
||||
}
|
||||
|
||||
.citation-dialog.entry {
|
||||
background: -moz-linear-gradient(-90deg, rgb(243,123,119) 0, rgb(180,47,38) 50%, rgb(156,36,27) 50%);
|
||||
|
@ -95,8 +92,4 @@ panel button:hover:active {
|
|||
|
||||
panel button:-moz-focusring {
|
||||
box-shadow: 0 0 1px -moz-mac-focusring inset, 0 0 4px 1px -moz-mac-focusring, 0 0 2px 1px -moz-mac-focusring;
|
||||
}
|
||||
|
||||
.citation-dialog.bubble {
|
||||
padding: 1px 6px 1px 6px;
|
||||
}
|
|
@ -18,6 +18,7 @@ window.citation-dialog {
|
|||
}
|
||||
|
||||
#zotero-icon {
|
||||
margin: 0 0 0 2px;
|
||||
padding: 4px 4px 6px 4px !important;
|
||||
margin: 2px 0;
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
|
||||
Copyright © 2022 Center for History and New Media
|
||||
George Mason University, Fairfax, Virginia, USA
|
||||
http://zotero.org
|
||||
|
||||
This file is part of Zotero.
|
||||
|
||||
Zotero is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Zotero is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
-->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" style="height: 100%">
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://zotero/skin/integration.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://zotero-platform/content/zotero.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://zotero-platform/content/integration.css"/>
|
||||
</head>
|
||||
<body contenteditable="true" spellcheck="false" class="citation-dialog editor"></body>
|
||||
</html>
|
|
@ -26,6 +26,7 @@
|
|||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://global/skin/browser.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://zotero/skin/zotero.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://zotero-platform/content/zotero.css"?>
|
||||
<?xml-stylesheet href="chrome://zotero/skin/integration.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://zotero-platform/content/integration.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://zotero-platform-version/content/style.css" type="text/css"?>
|
||||
|
@ -39,7 +40,7 @@
|
|||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
persist="screenX screenY"
|
||||
onkeypress="Zotero_QuickFormat.onKeyPress(event)"
|
||||
onkeypress="Zotero_QuickFormat.onWindowKeyPress(event)"
|
||||
onunload="Zotero_QuickFormat.onUnload()">
|
||||
|
||||
<script src="../include.js"/>
|
||||
|
@ -49,18 +50,12 @@
|
|||
|
||||
<box orient="horizontal" class="citation-dialog entry">
|
||||
<deck class="citation-dialog deck" selectedIndex="0" flex="1">
|
||||
<hbox class="citation-dialog search" flex="1" align="start">
|
||||
<hbox class="citation-dialog main" flex="1" align="start">
|
||||
<hbox flex="1">
|
||||
<iframe
|
||||
class="citation-dialog iframe"
|
||||
ondragstart="event.stopPropagation()"
|
||||
src="citationDialogIframe.html"
|
||||
tabindex="1"
|
||||
flex="1"
|
||||
type="content"
|
||||
remote="false"
|
||||
maychangeremoteness="false"/>
|
||||
<image class="citation-dialog spinner zotero-spinner-16"/>
|
||||
<html:div flex="1" spellcheck="false" class="citation-dialog editor insert-note" role="application"></html:div>
|
||||
<vbox class="citation-dialog spinner">
|
||||
<image class="zotero-spinner-16"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</hbox>
|
||||
<html:progress class="citation-dialog progress-meter" max="100"/>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -41,72 +41,72 @@
|
|||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
persist="screenX screenY"
|
||||
width="800"
|
||||
onkeypress="Zotero_QuickFormat.onKeyPress(event)"
|
||||
onkeypress="Zotero_QuickFormat.onWindowKeyPress(event)"
|
||||
onunload="Zotero_QuickFormat.onUnload()">
|
||||
|
||||
<script src="../include.js"/>
|
||||
<script src="windowDraggingUtils.js" type="text/javascript"/>
|
||||
<script src="quickFormat.js" type="text/javascript"/>
|
||||
|
||||
<linkset>
|
||||
<html:link rel="localization" href="zotero.ftl"/>
|
||||
</linkset>
|
||||
|
||||
<box orient="horizontal" class="citation-dialog entry">
|
||||
<deck class="citation-dialog deck" selectedIndex="0" flex="1">
|
||||
<hbox class="citation-dialog search" flex="1" align="start">
|
||||
<hbox class="citation-dialog main" flex="1" align="start">
|
||||
<hbox flex="1">
|
||||
<toolbarbutton id="zotero-icon" type="menu">
|
||||
<menupopup>
|
||||
<menuitem id="keep-sorted" label="&zotero.citation.keepSorted.label;"
|
||||
oncommand="Zotero_QuickFormat.onKeepSortedCommand()" type="checkbox"
|
||||
hidden="true"/>
|
||||
<menuitem id="show-editor" label="&zotero.integration.showEditor.label;"
|
||||
oncommand="Zotero_QuickFormat.onShowEditorCommand()" type="checkbox"
|
||||
hidden="true"/>
|
||||
<menuitem id="classic-view" label="&zotero.integration.classicView.label;"
|
||||
oncommand="Zotero_QuickFormat.onClassicViewCommand()"/>
|
||||
</menupopup>
|
||||
</toolbarbutton>
|
||||
|
||||
<iframe
|
||||
class="citation-dialog iframe"
|
||||
ondragstart="event.stopPropagation()"
|
||||
src="citationDialogIframe.html"
|
||||
tabindex="1"
|
||||
flex="1"
|
||||
type="content"
|
||||
remote="false"
|
||||
maychangeremoteness="false"/>
|
||||
|
||||
<image class="citation-dialog spinner zotero-spinner-16"/>
|
||||
<vbox flex="1" align="center" style="display: flex;align-items: center;max-width: 38px;justify-content: center;">
|
||||
<toolbarbutton id="zotero-icon" type="menu" tabindex="0" disabled="true">
|
||||
<menupopup>
|
||||
<menuitem id="keep-sorted" label="&zotero.citation.keepSorted.label;"
|
||||
oncommand="Zotero_QuickFormat.onKeepSortedCommand()" type="checkbox"
|
||||
hidden="true"/>
|
||||
<menuitem id="show-editor" label="&zotero.integration.showEditor.label;"
|
||||
oncommand="Zotero_QuickFormat.onShowEditorCommand()" type="checkbox"
|
||||
hidden="true"/>
|
||||
<menuitem id="classic-view" label="&zotero.integration.classicView.label;"
|
||||
oncommand="Zotero_QuickFormat.onClassicViewCommand()"/>
|
||||
</menupopup>
|
||||
</toolbarbutton>
|
||||
</vbox>
|
||||
<html:div flex="1" spellcheck="false" class="citation-dialog editor" role="application"></html:div>
|
||||
<vbox class="citation-dialog spinner">
|
||||
<image class="zotero-spinner-16"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</hbox>
|
||||
<html:progress class="citation-dialog progress-meter" max="100"/>
|
||||
</deck>
|
||||
</box>
|
||||
<html:div id="bubble-description" class="aria-hidden" role="tooltip" data-l10n-id="quickformat-aria-bubble"></html:div>
|
||||
<html:div id="input-description" class="aria-hidden" role="tooltip" data-l10n-id="quickformat-aria-input"></html:div>
|
||||
<html:div id="item-description" class="aria-hidden" role="tooltip" data-l10n-id="quickformat-aria-item"></html:div>
|
||||
<panel class="citation-dialog reference-panel" noautofocus="true" norestorefocus="true"
|
||||
height="0" width="0">
|
||||
<richlistbox class="citation-dialog reference-list" flex="1"/>
|
||||
</panel>
|
||||
<panel id="citation-properties" type="arrow" orient="vertical"
|
||||
onkeypress="Zotero_QuickFormat.onPanelKeyPress(event)"
|
||||
onpopuphidden="Zotero_QuickFormat.onCitationPropertiesClosed(event)">
|
||||
onkeydown="Zotero_QuickFormat.onPanelKeyPress(event)"
|
||||
onpopuphidden="Zotero_QuickFormat.onItemPopoverClosed(event)">
|
||||
<vbox flex="1">
|
||||
<description id="citation-properties-title"/>
|
||||
<hbox id="citation-properties-info"/>
|
||||
<description id="citation-properties-title" tabindex="1"/>
|
||||
<hbox id="citation-properties-info" tabindex="2"/>
|
||||
</vbox>
|
||||
<html:div id="citation-properties-grid">
|
||||
<menulist id="locator-label" sizetopopup="none"
|
||||
<menulist id="locator-label" sizetopopup="none" tabindex="3"
|
||||
oncommand="Zotero_QuickFormat.onCitationPropertiesChanged(event)" native="true">
|
||||
<menupopup id="locator-label-popup"/>
|
||||
<menupopup id="locator-label-popup" onpopuphidden="Zotero_QuickFormat.ignoreEvent(event)"/>
|
||||
</menulist>
|
||||
<html:input type="text" id="locator"
|
||||
<html:input type="text" aria-labelledby="locator-label" tabindex="4" id="locator"
|
||||
oninput="window.setTimeout(function(event) { Zotero_QuickFormat.onCitationPropertiesChanged(event) }, 0)"/>
|
||||
<label value="&zotero.citation.prefix.label;"/>
|
||||
<html:input type="text" class="citation-textbox" id="prefix" flex="1"
|
||||
<label id="prefix-label" value="&zotero.citation.prefix.label;"/>
|
||||
<html:input type="text" aria-labelledby="prefix-label" tabindex="5" class="citation-textbox" id="prefix" flex="1"
|
||||
oninput="window.setTimeout(function(event) { Zotero_QuickFormat.onCitationPropertiesChanged(event) }, 0)"/>
|
||||
<label value="&zotero.citation.suffix.label;"/>
|
||||
<html:input type="text" class="citation-textbox" id="suffix" flex="1"
|
||||
<label id="suffix-label" value="&zotero.citation.suffix.label;"/>
|
||||
<html:input type="text" aria-labelledby="suffix-label" tabindex="6" class="citation-textbox" id="suffix" flex="1"
|
||||
oninput="window.setTimeout(function(event) { Zotero_QuickFormat.onCitationPropertiesChanged(event) }, 0)"/>
|
||||
<html:div>
|
||||
<html:input type="checkbox" id="suppress-author" native="true"
|
||||
<html:input type="checkbox" id="suppress-author" native="true" tabindex="7"
|
||||
onchange="Zotero_QuickFormat.onCitationPropertiesChanged(event)"/>
|
||||
<html:label for="suppress-author">
|
||||
&zotero.citation.suppressAuthor.label;
|
||||
|
@ -114,7 +114,7 @@
|
|||
</html:div>
|
||||
</html:div>
|
||||
<vbox flex="1" align="center">
|
||||
<button id="citation-properties-library-link" onclick="Zotero_QuickFormat.showInLibrary()"/>
|
||||
<button id="citation-properties-library-link" tabindex="8" onclick="Zotero_QuickFormat.showInLibrary()"/>
|
||||
</vbox>
|
||||
</panel>
|
||||
<guidance-panel class="citation-dialog guidance" about="quickFormat"
|
||||
|
|
|
@ -44,9 +44,10 @@ Zotero.Cite = {
|
|||
* Get localized string for locator
|
||||
*
|
||||
* @param {String} locator - Locator name (e.g., 'book')
|
||||
* @param {string} form - Fetch a specific form of the locator. E.g. form="short" for "page" is "p."
|
||||
* @return {String} - Localized string (e.g., 'Livre')
|
||||
*/
|
||||
getLocatorString: function (locator) {
|
||||
getLocatorString: function (locator, form = null) {
|
||||
// 'timestamp' not included in CSL locales
|
||||
if (locator == 'timestamp') {
|
||||
return Zotero.getString('citation.locator.timestamp');
|
||||
|
@ -60,6 +61,11 @@ Zotero.Cite = {
|
|||
|
||||
// If locator strings are already cached for the current locale, use that
|
||||
if (this._locatorStrings.has(cslLocale)) {
|
||||
// If a specific form is requested, try to return it. Fallback to the regular form if not found.
|
||||
if (form) {
|
||||
let locatorWithForm = this._locatorStrings.get(cslLocale).get(locator + `_${form}`);
|
||||
if (locatorWithForm) return locatorWithForm;
|
||||
}
|
||||
return this._locatorStrings.get(cslLocale).get(locator);
|
||||
}
|
||||
var map = new Map();
|
||||
|
@ -78,16 +84,17 @@ Zotero.Cite = {
|
|||
var englishDoc;
|
||||
// Cache all locators for the current locale
|
||||
for (let locator of this.labels) {
|
||||
let elem = doc.querySelector(`term[name="${locator}"]:not([form="short"]) > single`);
|
||||
if (!elem) {
|
||||
// Fetch all <term>s - including the short form
|
||||
let terms = [...doc.querySelectorAll(`term[name="${locator}"]`)];
|
||||
if (!terms.length) {
|
||||
// If locator not found, get from the U.S. English locale
|
||||
if (cslLocale != 'en-US') {
|
||||
Zotero.logError(`Locator '${locator}' not found in ${cslLocale} locale -- trying en-US`);
|
||||
if (!englishDoc) {
|
||||
englishDoc = parser.parseFromString(Zotero.Cite.Locale.get('en-US'), 'text/xml');
|
||||
}
|
||||
elem = englishDoc.querySelector(`term[name="${locator}"]:not([form="short"]) > single`);
|
||||
if (!elem) {
|
||||
terms = englishDoc.querySelectorAll(`term[name="${locator}"]}`);
|
||||
if (!terms.length) {
|
||||
Zotero.logError(`Locator '${locator}' not found in en-US locale -- using name`);
|
||||
}
|
||||
}
|
||||
|
@ -95,22 +102,31 @@ Zotero.Cite = {
|
|||
Zotero.logError(`Locator '${locator}' not found in en-US locale -- using name`);
|
||||
}
|
||||
// If still not found, use the locator name directly
|
||||
if (!elem) {
|
||||
if (!terms.length) {
|
||||
map.set(locator, Zotero.Utilities.capitalize(locator));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// If <single> is empty, use the locator name directly
|
||||
let str = elem.textContent;
|
||||
if (!str) {
|
||||
Zotero.logError(`Locator '${locator}' is empty in ${cslLocale} locale -- using name`);
|
||||
map.set(locator, Zotero.Utilities.capitalize(locator));
|
||||
continue;
|
||||
// Add all terms to the cache. If a term has a form, add "_<form>" suffix after the locator.
|
||||
// E.g. <term name="page" form="short"> is saved as "page_short" = "p."
|
||||
for (let elem of terms) {
|
||||
let single = elem.querySelector("single");
|
||||
// If <single> is empty, use the locator name directly
|
||||
if (!single) {
|
||||
single = elem;
|
||||
}
|
||||
let str = single.textContent;
|
||||
if (!str) {
|
||||
Zotero.logError(`Locator '${locator}' is empty in ${cslLocale} locale -- using name`);
|
||||
map.set(locator, Zotero.Utilities.capitalize(locator));
|
||||
continue;
|
||||
}
|
||||
let form = elem.getAttribute('form');
|
||||
map.set(locator + (form ? `_${form}` : ''), Zotero.Utilities.capitalize(str));
|
||||
}
|
||||
map.set(locator, Zotero.Utilities.capitalize(str));
|
||||
}
|
||||
|
||||
return map.get(locator);
|
||||
|
||||
return map.get(locator + (form ? `_${form}` : ''));
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -421,3 +421,7 @@ toggle-preview =
|
|||
[collapsed] Show
|
||||
*[unknown] Toggle
|
||||
} Attachment Preview
|
||||
|
||||
quickformat-aria-bubble = Down Arrow to open citation properties. Up Arrow to close citation properties after.
|
||||
quickformat-aria-input = Type to search for your item. Tab to navigate the items list.
|
||||
quickformat-aria-item = Tab to go back to the search field. Enter to select this item.
|
|
@ -108,21 +108,46 @@
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
.citation-dialog .zotero-bubble-input {
|
||||
outline: none;
|
||||
min-width: 10px;
|
||||
width: 10px;
|
||||
border: none;
|
||||
max-width: 700px; /* Entire line of the editor */
|
||||
box-sizing: border-box;
|
||||
height: 15px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.citation-dialog span {
|
||||
/* Same left padding as for input */
|
||||
padding-left: 4px;
|
||||
/* Make last white space be counted during width calculations */
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
#dragged-bubble {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.citation-dialog.bubble {
|
||||
border-radius: 8px;
|
||||
background-color: #dee7f8;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-color: #a8c0ec;
|
||||
padding: 0 6px 0 6px;
|
||||
margin: -1px 2px 0 2px;
|
||||
padding: 0 6px;
|
||||
margin: 3px 2px 0 2px;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
line-height: normal;
|
||||
color: #000;
|
||||
-moz-user-select: all;
|
||||
-moz-user-select: none;
|
||||
cursor: pointer;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
|
||||
.citation-dialog.bubble:hover {
|
||||
background-color: #bbcef1;
|
||||
border-color: #6d95e0;
|
||||
|
@ -134,12 +159,13 @@
|
|||
color: #fff;
|
||||
}
|
||||
|
||||
.citation-dialog.search {
|
||||
.citation-dialog.main {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
background: white;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.citation-dialog.iframe {
|
||||
|
@ -148,31 +174,36 @@
|
|||
}
|
||||
|
||||
.citation-dialog.editor {
|
||||
padding: 0 2px 0 2px;
|
||||
padding: 0 2px 0px 2px;
|
||||
margin: 0;
|
||||
font: -moz-field;
|
||||
overflow: hidden;
|
||||
outline: none;
|
||||
line-height: 2em;
|
||||
width: 710px;
|
||||
height: 28px;
|
||||
font-size: 13px;
|
||||
background: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.citation-dialog.editor.insert-note {
|
||||
width: 750px;
|
||||
}
|
||||
|
||||
.citation-dialog.editor::selection {
|
||||
color: white;
|
||||
background: var(--color-accent);
|
||||
}
|
||||
|
||||
.citation-dialog.spinner {
|
||||
margin-top: 2px;
|
||||
margin-right: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.citation-dialog.item {
|
||||
font-size: 12px;
|
||||
font: -moz-field;
|
||||
-moz-user-focus: normal;
|
||||
padding: 3px 5px 3px 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.citation-dialog.item:not(:last-child), .citation-dialog.separator:not(:last-child) {
|
||||
|
@ -218,15 +249,26 @@ richlistitem[selected="true"] {
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
#zotero-icon .toolbarbutton-text {
|
||||
display: none;
|
||||
/* Add cursor and hover/active effects to make the Z icon act like a button */
|
||||
#zotero-icon:not([disabled]) {
|
||||
cursor: pointer;
|
||||
padding: 5px 4px 5px 5px;
|
||||
}
|
||||
|
||||
#zotero-icon .toolbarbutton-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
#zotero-icon:not([disabled]):hover,
|
||||
#zotero-icon:not([disabled]):focus,
|
||||
#zotero-icon[open="true"]:not([disabled]) {
|
||||
background: #f2f2f2;
|
||||
}
|
||||
|
||||
|
||||
#zotero-icon:not([disabled])::after {
|
||||
background: url("searchbar-dropmarker@2x.png") no-repeat center / contain;
|
||||
display: inline-block;
|
||||
content: "";
|
||||
width: 5px;
|
||||
height: 8px;
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
#citation-properties:is(panel, menupopup)::part(content) {
|
||||
|
@ -304,3 +346,14 @@ panel button .button-text {
|
|||
window.citation-dialog {
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.aria-hidden {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue