CSS Basics and Style Guide

Intro to CSS

After you've laid down the structure with html, it's time to decorate it with CSS. What is CSS? Every HTML element has a list of visual properties that can be changed or tweaked. CSS is basically a list of rules that set the values of those properties to what we want. There are two main ways to add a style sheet to our HTML. Embedded style sheets and external style sheets.
Embedded style sheets are written right in the HTML. We just put a pair of <style>...</style tags in the head section of HTML and the CSS rules go right in between.

			<head>
				<style>
				Style rules go here
				.
				.
				</style>
			.
			.
			.
		

External style sheets are written as separate documents (.css) and linked to the HTML later. You can have multiple style sheets for the same HTML document. They'll all apply with some override if conflicts occur. There's no real formal structuring like <head> or <body> in a CSS document. Just list your rules and you're good. There are two ways to link an external style sheet.

  1. Using the <link> Element

    In the head of the document, place the following line:

    <link rel="stylesheet" href="url to stylesheet">
  2. Using @import

    Right at the beginning of the style section of the document, place the following line:

    @import url("url to stylesheet");

    You can add media queries so that different style sheets are imported depending on the device. For example the following stylesheet is used when the webpage is printed.

    @import url("url to stylesheet") print;

    See the media queries section for more options

CSS Syntax

The syntax of a CSS rule is as follows:

			selector{
				property: value;
				.
				.
				.
			}
		

The selector is basically the name of the element we want to change (so whatever word is between the < and &bgt;). Applying style rules to an element will apply them to every single instance of that element in the document. If we want to be more specific, we can use the selector to target classes or IDs; just use . or # respectively. We can even add multiple selectors - just separate them with a comma. We can use descendent selectors to target specific descendents of specific elements, just separate parent and child with a space. In the below example, only elementB elements that are children of elementA elements will be targetted by the enclosed rules. There's also the child selector which targets specific children of elements and sibling selector that targets specific elements that appear right after another element. If we want to target every child, descendent, or sibling or a specific element just use the wildcard selector (*).

The properties are whatever properties are available in the element(s) you're targeting. The values are whatever we want to change it to. Formally, each property value pair is called a declaration. Each selector can have multiple declarations to change its appearance, collectively known as a delcaration block. What if you have multiple declarations that target the same property on the same element, i.e. style conflicts? The general rule is the closer the rule is to the actual markup, the higher its priority. So an external style sheet would be overridden by an embedded style sheet which would be overridden by the element's HTML style values. Also the more specific a style rule is, the higher the priority. So an element selector would be overridden by a class selector which would be overridden by an id selector which would be overridden by the elements HTML style value.
Style inheritance is another feature of CSS. There are certain style properties that can be passed down by container elements to their child elements. For example:

This is an unstyled paragraph.

This is a styled paragraph.

Both paragraphs elements above have the word 'paragraph' within <i> elements. The first paragraph has no styles. The second paragraph element is styled with a cursive font. Noticed how the cursive style is applied to 'paragraph' even though no style was applied specifically to that element. Thats the power of inheritance! In general, styles affecting text get passed down while styles affecting borders and backgrounds don't

Units of Measurement

When designing web pages, its important to enforce how big things should be so that your users see your website as it should be, regardless of what device they use. There are two types of units: Absolute and Relative. Absolute units can be measured in real life because they always stay that size, regardless of the size of the screen. Relative units are based on the size of something else, whether its screen size or font size. The size can change depending on the state of the reference. In general we will want to use relative units of measurement to ensure our web content adapts with the user's device. Note: when inputtings units, make sure there's NO space between the unit and its value. Example.

Absolute Units

px
Pixels, defined as 1/96 of an inch. This is pretty much the only absolute unit used in web design. Others exist like in for inches and cm for centimeters but they're not as appropriate for screens

Relative Units

em
A unit based on the element's inherited font size, specifically the size of a capital 'M'. If the inherited font size is 12, then 1 em is equivalent to an 'M' in 12 size font.
rem
A unit based on the root font size (font size of the HTML element). By default, this is 16 pixels so 1 rem is equal to 16 pixels.
vw|vh
These stand for 'viewport width' and 'viewport height', respectively. They serve as percentage sizes based on the size of the viewport (browser window). For example a 100vw element would take up 100% of the viewports width.

