HTML comments: syntax, multi-line comments and shortcuts

Put text between <!-- and --> and the browser leaves it off the page. The comment stays in the file, though, where anyone who opens the source can read it.

An HTML comment starts with <!-- and ends with -->. Everything between the two markers stays in the file but is left off the page: <!-- Update these hours in January -->.

Use comments for notes to yourself and to switch off a piece of markup while you test.

Edit the HTML on the left. The right side shows the page, and the list below shows every comment the browser found.

Live exampletry it here, then copy the code
Share it as a link
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>HTML comment playground</title>
<style>
  body { margin: 0; padding: 14px; font-family: system-ui, sans-serif; background: #f4f5f7; color: #1d2330; }
  .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
  @media (max-width: 560px) { .grid { grid-template-columns: 1fr; } }
  h2 { font-size: 13px; margin: 0 0 6px; color: #4b5563; text-transform: uppercase; letter-spacing: .4px; }
  textarea {
    width: 100%; box-sizing: border-box; height: 190px; padding: 10px;
    font: 13px/1.5 ui-monospace, Consolas, monospace;
    border: 1px solid #d5d9e0; border-radius: 8px; resize: vertical;
  }
  .box { background: #fff; border: 1px solid #e1e4ea; border-radius: 8px; padding: 10px 12px; min-height: 60px; }
  #page p { margin: 0 0 8px; }
  #found { margin: 0; padding-left: 20px; font: 12.5px/1.5 ui-monospace, Consolas, monospace; }
  #found li { background: #eef6f0; border-radius: 4px; padding: 2px 6px; margin-bottom: 4px; white-space: pre-wrap; word-break: break-word; }
  .count { font-size: 13px; margin: 10px 0 6px; }
</style>
</head>
<body>
<div class="grid">
  <div>
    <h2>Your HTML (edit it)</h2>
<textarea id="src" spellcheck="false"><p>Opening hours: 9 to 5.</p>
<!-- Update these hours in January -->
<p>Closed on public holidays.</p>
<!--
<p>Summer sale: 20% off.</p>
<p>Ends on Friday.</p>
-->
<p>Call us any time.</p></textarea>
  </div>
  <div>
    <h2>What the page shows</h2>
    <div class="box" id="page"></div>
  </div>
</div>

<p class="count" id="count"></p>
<div class="box"><ol id="found"></ol></div>

<script>
  const src = document.getElementById('src');
  const page = document.getElementById('page');
  const found = document.getElementById('found');
  const count = document.getElementById('count');

  function update() {
    page.innerHTML = src.value;  // the browser parses the HTML, comments included

    // Walk the parsed result and collect every Comment node
    const walker = document.createTreeWalker(page, NodeFilter.SHOW_COMMENT);
    const comments = [];
    while (walker.nextNode()) comments.push(walker.currentNode.data);

    count.textContent = comments.length + ' comment(s) found. They are in the page, but not on screen:';
    found.innerHTML = '';
    comments.forEach((text) => {
      const li = document.createElement('li');
      li.textContent = text.trim() || '(empty)';
      found.appendChild(li);
    });
  }

  src.addEventListener('input', update);
  update();
</script>
</body>
</html>
Type a comment, remove a closing marker, or wrap a paragraph. The browser decides what is hidden.

The browser does not throw comments away. It keeps each one in the page as a comment node. It just never draws them.

HTML comment syntax

A comment has three parts: the opener, the text, and the closer. The text can be a word, a sentence or a whole block of markup.

The opener, the text and the closer. The rules below apply to the text in the middle.
The opener, the text and the closer. The rules below apply to the text in the middle.
<!-- A one-line comment -->

<!--
  A comment can run over
  as many lines as you like.
-->

The HTML standard puts a few limits on the text inside. It must not start with > or ->. It must not contain <!--, --> or --!>, and it must not end with <!-.

Two hyphens in the middle, as in <!-- step 1 -- draft -->, are allowed in HTML today. XML and older versions of HTML did not allow them, so some style guides still say to avoid -- inside a comment. Avoiding it costs nothing.

Multi-line comments and commenting out code

HTML has no separate multi-line comment. The same markers cover any number of lines, because only --> ends a comment. A line break does not.

That makes comments the quickest way to switch something off while you test. Wrap the markup, reload, and the element is gone. Remove the two markers and it is back.

<p>Opening hours: 9 to 5.</p>
<!--
<p>Summer sale: 20% off.</p>
<p>Ends on Friday.</p>
-->

You rarely need to type the markers. In many editors, Ctrl+/ (Cmd+/ on a Mac) comments out the current line or the selected lines, and the same keys remove the comment again.

Editors that understand HTML usually switch to the CSS or JavaScript marker when the cursor is inside a <style> or <script> block.

Comments cannot be nested

This is the trap most people hit when they comment out a block that already has a comment in it. A comment ends at the first --> after it starts. The inner <!-- is just more text, and the inner --> closes the outer comment.

Live exampletry it here, then copy the code
Share it as a link
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>The nested comment trap</title>
<style>
  body { margin: 0; padding: 14px; font-family: system-ui, sans-serif; background: #f4f5f7; color: #1d2330; }
  .tabs button {
    font: 600 13px system-ui, sans-serif; padding: 7px 12px; margin: 0 6px 10px 0;
    border: 1px solid #d5d9e0; border-radius: 99px; background: #fff; cursor: pointer;
  }
  .tabs button.on { background: #1d2330; color: #fff; border-color: #1d2330; }
  h2 { font-size: 13px; margin: 12px 0 6px; color: #4b5563; text-transform: uppercase; letter-spacing: .4px; }
  pre {
    margin: 0; padding: 10px 12px; background: #fff; border: 1px solid #e1e4ea; border-radius: 8px;
    font: 13px/1.55 ui-monospace, Consolas, monospace; white-space: pre-wrap; word-break: break-word;
  }
  .c { background: #d6f2df; color: #0f5132; }      /* hidden by a comment */
  .end { background: #0f5132; color: #fff; }       /* the --> that closed it */
  .box { background: #fff; border: 1px solid #e1e4ea; border-radius: 8px; padding: 10px 12px; }
  .box p { margin: 0 0 6px; }
  .legend { font-size: 12.5px; color: #4b5563; margin-top: 6px; }
  .legend span { padding: 0 4px; border-radius: 3px; }
</style>
</head>
<body>
<div class="tabs">
  <button id="bad" class="on">Nested comment (broken)</button>
  <button id="good">Fixed</button>
</div>

<h2>Source</h2>
<pre id="code"></pre>
<p class="legend"><span class="c">green</span> = inside a comment, <span class="end">dark</span> = the <code>--&gt;</code> that ended it</p>

<h2>What the page shows</h2>
<div class="box" id="page"></div>

<!-- The two versions are kept in textareas so the markup stays plain text -->
<textarea id="v-bad" hidden><p>Welcome!</p>
<!-- Hide the banner for now
<div class="banner">
  <!-- TODO: new photo -->
  <b>Big sale today</b>
</div>
-->
<p>Thanks for visiting.</p></textarea>
<textarea id="v-good" hidden><p>Welcome!</p>
<!-- TODO: new photo -->
<!-- Hide the banner for now
<div class="banner">
  <b>Big sale today</b>
</div>
-->
<p>Thanks for visiting.</p></textarea>

<script>
  const code = document.getElementById('code');
  const page = document.getElementById('page');

  const esc = (s) => s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');

  // Mark comments the way the parser reads them:
  // a comment starts at <!-- and ends at the FIRST --> after it.
  function highlight(src) {
    let out = '', i = 0;
    while (true) {
      const start = src.indexOf('<!--', i);
      if (start < 0) break;
      const end = src.indexOf('-->', start + 4);
      if (end < 0) { out += esc(src.slice(i, start)) + '<span class="c">' + esc(src.slice(start)) + '</span>'; return out; }
      out += esc(src.slice(i, start))
        + '<span class="c">' + esc(src.slice(start, end)) + '</span>'
        + '<span class="end">--&gt;</span>';
      i = end + 3;
    }
    return out + esc(src.slice(i));
  }

  function show(which) {
    const src = document.getElementById('v-' + which).value;
    code.innerHTML = highlight(src);
    page.innerHTML = src;  // the real browser parser decides what is hidden
    document.getElementById('bad').classList.toggle('on', which === 'bad');
    document.getElementById('good').classList.toggle('on', which === 'good');
  }

  document.getElementById('bad').addEventListener('click', () => show('bad'));
  document.getElementById('good').addEventListener('click', () => show('good'));
  show('bad');
</script>
</body>
</html>
Switch between the two versions. Green is inside a comment, dark green is the marker that ended it.

Everything after that point is ordinary markup again. The sale text reappears, and the outer --> shows up on the page as literal text.

Nested: the first closing marker ends both comments. Side by side: two separate comments hide everything.
Nested: the first closing marker ends both comments. Side by side: two separate comments hide everything.

There are two fixes. Move the inner comment outside the block first, or delete its markers before you wrap the block. Either way, each <!-- gets exactly one -->.

Comments in CSS and JavaScript

Inside a <style> or <script> element, the browser is no longer reading HTML. The contents go to the CSS or JavaScript engine, and each language has its own comment markers.

The comment marker depends on the language of the part of the file you are in.
The comment marker depends on the language of the part of the file you are in.
Where Comment Notes
HTML, between tags <!-- note --> One line or many
CSS, in <style> or a .css file /* note */ CSS has no one-line // comment
JavaScript, in <script> or a .js file // note Hides the rest of that line
JavaScript, several lines /* note */ Cannot be nested either

The HTML markers do not do the job there. In CSS, <!-- and --> are skipped, so a rule between them still applies. In a classic script, each marker hides only the rest of its own line, so the code between them still runs.

/* This rule is switched off:
.card { border: 3px solid red; }
*/

The same applies to CSS in a separate file. External stylesheets use /* */ as well, and so does the style attribute used for inline CSS: style="color: red; /* color: blue; */" keeps the text red.

Anyone can read your comments

A comment is hidden from the page, not from people. View Source shows the file exactly as it was sent, comments included, and the browser developer tools list comment nodes next to the elements.

This finished page uses all three kinds. The old price is behind an HTML comment, a red border behind a CSS comment, and two lines of script behind JavaScript comments. The button shows what a visitor sees in the source.

Live exampletry it here, then copy the code
Share it as a link
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Comments in HTML, CSS and JS</title>
<style>
  body { margin: 0; padding: 14px; font-family: system-ui, sans-serif; background: #f4f5f7; color: #1d2330; }
  .card { background: #fff; border-radius: 12px; padding: 14px 16px; box-shadow: 0 4px 14px rgba(0,0,0,.08); }
  .card h1 { font-size: 18px; margin: 0 0 6px; }
  .price { font-size: 26px; font-weight: 700; color: #0f5132; }
  /* CSS comment: this rule is switched off
  .card { border: 3px solid red; }
  */
  #toggle { margin: 12px 0 8px; font: 600 13px system-ui, sans-serif; padding: 8px 12px; border-radius: 8px; border: 1px solid #1d2330; background: #1d2330; color: #fff; cursor: pointer; }
  #source { display: none; margin: 0; padding: 10px 12px; background: #fff; border: 1px solid #e1e4ea; border-radius: 8px; font: 12px/1.5 ui-monospace, Consolas, monospace; white-space: pre-wrap; word-break: break-word; }
  #source.open { display: block; }
  #source mark { background: #d6f2df; color: #0f5132; }
</style>
</head>
<body>
<div class="card">
  <h1>Starter plan</h1>
  <p class="price" id="price">$9 / month</p>
  <!-- HTML comment: the old price stays in the file, not on the page
  <p class="price">$12 / month</p>
  -->
  <p id="note">Cancel any time.</p>
</div>

<button id="toggle">Show source</button>
<pre id="source"></pre>

<script>
  // JS comment: the line below does nothing
  // document.getElementById('note').textContent = 'Old note';

  /* JS block comment: so does this one
  document.getElementById('price').style.color = 'red';
  */

  // Copy the page's own markup before anything changes
  const markup = '<!doctype html>\n' + document.documentElement.outerHTML;

  const esc = (s) => s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
  // Mark the three kinds of comment in the source view
  const marked = esc(markup).replace(/(&lt;!--[\s\S]*?--&gt;|\/\*[\s\S]*?\*\/|^\s*\/\/.*$)/gm, '<mark>$1</mark>');

  const source = document.getElementById('source');
  const toggle = document.getElementById('toggle');
  source.innerHTML = marked;

  toggle.addEventListener('click', () => {
    const open = source.classList.toggle('open');
    toggle.textContent = open ? 'Hide source' : 'Show source';
  });
</script>
</body>
</html>
Comments hide code from the page. Press the button: every comment is still in the source.

So never leave passwords, API keys, private links or internal notes in a comment. Commenting out a script does not remove it either. The code stays in the file for anyone to copy.

If comments should not reach visitors, remove them before the file goes out. A minifier does that as part of shrinking the file.

Conditional comments are obsolete

Older pages sometimes contain comments like this:

<!--[if IE]>
  <link rel="stylesheet" href="ie-fixes.css">
<![endif]-->

These conditional comments were read only by old versions of Internet Explorer. Microsoft removed them in Internet Explorer 10. Every current browser treats the whole thing as one ordinary comment, so the markup inside never loads. You can delete them.

When it does not work

What you see Cause Fix
Part of a commented block appears, followed by --> A comment inside the comment Move the inner comment out, or delete its markers
The rest of the page disappears The closing --> is missing or mistyped, such as - -> Add --> where the comment should end
A CSS rule still applies after wrapping it in <!-- --> CSS ignores HTML comment markers Use /* */
Script lines still run after wrapping them in <!-- --> Each marker hides only its own line Use // or /* */
A comment shows up as text A space in the opener, as in < !-- Type <!-- with no spaces
Someone found a key or a note in your page Comments ship with the file Delete it from the file, and change the key

Comments are easiest to explain on a page people can open. A screenshot cannot show what the source holds, and an .html attachment may open as plain code, or not at all, on a phone.

To send the working version, paste the page into a NOS document and choose Create share link. HTML to link walks through it.

The page renders as written and its scripts run, so the people you send it to can press the buttons and read the source themselves. If you change the code later, the same link shows the new version.

Questions people ask

How do I write a comment in HTML?

Start it with <!-- and end it with -->. Everything in between is left off the page, whether it is one line or many.

Is there a keyboard shortcut for HTML comments?

In many editors, Ctrl+/ (Cmd+/ on a Mac) comments out the current line or selection, and pressing it again removes the comment. Check your editor's keyboard settings if it does nothing.

Can I put one HTML comment inside another?

No. A comment ends at the first --> after it starts, so the inner comment's --> closes the outer one too. Whatever follows appears on the page, including a stray -->.

Do HTML comments work inside style or script tags?

No. Inside a style block use /* */. Inside a script block use // for one line or /* */ for several. The HTML markers there do not hide the code that sits between them.

Can visitors see my HTML comments?

Yes. Comments are not shown on the page, but they are part of the file. View Source and the browser developer tools both show them, so never keep passwords, keys or private notes in a comment.

Keep reading