You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ashen-earth/posts/2019-12-04_html-beginners-g...

214 lines
9.9 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

---
title: "A Beginner's Guide to HTML: Layout and Display"
subtitle: Some early thoughts for a friend
---
Welcome back! It's been a while, but today we're going to talk about
web stuff - I've been meaning to write a beginner's guide for a friend, so
today's the day!
We're not going to get too far into depth, we'll just be going over the basics of
browser layout, and how to use display `inline`, `block`, and `inline-block` elements.
> *Note:* This post will not be addressing `flex` or `grid` elements - I plan to cover those in a later post.
## Browser Layout and the Display Property
Every element in an HTML page has a `display` property - you might see it defined in CSS like this:
```css
img.photo {
display: block;
}
img.icon {
display: inline;
}
img.galleryCard {
display: inline-block;
}
```
This instructs the browser to render various elements as either `display: block`, `display: inline`, or `display: inline-block`. But what exactly do these display rules mean?
Generally speaking: block elements are elements which the browser renders as a box, and inline elements are elements which the browser renders as flowing text. Lets get into that a bit more!
### Block elements:
- Can have a defined width and height
- Can be given both vertical and horizontal margins
- Clear the whole width of their container
Block elements are typically things like <div>, <ul>, and header (<h1><h6>) elements - although most HTML elements can be rendered as a block if you enforce it with the `display: block` rule. Heres a quick example:
```html
<div style="
padding: 10px;
background: gray;
color: white
">
<p>This box is display block. Notice it takes the full width of its container.</p>
</div>
```
<div style="background:#444; padding: 20px">
<div style="background: gray; padding:10px; color: white">
<p>This box is display block. Notice it takes the full width of its container.</p>
</div>
</div>
See how this box automatically takes the full width? We can give it a fixed width and it will behave slightly differently:
```html
<div style="
width:200px;
padding: 10px;
background: gray;
color: white
">
<p>This box is display block.</p>
<p>It is constrained to be 200px wide.</p>
</div>
```
<div style="background:#444; padding: 20px">
<div style="width:200px; background: gray; padding:10px; color: white">
<p>This box is display block.</p>
<p>It is constrained to be 200px wide.</p>
</div>
</div>
Lets look at whats going on here:
- The box is set to have a width of 200px
- We give it 10px of padding on each side (so the text doesn't run right up to the edge)
- We set the background color of the box and text color for elements in the box
Remember how initially I mentioned that block elements clear the width of their container? Let's demonstrate that:
<div style="color: white; background:#444; padding: 20px">
Text before the block element . . .
<div style="width:200px; height: 200px;margin:20px 0;background: gray; padding:10px; color: white">
<p>Even when we remove the centering margin - block elements clear the whole width of their container.</p>
</div>
Text after the block element . . .
</div>
Block elements clear all of the space to the side of them _by default_. This can be convenient sometimes, but other times it will be a bit annoying - try putting a border around a &lt;h1&gt; tag sometime, unless youre clever the border will extend to the full width of the page.
So if thats block elements, how are inline elements different?
### Inline elements:
- Flow from line to line, filling the space defined by their closest `block` ancestor
- Cannot have vertical margins
- Do not clear space to either side of them
Inline elements are things like &lt;a&gt;, &lt;b&gt;, &lt;i&gt;, and &lt;span&gt; tags. These are effectively treated as text, they wrap at the end of the line, and generally flow like you would expect text to in a word processor, although they dont necessarily have to be text:
```html
<img src="https://placekitten.com/250/100"/>
<img src="https://placekitten.com/250/100"/>
<img src="https://placekitten.com/250/100"/>
<img src="https://placekitten.com/250/100"/>
```
<div style="padding: 20px; text-align: center; background: #444;">
<img style="display: inline" src="https://placekitten.com/250/100"/>
<img style="display: inline" src="https://placekitten.com/250/100"/>
<img style="display: inline" src="https://placekitten.com/250/100"/>
<img style="display: inline" src="https://placekitten.com/250/100"/>
</div>
Notice how when your screen isn't wide enough for all of them, these kitten images wrap at the end of the line? Also of interest is that there is a space between each of them (from the whitespace in our source code) but not between different rows of images. Images are by default `display: inline` so the browser tries to use its text-layout rules for how it should display these kittens.
One downside to inline display elements like this is that we have very little control over how much space is around our kittens - we can set a left or right margin, but theres no way to make sure we have vertical spacing between the rows. Well see in a bit how we can use `inline-block` to get around this, but lets keep exploring how `inline` works for a second.
Because these images are treated as very tall text, other text immediately before or after the kittens can also get weird - inline elements **dont** clear space beside them like block elements:
```html
Text immediately before an image
<img src="https://placekitten.com/100/100"/>
<img src="https://placekitten.com/100/100"/>
Text immediately after
```
<div style="color: white; padding: 20px; background: #444;">
Text immediately before an image
<img style="display: inline" src="https://placekitten.com/100/100"/>
<img style="display: inline" src="https://placekitten.com/100/100"/>
Text immediately after
</div>
But remember we said before that any of these `display` properties can be overwritten?! If we instead set our kittens to be `display: block` then we see that our kittens suddenly behave much more like our space-clearing box from earlier:
```html
Text immediately before an image
<img style="display: block" src="https://placekitten.com/250/300"/>
Text immediately after
```
<div style="color: white; padding: 20px; background: #444;">
Text immediately before an image
<img style="display: block" src="https://placekitten.com/250/300"/>
Text immediately after
</div>
**Note:** This technique of setting images to be `display: block` is often used for illustrations on the web - just add an `auto` side margin and its even centered:
```html
Illustration of a kitten:
<img style="display: block; margin: 20px auto" src="https://placekitten.com/200/300"/>
(Text after the kitten)
```
<div style="color: white; padding: 20px; background: #444;">
Illustration of a kitten:
<img style="display: block; margin: 20px auto" src="https://placekitten.com/200/300"/>
(Text after the kitten)
</div>
Now you might be thinking _“Couldnt I just use &lt;p&gt; tags for my text and not have to deal with this `display: block` stuff?”_ . . . well yes. Sort of.
Its true that if you put your text in &lt;p&gt; tags then you get a nice result more or less for free:
```html
<p>Text in a &lt;p&gt; before an image</p>
<img src="https://placekitten.com/300/200"/>
<p>Text in a &lt;p&gt; after</p>
```
<div style="color: white; padding: 20px; background: #444;">
<p>Text in a &lt;p&gt; before an image</p>
<img style="display: inline" src="https://placekitten.com/300/200"/>
<p>Text in a &lt;p&gt; after</p>
</div>
But even here, youre dealing with the pernicious influence of the `display: block` - &lt;p&gt; tags are block elements! This might seem counter-intuitive at first because we started by describing inline elements like flowing text, and &lt;p&gt; tags are _literally for text_, but I promise it makes sense: &lt;p&gt; tags represent a paragraph, and a paragraph should fill the width of its container. (Now, the _text inside_ the &lt;p&gt; tag is inline, but thats another story . . . )
So anyways, now that weve exposed the dirty secret of &lt;p&gt; tags, what exactly are `inline-block` elements?
### Inline-Block: A Surprisingly Useful Hybrid
So it should come as no surprise to you that an element with the style rule `display: inline-block` should behave in some ways like an inline element, and in some ways like a block element. `inline-block` is useful because it allows us the control over width, height, padding, and margin that a `block` element does, but it can be used a situation where `block` doesnt work - primarily where you want your elements to come one after the other within the same line like an `inline` element.
This kind of element is commonly used for photo galleries or navigation menus like this:
```html
<a style="display: inline-block; margin: 10px; padding: 10px; border: solid 1px white; border-radius: 3px;" href="#">Home</a>
<a style="display: inline-block; margin: 10px; padding: 10px; border: solid 1px white; border-radius: 3px;" href="#">Posts</a>
<a style="display: inline-block; margin: 10px; padding: 10px; border: solid 1px white; border-radius: 3px;" href="#">Contact</a>
```
<div style="background:#444; padding: 20px; color: white;">
<a style="display: inline-block; margin: 10px; padding: 10px; border: solid 1px white; border-radius: 3px" href="#">Home</a>
<a style="display: inline-block; margin: 10px; padding: 10px; border: solid 1px white; border-radius: 3px" href="#">Posts</a>
<a style="display: inline-block; margin: 10px; padding: 10px; border: solid 1px white; border-radius: 3px" href="#">Contact</a>
</div>
There are a lot of different ways to use `inline-block` elements, and for a long time it was the preferred way to make several block elements that flowed from left to right rather than just top to bottom. Nowadays this use has largely been replaced by the new CSS flexbox and grid rules - but well have to talk about that another time!