Pseudo-Classes and Pseudo-Elements

CSS provides an additional way to select and group elements by their current state, instead of by user-defined classes, or relationships. These selectors are called pseudo-class selectors. They allow us to add additional styles based on the current state of an element; ex. whether it's been hovered over, clicked, etc. As stated earlier, the syntax for classes used '.' before the class name. For pseudo-classes, we use ':' before the pseudo-class name.

Pseudo-classes for Links

a:link
Applies a style for unclicked links
a:visited
Applies a style for clicked links

Pseudo-classes for User Actions

element:focus
Applies a style when the element is selected and is waiting for input, like a form element
element:hover
Applies a style when the element is hovered over with a mouse pointer. No effect for mobile users
element:active
Applies a style for that brief moment when an element is clicked and the mouse hasn't been released yet. Good for buttons and links.

Keep in mind the order you chain your pseudo-class styles when applying multiple for the same element. The styles applied last will override the others so if :link or :visted are applied last, then none of the others will appear. The order should be :link, :visited, :focus, :hover, then :active.
There are many other pseudoselectors, many of which target specific element relationships like :first-child and only-child. You can read more about them here

Pseudo-elements

Unlike pseudo-classes which offer group selection based on state or relationship, pseudo-elements allow you to target specific areas within the content of elements. The syntax for pseudo-elements is 'element::pseudo-element'.

element::first-line
Use to apply a style rule to the first-line of the element
element::first-letter
Use to apply a style rule to the last-line of the element
element::before
Use to add additional content before the original content of the element. Use the content property to add more text (enclosed by quotation marks) or add an image using the url(...) syntax. Add any styles you want applied to the extra content in the same declaration block.

More Attribute Selectors

We've seen the class and id selectors earlier. In reality, these were just special types of attribute selectors, selectors that target based on attribute names or values. Normal attribute selectors follow the syntax element[attribute].

element[attribute]
Apply a style to elements with the specified attribute.
element[attribute="value"]
Apply a style to elements who have the specified attribute with the exact specified value
element[attribute~="value"]
Apply a style to elements who have the specified attribute that contains the specified value as a word, separated by spaces.
element[attribute|="value"]
Apply a style to elements that have the specified attribute that has hyphen-separated values that has the specified value contained within
element[attribute^="first part of value"]
Apply a style to elements that have the specified attritube that has a value that starts with the specified value
element[attribute$="last part of value"]
Apply a style to elements that have the specified attribute that has a value that ends with the specified value
element[attribute*="any part of value"]
Apply a style to elements that have the specified attribute that has the specified value as a substring in its value

Element Boxes

When elements are placed on a page, they take up space. This is obvious with block elements but even in-line elements have their contents enclosed by boxes. Each of these element boxes is made up of the area taken up by the content, followed by any padding, the border, and then any margins. The padding is the space between the content box and the border. The margins are any space maintained between other elements as well as between the viewport edges. Margins have an interesting property called collapsing margins; when two vertically adjacent elements with margins meet, the space between them is notthe combined total of their margins; it is the largest margin between the two elements. Horizontal margins never collapse. In this section we'll look at ways to play around with element boxes.

Changing The Size of the Element Box

