afin qu'ils puissent défiler ensemble et rester alignés.
Le CSS
Voici l'intégralité du CSS que j'ai utilisé pour l'éditeur.
html,
body {
height: 100vh;
width: 100vw;
padding: 0;
margin: 0;
}
#editor {
height: 100%;
width: 100%;
box-sizing: border-box;
display: grid;
grid-template: 1fr / 1fr;
place-items: top;
overflow: auto;
padding: 2rem;
background-color: #1a1723;
}
#editor .code,
#editor .preview {
all: unset;
}
#editor .code,
#editor .preview {
height: auto;
grid-column: 1 / 1;
grid-row: 1 / 1;
font-family: Monaco, monospace;
font-size: 16px;
resize: none;
line-height: 24px;
white-space: pre-wrap;
overflow: hidden;
}
#editor .preview {
pointer-events: none;
color: #ccc;
}
#editor .code {
color: rgba(255, 255, 255, 0);
caret-color: magenta;
}
Superposition des éléments
L'un des éléments clés ici consiste à utiliser la grille d'affichage pour superposer la zone de texte et l'aperçu
#editor {
...
display: grid;
grid-template: 1fr / 1fr;
place-items: top;
overflow: auto;
...
}
J'utilise l'unité fr pour superposer les deux éléments à l'intérieur du conteneur. Vous pouvez en savoir plus sur fr sur CSSTricks ici.
Stylage de la zone de texte et aperçu à l'identique
Vous remarquerez peut-être que j'applique les mêmes règles à l'aperçu et à la zone de texte. Cela garantit qu'ils se chevauchent avec précision.
#editor .code,
#editor .preview {
height: auto;
grid-column: 1 / 1;
grid-row: 1 / 1;
font-family: Monaco, monospace;
font-size: 16px;
resize: none;
line-height: 24px;
white-space: pre-wrap;
overflow: hidden;
}
Rendre la zone de texte transparente
Utiliser rgba pour la couleur du texte me permet d'avoir le texte entièrement transparent, il semble donc que vous sélectionniez et modifiiez l'aperçu.
#editor .code {
color: rgba(255, 255, 255, 0);
caret-color: magenta;
}
Un peu de Javascript
Nous avons besoin d'une petite quantité de Javascript pour relier tout cela ensemble. Jetons un coup d'œil à ce dont nous avons besoin.
const $preview = document.querySelector("#editor .preview");
const $code = document.querySelector("#editor .code");
function mirror() {
// make textarea grow to height of content so we can scroll together
$code.style.height = $code.scrollHeight;
// update the preview underlay with the syntax highlight
$preview.innerHTML = Prism.highlight(
$code.value,
Prism.languages.javascript,
"javascript",
);
}
// insert two spaces on tab
$code.addEventListener("keydown", (ev) => {
if (ev.code === "Tab") {
ev.preventDefault();
$code.setRangeText(" ", $code.selectionStart, $code.selectionStart, "end");
mirror();
}
});
$code.addEventListener("input", mirror);
mirror();
Nous utiliserons Prism pour cela, mais vous pouvez utiliser tout ce que vous voulez.
La fonction miroir() fait plusieurs choses ici.
<div id="editor">
<div class="preview"></div>
<textarea class="code" spellcheck="false"></textarea>
</div>
Cela garantit que lorsque vous tapez, la hauteur du champ
html,
body {
height: 100vh;
width: 100vw;
padding: 0;
margin: 0;
}
#editor {
height: 100%;
width: 100%;
box-sizing: border-box;
display: grid;
grid-template: 1fr / 1fr;
place-items: top;
overflow: auto;
padding: 2rem;
background-color: #1a1723;
}
#editor .code,
#editor .preview {
all: unset;
}
#editor .code,
#editor .preview {
height: auto;
grid-column: 1 / 1;
grid-row: 1 / 1;
font-family: Monaco, monospace;
font-size: 16px;
resize: none;
line-height: 24px;
white-space: pre-wrap;
overflow: hidden;
}
#editor .preview {
pointer-events: none;
color: #ccc;
}
#editor .code {
color: rgba(255, 255, 255, 0);
caret-color: magenta;
}
Ensuite, nous utilisons Prism pour récupérer le code de la zone