I have a Readme with a half dozen lists.
Everything works fine until the second to last list. The problem is that an extra newline appears between those list items.
Your first list is a "tight" list while the second is a "loose" list because it contains a codeblock in one of the list items. If you want the lists to match, use the same type for both. Adding a blank line between items on the first list will cause them to match. As the spec explains:
A list is loose if any of its constituent list items are separated by blank lines, or if any of its constituent list items directly contain two block-level elements with a blank line between them. Otherwise a list is tight. (The difference in HTML output is that paragraphs in a loose list are wrapped in
tags, while paragraphs in a tight list are not.)
As a simple example, this list:
* line 1
* line 2
would be rendered to this HTML:
- line 1
- line 2
Whereas this list:
* line 1
* line 2
a second block
Would be rendered as:
-
line 1
-
line 2
a second block
Notice that the second list item contains multiple paragraphs. Therefore each paragraph in the the list item is wrapped in tags, making the list a "loose" list. For consistency, all items in the list are then wrapped in
tags (including the first item). While that example uses a paragraph, the same applies to any blocklevel construct, including the codeblock in your example.
You can also force a list to be a "loose" list by adding a blank line between list items. For example, this list:
* line 1
* line 2
Results in this HTML:
-
line 1
-
line 2
Therefore, if you add a blank line between at least two of the items in your first list, both lists will consistently be displayed with some white space between them.
The reason that wrapping the content of the list item in tags adds white space is that the styles for the page (CSS) have defined padding and/or margin for
tags. One could edit the CSS to remove this padding/margin on their own site, but on third party hosts, that is generally not an option.
As for why some tools do not seem to exhibit this behavior; it could be that they have default CSS styles which cause both types of lists to look the same (StackOverflow does this for example). The other possibility is that they are using an old-school Markdown parser rather than the much newer CommonMark spec (which GitHub uses). The original Markdown rules also had the concept of loose and tight lists, but the behavior was not so specifically defined so different implementations behaved slightly differently. Many followed the reference implementation and only made the list items adjacent to blank lines "loose" and all other items "tight". In your example only the last item would be "loose" but, as it is the last item in the list, would not be as noticeable. For a comparison of how various implementations behave, see Babelmark.
Regardless of implementation, if you want "tight" lists, the only way to always get that is to never include any blank lines anywhere in your list items. That means that you can never nest other block level constructs, with a few very specific exceptions:
The obvious exception would be nested lists, but even then, you would need to avoid blank lines (see example):
* parent item
* nested item
* Another nested item
* sibling of parent
* Another sibling of parent
A nested codeblock or blockquote can be nested in some implementations, but it needs to start on the first line of the list item and contain no blank lines.
* list item
* A code block because it is indented appropriately
* > a blockquote
* a list item
As you can see in that example, it only works in some implementations. Notably, the CommonMark implementations. In other words it will work on GitHub, but it may not with other tools or on other sites.
Regardless, you can not have a a tight list if you have multiple child paragraphs, code blocks, and/or blockquotes.