width
Values:rem,em,%,auto
Used to change the width of the content box of the element, unless chnaged by the box-sizing property. By default, this is set to auto which means elements are as wide as the block element that contains it.
height
Values:rem,em,%,auto
Used to change the height of the content box of the element, unless changed by the box-sizing property. By default this is set to auto which means the box is just tall enough to fit the content.
box-sizing
Values:content-box,border-box
Changes whether width and height properties are applied to the content-box (default) or the border-box. "Content-box" means that any sizes you set for the width and height are only applied to the content-box. Any padding and margin sizes get slapped on top of that, so you might end up with something larger than expected. Changing it to "border-box" means the entire element (including margins and padding) will be the size you specify.
overflow
Values:visible,hidden,scroll,auto
Used to change how elements are displayed when the content is much larger than its box. By default, this is set to "visible", which means the extra content protrudes out of the box. "Hidden" clips off any extra content. "Scroll" adds a scroll bar to the box to view the extra content. "Auto" leaves the choice up to the browser.
padding
Values:rem,em,%
Adds padding to the element box. Takes up to 4 values (not comma separated), one for each of the sides. Order of the values changes top right bottom left padding in that order. Percentage units are relative to the width of the parent element, even for top and bottom paddding. Default value is 0 padding.
border-style
Values:none,solid,dotted,dashed,double,groove,ridge,inset,outset
Changes the border style of the element. Takes up to 4 values (not comma separated), one for each side. Order fo the values is top right bottom left border, in that order. Default value is none.
border-width
Values:px,rem,em,thin,medium,thick
Changes the thickness of the border. Takes up to 4 values (not comma separated), one for each side. Order of the values is top right bottom left border, in that order. Default value is medium thickness.
<
border-color
Values:colorname,RGB,HSL,transparent
Changes the color of the border. Takes up to 4 values (not comma separated), one for each side. Order of the values is top right bottom left border, in that order. Default value is whatever the color property is set to.
border-radius
Values:px,rem,em,%
Used to create rounded border corners. Values can be specified for each corner (not comma separated), starting with the top-left corner and moving clockwise. Each corner can have one value for smooth, even, circular corners or they can have two values (horizontal and vertical radii, separated with a /) for interesting uneven elliptical corners.
margin
Values:px,rem,em,%,auto
Used to change the margins of the element box. Takes up to 4 values (not comma separated), one for each side. Order of the values is top right bottom left margin. Percentage units are relative to the width of the parent element, even for top and bottom paddding. Negative units cause neighbouring elements to overlap with the current one. Default value is "auto" which means the browser uses enough margin to fill any available space. Non-replaced inline elements like a only have left and right margins.
display
Values:inline,block,run-in,flex,flow,list-item,table,ruby,inline-block,inline-grid,contents,none
Used to specify how elements behave in layouts. Default is "inline" but you can make items behave as though they're table items or list items. This is useful for changing the look of things without messing with the markup. The "none" value not only turns the element invisible, it removes it entirely and the space it filled is taken up by the other elements. This is useful for hiding elements from certain display types like the print view. Note that elements hidden in this way are still downloaded so this does nothing to save data.
box-shadow
Values:inset,px,rem,em,colour
Adds a shadow around the element box (excluding margin). The "inset" value is a toggle that enables shadows inside the box area and makes the box look like its sunken in rather than popping out; normally it is outside. There are four possible measurement values. The first two are mandatory: horizontal offset and vertical offset. The horizontal offset dictates how far to the right the shadow should be, relative to the box. The vertical offset dictates how far down the shadow should move, relative to the box. The third optional measurement is for the blur radius; the larger the blur radius, the softer the shadow becomes. The fourth optional measurement is for spread; the larger the spread, the bigger the shadow.The last value of this property is the colour of the shadow. If no colour is specified, it is the same as the element foreground (text and border). You can have multiple box shadows on the same element; just separate the sets with commas. They all get drawn on top of one another.

Font Properties

font-family
Use the font-family to specify a comma-separated list of fonts for that element. The browser will go in order from left-to-right until it finds a font it can render on the screen. For the most part, all font names must capitalized with the exception of generic ones (monospace, serif, sans-serif, cursive, fantasy). Fonts that have names that are more than one word require quotation marks. In general, your font stack should start with your first choice, followed by similar looking alternatives, and then end off with the closest generic font.
Click here for a list of font-families to choose from.
font-size
Values:rem,em,%
Sets the size of the element's font. You can use the units mentioned earlier or percentage units. If you put a percentage, it scales the font up or down based on it's inherited font value. Its common practice to set the font-size of the html element to 100% (equal to 16px for all modern browsers) so we have a clear base going forward with the font-sizes of other elements.
font-weight
Values:normal,bold,bolder,lighter,100,200,300,...,900
Used to set how bold the font is. There are a lot of values but for the most part just stick with bold. You can also use normal to 'un-bold' things that normally appear bold like headlines.
font-style
Values:normal,italic,oblique
Used to set the font italic. Use normal to make un-slant things that are normally in italics like em.
font-variant
Values:normal,small-caps
Changes the font to use capital letters in place of lowercase letters. Good for times and units and maybe acronyms and abbreviations.
font-stretch
Values:normal,ultra-condensed,condensed,semi-condensed,semi-expanded,expanded,extra-expanded,ultra-expanded,
Changes the font-family to its normal|condensed|expanded version. If the browser can't find one, it'll switch out the font-family with a different one.
color
Values: black,white,purple,lime,navy,aqua,silver,maroon,fuchsia,olive,blue,orange,gray,red,green,yellow,teal,#RGB
Changes the color of foreground elements: font and border. You can use predefined color names like black, red, or purple or RGB numbers.
font
Values: style weight stretch variant size/line-height font-family
Shorthand property that merges all the above properties into one. Property values must be typed in the order as seen in the values. Omitting any value means its default value is used instead. Saves space but easier to keep track if you specify all the properties individually.

Line Styles

line-height
Values: rem,em,%,#,normal
Used to set the line height which is the space between baselines (the imaginary line where the letters sit). The line height is based on the current font size of the element. Units include your basic rem, em and % but also numerical values. When you use just a number, it acts a multipler (so '2' would mean a line-height that is 2x the current font size). It is important to note the difference in terms of inheritance. When you use a number multiplier, its descendents also inherit the multiplier. This means a descendent paragraph with a font size of 8px would have a line-height of 16px. However, when you use em, the descendents inherit the ancestor's calculated size. For example, lets say we have a body element with a line-height of 1em. Assuming default font size, this means the body element and all its descendents will have a line-height of 16px. This could be bad if we have elements like a 24px headline.
text-indent
values:rem,em,%
Used to set indent length. Percentage values are based on the length of the whole line. All relative units are passed down to descendents as relative not calculated so you won't see the same problem as line-heights You can use negative values to generate an overhang as opposed to an indent.
text-align
Values:left,right,center,justify,start,end
Adjust the position of the text within its block. Pretty straightforward.
text-decoration
Values:none,underline,overline,line-through
Adds special decoration to the element text.
text-transform
Values:none,capitalize,lowercase,uppercase
Transforms the element's text. Capitalize changes the first letter of every word in the element to a capital, whereas uppercase changes every letter to a capital
letter-spacing
Values:rem,em,%,normal
Adds space between letters. If you use em, descendents will inherit the calculated value, not the relative value so be careful.
word-spacing
Values:rem,em,%,normal
Adds space between words. Like letter-spacing if you use em, descendents will inherit the calculated value, not the relative value.
text-shadow
Values:rem,em,none
Creates a shadow behind the letters. There are three measurement values. The first two are mandatory: horizontal offset and vertical offset. The horizontal offset dictates how far to the right the shadow should be, relative to the actual letters. The vertical offset dictates how far down the shadow should move, relative to the letters. The third optional measurement is for the blur radius; the larger the blur radius, the softer the shadow becomes. The fourth and last value of this property is the colour of the shadow.
list-style-type
Values:none,disk,circle,square,decimal,decimal-leading-zero,lower-alpha,upper-alpha,lower-latin,upper-latin,lower-roman,upper,roman,lower-greek
Applies only to list elements. Changes the marker used to mark each item in the list. Use 'none' to remove the markers entirely.
list-style-position
Values:inside,outside,hanging
Applies only to list elements. Changes the position of the bullet, relative to the list item's box. Inside means inside the box. Outside means outside the box without touching it. Hanging is like inside with the markers just hanging on the outside edge of the box.
list-style-image
Values:url(),none
Applies only to list elements. Use a specified image instead of conventional markers to separate list items. Use this property in conjunction with list-style-type in-case the image doesn't load.

Colour

There are a set 140 colours that all browsers can recognize the name of and render onto the screen (You can see the full list here). However, there are alot more colour options to pick from if we use RGB values (255 values in each channel = 16.7 million colours!). You can use Google's colorpicker to find the RGB values of your desired colour. To use RGB, we can just type in the values for each channel as shown below:

color: rgb(97,201,201);

We can also use hexadecimal values. The hex value below produces the same colour as the decimal value above.

color: #61c9c9;

RGBa

The 'a' in RGBa stands for alpha. Essentially, it adds a fourth channel to RGB but this channel affects the colour's transparency rather than its hue.

color: rgba(97,201,201,.1);

The alpha value ranges from 0 to 1, with 0 being completely transparent and 1 being completely visible.

HSL and HSLa

Besides colour names and RGB values, there is a third way to define colours: HSL. HSL stands for Hue Saturation Luminosity. Imagine a circle with all the colours of the rainbow spread out as a gradient with red at the very top. The angles of each colour, with red being at the 0/360o position, correspond to the hue value. Saturation and luminosity are both percentage values. Saturation affects how much of that hue is rendered (0% means gray). Luminosity affects how light or dark you want to make that hue (100% gives you white, 0% gives you black). The following CSS shows the HSL equivalent of the examples above.

color: hsl(180,49%,58%);

Like with RGBa, HSLa adds a fourth channel for transparency, with 0 being completely transparent and 1 being completely visible.

Background Colour

When applying colour to elements, it gets applied to the foreground elements: the text as well as any defined border. If we want to change the colour of the background, we need to use another property: background-color.

background-color
Values:colour name,RGB,HSL
Applies a colour to the background of the element, which by default extends right to the outer edge of the border.
background-clip
Values:border-box,padding-box,content-box
Changes the area that the background covers. Default is border-box which extends the background to the outer edge of the border. Padding-box stops the background right before the border. Content-box limits the background to just around the content.

Opacity

opacity
Values:number between 0 and 1
Changes the transparency of the entire element, foreground and background.

Background Images

background-image
Values:url(...)
Uses an image source as the background for the element. Note: the URL is relative to the location of the CSS rule (so its external sheet location or the HTML file location). The behaviour is that the image starts in the top-left corner (right before the border) and repeats itself horizontally, then vertically, until the whole element box is filled. If you combine this with back-ground colour, the image goes on top of the colour. It's recommended you do so that if the image doesn't work, there's still a background colour to cover for it.
background-repeat
Values:repeat,no-repeat,repeat-x,repeat-y,space,round
Specifies how the background image repeats itself. Repeat is the default. No-repeat means the image shows only once. Repeat-x or Repeat-y means the image only repeats itself in the x or y direction. The space value is used to ensure that no clipping occurs when repeating; the browser calculates how many whole images can fit in the element, then adds space between them to fill out any gaps. The round value also prevents clipping but by changing the dimensions so that the image fits an even amount of times in the background.
background-position
Values:rem,em,%,left,center,right,top,bottom
Changes the position of where the image is first placed. Use rem or em to indicate offsets from the top-left corner. Or percentages are used in pairs to indicate horizontal and vertical offset (in that order) from the top left corner: 0% 0% for the top-left corner, 100% 100% for the bottom-right corner. As a final alternative, you can use the directional keywords to move your origin image around: 'left top' is the default but you could move it 'right bottom'. If you only specify one 'direction' like just 'right'. then the browser automatically assumes that the image should also be 'center'.
background-origin
Values:border-box,padding-box,content-box
As stated earlier, background images by default do not intersect the border area; this is the default value of padding-box. We can use background-origin to change this behaviour. If we change it to border-box, the origin image will go right to the outer edge of the border. If we change it to content-box, then the origin image will start within the content area (where the text is).
background-attachment
Values:scroll,fixed,local
Changes how the background image scrolls. The default value is scroll; the background image scrolls with the content. If we specify it to be fixed, then the background image stays put while the content scrolls over it. The local value is used when the element the background image is attached to has its own scroller; it ties the scrolling to the element's scroller and not the browsers'.
background-size
Values:px,rem,em,%,auto,cover,contain
Changes the size of the image used for the background. Two values are needed, one for each dimension. If only one is specified, it is assumed to be horizontal dimension and the vertical dimension is set to 'auto'. What auto does is it resizes in whatever direction is necessary to maintain the proportion of the image. Percentage values are based on the size of background positioning area, which itself is based on the value set in the background-origin property. The cover keyword resizes the image so that one copy covers the entire background positioning area. The contain keyword resizes the image either horizontally or vertically until it fits the background positioning area completely in that one dimension. If there is any leftover space, then the image repeats itself.

Multiple background Images

You can add multiple background images by simply separating each image url with commas in the background-image property. Images "stack" on top of one another, with the first url's image on top, the next image under that, and so on. To use the other properties with each image separately, just separate the values with commas, in the same order as the images are stacked from top to bottom.

Gradients

You can add color gradients to your backgrounds as well. Even though no image is provided they still get treated as background-images and can be used anywhere a background-image property can be used.

background-image:linear-gradient(...)
Values:angle,startcolour,....,endcolour
Generates a linear gradient with the background-image property. At least three values are needed in the brackets as shown below.
background-image:linear-gradient(180deg, green, blue 40%, red)
The first is the angle, specified by #deg. A value of 0deg means the gradient goes from bottom to top. Positive angles turn gradient clockwise so at 90deg, the gradient goes from left to right. There are also keywords you can use although these restrict the angle to 45 degree increments (to top, to right, to left, to bottom, to top right, to top left, to bottom right, to bottom left).
The next values must be at least two colours, the start and end colours respectively, with as many of the colours you want in between. You can set colour stops by adding percentages after the colours; these tell the browser where along the gradient these colours should appear. In the example above, the colour blue is set to appear at 40% of the gradient. By default the start and end colours appear at 0% and 100% respecitvely. If a colour stop is specified for the start colour, then the gradient will be filled with just the start colour up until that stop point. If a colour stop is used for the end colour, then the gradient will be filled with that last colour from the stop point all the way to the end.
background-image:radial-gradient(...)
Creates a gradient that by default, radiates from the center of the element. This generates a circle if the element is square or an ellipse of the element is rectangular. Two colours at least are required for the start and end colours. You can change the shape by specifying either 'circle' or 'ellipse' or by supplying horizontal and vertical dimensions. You can change where teh gradiant begins by using the same keywords for the background-position property.

Floating Elements

Floating an element means pushing it off to the side and allowing other elements to flow or wrap around it. This can be useful for saving space and can also make your overall layout look nicer. There are some key things to note about floated objects:

float
Value:left,right,none
Used to float an element to the left or right of its containing element.
clear
Value:left,right,both,none
Used to stop an element from wrapping around a floated one and have it start at the next available space below it. The values 'left' and 'right' stop the element from wrapping around elements floated on the left or right respectively. The 'both' value prevents the element from wrapping around any floated element.

Text Wrapping

When text wraps around floated objects, they always wrap in a straight line, forming a rectangle around the floated element. This is fine if the floated element is also text but its not as nice for images. To make it comform to the outline of the image we use the shape-outside property.

shape-outside
Values:none,circle(..),ellipse(..),polygon(..),url(..)
Use to help text wrap around images better. The circle value takes in a radius. The ellipse value uses the notation "rx ry at x% y%". The rx is the horizontal radius, ry is the vertical radius, x% is the horizontal position of the ellipse center and y% is the vertical position of the ellipse center. The polygon value takes in a bunch of x,y coordinates separated by commas. The top left corner of the image is 0px 0px and the bottom right corner's coordinates would be equivalent to whatever dimensions your image is in. Finally, the url value can take in the url of an image that has transparent areas. The text will automatically flow into the transparent areas and stop when it hits coloured ones. Note: the shape-outside property allows text to flow into a floated element but it cannot push the text away further than it normally does; use shape-margin for that.
shape-margin
Values:px,rem,em,%
Creates a margin between the text and the outline specified by shape-outside.

Positioning Elements

Aside from floating, we can move elements around the page using the position property. Like floating, elements positioned this way behave like block elements. Unlike floating, positioned elements can overlap other elements, including other positioned elements.

position
Value:static,relative,absolute,fixed
Used to specify how an object is to be positioned. Static is the default and is how elements normally arrange themselves. Relative moves the element box relative to its original position, while keeping its original position as empty space. Absolute moves element box relative to its containing block(more on this later) and closes up its original position. Fixed moves the element relative to the viewport and makes it stay there, even through scrolling. Fixed objects also have their original position closed up.
top|right|bottom|left
Values:px,rem,em,%,auto
Offset properties used to provide the location for repositioning, based on the positioning format and point of reference specified by the position property. The values for each of the four properties do not correspond to the actual coordinates but rather how far to move away from the corresponding edge; positive values move the element away from that edge, negative values move it closer. It is important to note that by setting offsets on each of the sides, you may end up accidentally changing the dimensions of your positioned element if its containing block is too small. In order words, the size of the positioned element and its offsets has to be less than or equal to the size of its containing block.

Containing Blocks

Absolute positioning is based on the element's containing block. This is not always its parent! Here's how we determine the containing block:

An easy way to turn an element's ancestor into its containing block without having to make the ancestor around is to just assign it the style position: relative

Stacking Positioned elements

z-index
Values:#|auto
Used for positioned elements to change the stacking order. The smaller the z-index, the lower in the stack the element will display. Z-index values do not have to be in order and can be any arbitrary number.

Flexboxes

Another CSS tool for configuring layouts. To create a flexbox, simply set the container element's display property to 'flex'. When you designate a container element to be a flexbox, you gain the ability to manipulate all of its direct child elements, which have now become flex items. The flex items are then laid out along a flex line which is basically a vertical or horizontal axis on the page. By default, the direction the flex items are laid out will correspond to the document's language: left-to-right for English. You can create nested flexboxes by turning the flex items into flexboxes.

Flexbox Properties

flex-direction
Values:row,column,row-reverse,column-reverse
Changes the way flex-items get aligned in the flexbox. Default is 'row'. Whatever is set here is the main-axis and the cross-axis becomes whatever is perpendicular to the main-axis.
flex-wrap
Values:nowrap,wrap,wrap-reverse
Changes how flex items wrap in the flex box. Default is nowrap, which means flex items squish as much as they can and try to fit. 'Wrap' allows the flex-items to flow onto multiple lines in the same flex-direction, from start of the container to end. 'Wrap-reverse' also allows wrapping across multiple lines but in the oppositeflex-direction (right to left), from the end of the container to the beginning. If the flex-direction is set to 'column' or'column-reverse', the container will expand to accomadate the content unless a height is specified. for the container
justify-content
Values: flex-start,flex-end,center,space-between,space-around
Defines how any extra space should be handled along the main axis. The default is 'Flex-start' which means all the flex-items line up without space at the start of box. 'Flex-end' lines them all without space at the end of box. 'Center' centers the flex-items without space in the middle of the box. 'Space-between' puts the first flex item at the beginning, the last flex item at the end and organizes the remaining flex items so that there is an equal distance between every flex item. 'Space-around' is similar to 'space-between' except the there is space around the first and last elements as well.
align-items
Values:flex-start,flex-end,center,baseline,stretch
Defines how items are arranged along the cross axis. Note: A container height must be set first: otherwise the container just automatically resizes to fit the content meaning there's no point in this property. The default is stretch meaning if there's any space along the cross axis of the container , the items will be stretched to fill that space. 'Flex-start' aligns the items at the start of the cross-axis. 'Flex-end' aligns the items at the end of the cross-axis. 'Center' aligns the items in the middle of the cross axis. Baseline aligns each flex-item individually such that the baselines of the text in each item all line up; this becomes apparent when the font size of the items differ.
align-content
Values:flex-start,flex,end,center,space-around,space-between,stretch
Defines how you'd like multiple lines of flex items to appear in the flexbox. Note: multiple lines of flex items is only possible if some type of wrapping is specified with the flex-wrap property.

Flex Item Properties

align-self
Valuesflex-start,flex-end,center,baseline,stretch:
Same as align-items but for individual flex items. Will override whatever is set in align-items. If you want to align individual flex items along the main-axis, try using margins to add space between it and the other flex items.
flex
Values:none,0,#,auto
Defines how the flex item "flexes". There are up to three values that can be entered, without comma separation. The first two values can be 0 or 1 and act as toggles to control whether the item can grow or shrink. 0 means no, 1 mean yes. If you want some items to grow larger than the others, give that item a grow value larger than 1 and it will grow that much more, proportionally. For example, an item with a grow value of 2 gets twice as much space as items with 1. The same principle works for the shrink value; a larger shrink value means the item shrinks that much more, prorportionally. The third value is the size of the flex item using measurement units. By default, the values are 0,1,auto meaning flex items can't grow but they can shrink and their base size is kept to whatever's specified in width and height.
order
Values:#
Defines the order the flex item appears in the flex-line. The default value is 0. The lower the order value, the closer they are to the beginning of the flex line. Items with the same flex value will appear in the order that they are in the HTML.

Grid Layouts

The final tool for configuring page layouts. While flexboxes are good for handling elements along one axis, gris can position objects into both rows and columns. Just like flexboxes, to turn an element into a grid, we just change its display property to 'grid'. There are some special terms to be familiar with when it comes to grids. Grid tracks are basically the rows and columns of the grid. Grid lines are the lines of the grid that separate the grid tracks, as you can see in the figure below.

Grid line numbering system

The numbers are positive when going from left to right and top to bottom. We can use these numbers to quickly refer to specific points in the grid layout. The lines are also labelled negatively as well from bottom to top and right to left. This allows us to refer to the end lines, without having to count how many lines there are (just use -1). Finally, grid cells refer to the individual sections of the grid once it has been divided up by the grid lines.

Setting up the Grid

grid-template-rows
Values:px,rem,em,fr,minmax(),auto,min-content,max-content
A list of heights for each of the rows starting from the top, not comma separated. The fr unit allows the associated row to expand or contract according to any leftover space. If used with fixed heights, the fr row will take up all the extra space in the window. If used with other fr rows, the amount of space they take up will depend on the fr value; larger fr values will take up proportionally that much more space when compared to smaller fr values. The minmax() unit specifies a minimum and maximum height for the row, comma separated. The amounts of heights you feed into this property correlates to how many rows your grid will have. Aside from the automatic numbering system, naming your rows provides the option to refer to them by name later on. You can name your rows by providing the name in [] before each height. If a row line should have multiple names(for example its the start of one section and the end of another), then you can assign multiple names by separating them with spaces in the brackets.
grid-template-columns
Values:px,rem,em,fr,minmax(),auto,min-content,max-content
A list of widths for each of the columns starting from the left, not comma separated. The amount of widths you feed into this property correlates to how many columns your grid will have. Naming your columns provides the option of referring to them by name late ron. You can name your columns by providing the name in [] before each width. If a column line should have multiple names (for example its the start of one section and the end of another), you can assign multiple names by separating them with spaces in the brackets.
grid-template-areas
Values:none,names of areas
Used to provide names to distinct areas on the grid, allowing you to target those areas specifically later. Areas are comprised of at least one or more cells that are adjacent to eachother. All cells must be named if any are named, and they are named from left to right,not comma separated, row by row. For example, a 3x3 grid could be named using the following property values.
grid-template-areas:
	"header header header"
	"ads main links"
	"footer footer footer";
An added feature of grid names is that they automatically name the associated grid-lines as well using the following convention: 'areaname-start', 'areaname-end'.
grid-row-gap|grid-column-gap
Values:px,rem,em
Adds space only between the tracks of the grid. If you want to add space to the outside edges of the grid, use padding.
justify-content|align content
Values:start,end,left,right,center,stretch,space-around,space-between,space-evenly
Used to position the grid tracks in the grid container in the case that the grid tracks do not fill up the grid container (i.e.explicit widths and heights are specified both the tracks and the container). Note that if you use 'space-around' and 'space-between', the space is additive with any grid-row-gap or grid-column-gap values.

Populating the grid

grid-row-start|grid-row-end|grid-column-start|grid-column-end
Values:line#,line name,span#
Putting these properties on a grid item tells it where it will be on the grid by using its bordering grid lines. Each property takes one value:the grid line reference. You can refer to the lines using the line number or its line name. You can also just provide a start line for the end, just tell it to span a certain number of rows or columns.
grid-area
Values:area name
Tells a grid item where to go using an area name. In my opinion, this is the easiest way to place grid items around your layout. An added benefit of area names is that even if you use a different grid, as long as the areas have the same name the items will go to their rightful place.
grid-auto-flow
Values:row,column,dense
Changes how grid items populate the grid if they're not explicitly placed. 'Row' means they flow in row by row. 'Column' means they flow in column by column. By default, the flow matches whichever direction the language is in. Here's an analogy as to how the items flow in. Imagine a pointer on the first cell of the grid. If the cell is large enough, the grid item is placed inside and the pointer moves on to the next cell. If the cell is not large enough, the pointer still moves on to the next cell; there is no backtracking. Adding the optional 'dense' keyword in front means that with every item that needs to get placed, the pointer moves all the way back to the start; i.e. we can fill in cells that were previously skipped for being too small. This can have the side-effect of items appearing out of the HTML defined order on your grid.
justify-self|align-self|justify-items|align-items
Values:start,end,center,left,right,self-start,self-end,stretch,normal,auto
Specify how grid-items are positioned in their cell / grid area if there is excess space. 'Justify' affects horizontal alignment while 'align' affects vertical alignment. Justify-items and align-items are used to apply positioning to every grid-item at once.