{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "206258a5",
   "metadata": {},
   "source": [
    "# CSS\n",
    "**CSS** or **Cascading Style Sheets** is a language used for styling and formatting HTML documents. It helps to separate the presentation layer from the content layer, allowing us to apply consistent styles across multiple pages or an entire website.\n",
    "\n",
    "CSS Reference: [Mozilla Docs](https://developer.mozilla.org/en-US/docs/Web/CSS)\n",
    "\n",
    "### Cascading\n",
    "**Cascading** refers to the **order** in which stylesheets are applied. In general, there are three types of stylesheets that can be applied to an HTML document:\n",
    "\n",
    "* **User Agent Stylesheets**: These are the default styles applied by the browser, such as font size and spacing. They have the lowest level of precedence, meaning any styles applied by the other two types of stylesheets will override them.\n",
    "\n",
    "* **User Stylesheets**: These are styles that are applied based on user preferences, such as a user's chosen font size or color scheme. These stylesheets have a higher level of precedence than user agent stylesheets, but lower than author stylesheets.\n",
    "\n",
    "* **Author Stylesheets**: These are the styles that we write ourselves, using CSS. They have the highest level of precedence, but this can be overridden by using the `!important` declaration.\n",
    "\n",
    "### Declaration\n",
    "A **declaration** is a CSS **property-value pair** in the form `property: value;`. Properties are the attributes that we want to apply styles to, such as `font-size` or `color`. Values are the specific values that we want to apply to the properties, such as `16px` or `#000000`. For example: `font-size: 16px;`\n",
    "\n",
    "### Declaration Block\n",
    "A declaration block is a **group of declarations** surrounded by curly braces `{}`. This is how we group together multiple declarations that we want to apply to a particular element.\n",
    "```css\n",
    "{\n",
    "color: blue;\n",
    "margin: 10px;\n",
    "}\n",
    "```\n",
    "This would apply a blue color and a 10 pixel margin to the element that it is applied to.\n",
    "\n",
    "\n",
    "### Ruleset\n",
    "A **ruleset** is a **selector** followed by a **declaration block**. The selector determines which elements on the page the ruleset will apply to, while the declaration block lists the styles that will be applied to those elements.\n",
    "```css\n",
    "selector {\n",
    "property: value;\n",
    "property: value;\n",
    "}\n",
    "\n",
    "h1 {\n",
    "  color: red;\n",
    "  font-size: 24px;\n",
    "}\n",
    "\n",
    "```\n",
    "This would apply a red color and a font size of 24 pixels to all h1 elements on the page.\n",
    "\n",
    "\n",
    "### `link`\n",
    "\n",
    "The `<link>` tag is used in HTML to link external resources, such as stylesheets. The `<link>` tag is a self-closing tag and has two attributes that are required when linking to a stylesheet:\n",
    "\n",
    "* **rel**: This attribute specifies the relationship between the current document and the linked document. When linking to a stylesheet, this should be set to **stylesheet**.\n",
    "\n",
    "* **href**: This attribute specifies the location of the linked document. It can be either an absolute or relative URL.\n",
    "\n",
    "For example:\n",
    "```css\n",
    "<head>\n",
    "  <link rel=\"stylesheet\" href=\"styles.css\">\n",
    "</head>\n",
    "```\n",
    "This would link to a stylesheet named `styles.css` located in the same directory as the HTML document."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "33aaed8d",
   "metadata": {},
   "source": [
    "### Selector\n",
    "It is a pattern used at the beginning of a **ruleset** for choosing which elements will be affected by the declarations. There are a variety of different selector types:\n",
    "\n",
    "* **Type selector**: Selects all of the elements of a specific HTML tag. For example, `h1` would select all `<h1>` elements.\n",
    "\n",
    "\n",
    "* **Class selector**: Selects all elements with a specific HTML **class** attribute. Class selectors are prefixed with a `.`, so for example `.foo` would select all HTML elements with the attribute `class=\"foo\"`.\n",
    "\n",
    "\n",
    "* **ID selector**: Selects an element with a specific HTML **ID** attribute. ID selectors are prefixed with a `#`, so for example `#bar` would select the HTML element with the attribute `id=\"bar\"`\n",
    "\n",
    "\n",
    "* **Attribute selector**. Selects all elements with a specific HTML attribute set to a **specific value**. These are surrounded by `[]` and use a `=` as a delimiter between the attribute name and value. For example, `[type=\"submit\"]` would select all elements with a type attribute set to \"submit\". Also, excluding the value will select all elements with the attribute set to any value. For example, `[type]` would select all elements with the type attribute set, regardless of the value.\n",
    "\n",
    "Attribute selectors can also use special syntax for basic pattern matching within the value. There are a variety of options here, but these are some of the more common ones:\n",
    "\n",
    "* The `[attribute*=value]` selector matches any element with an attribute that contains the specified value. For example, `[href*=\"google\"]` would match any element with an href attribute that contains the string `\"google\"` at any location.\n",
    "\n",
    "\n",
    "* The `[attribute^=value]` selector matches any element with an attribute that starts with the specified value. For example, `[href^=\"https://\"]` would match any element with an href attribute that starts with `\"https://\"`.\n",
    "\n",
    "\n",
    "* The `[attribute$=value]` selector matches any element with an attribute that ends with the specified value. For example, `[href$=\".pdf\"]` would match any element with an href attribute that ends with `\".pdf\"`.\n",
    "\n",
    "\n",
    "* The `[attribute~=value]` selector matches any element with an attribute that contains the specified word. For example, `[class~=\"button\"]` would match any element with a class attribute that contains the word `\"button\"`.\n",
    "\n",
    "\n",
    "* The `[attribute|=value]` selector matches any element with an attribute that has a hyphen-separated value that starts with the specified value. For example, `[lang|=\"en\"]` would match any element with a lang attribute that has a value of `\"en\"` or `\"en-us\"` or `\"en-gb\"`, etc.\n",
    "\n",
    "Attribute selectors can be very powerful when used correctly, and they can help us select specific elements with complex attribute values. However, it's important to use them sparingly and to avoid selecting elements based on non-semantic attributes (such as `id` or `data-*` attributes used for scripting) as it can make our code harder to maintain and less semantically meaningful."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "69c6c239",
   "metadata": {},
   "source": [
    "### Combinator\n",
    "Combinator combines multiple selectors to select elements based on their location in the DOM. There are a few types of combinators:\n",
    "\n",
    "* **Descendant combinator**: Represented by a single space, in the format `selector1 selector2`. Selects all elements that match `selector2` and are a descendant of an element matching `selector1`. A descendant does not need to be a direct child (e.g. the selected element's grandparent could match `selector1`).\n",
    "\n",
    "\n",
    "* **Child combinator**: Represented by `>`, in the format `selector1 > selector2`. Selects all elements that match `selector2` and are a direct child of an element matching `selector1`.\n",
    "\n",
    "\n",
    "* **Sibling combinator**: Represented by `~`, in the format `selector1 ~ selector2`. Selects all elements that match `selector2` and are a sibling of an element matching `selector 1`. The element matching `selector2` must come after the element matching `selector1`.\n",
    "\n",
    "\n",
    "* **Adjacent sibling combinator**: Represented by `+`, in the format `selector1 + selector2`. Selects all elements that match `selector2` and have an element matching `selector1` directly before them in the DOM.\n",
    "\n",
    "To illustrate combinators, let's consider the following HTML structure:\n",
    "```html\n",
    "<div class=\"container\">\n",
    "  <h1>Title</h1>\n",
    "  <p>Paragraph 1</p>\n",
    "  <p>Paragraph 2</p>\n",
    "  <ul>\n",
    "    <li>List item 1</li>\n",
    "    <li>List item 2</li>\n",
    "  </ul>\n",
    "</div>\n",
    "```\n",
    "\n",
    "The **descendant combinator** allows us to select all `p` elements that are descendants of the `di`v element with class `container`. We can write the following selector:\n",
    "```css\n",
    ".container p {\n",
    "  color: red;\n",
    "}\n",
    "```\n",
    "This will set the color of all `p` elements inside the `div` with class `container` to red.\n",
    "\n",
    "\n",
    "The **child combinator** allows us to select all `li` elements that are direct children of the `ul` element inside the div with class `container`. We can write the following selector:\n",
    "```css\n",
    ".container > ul > li {\n",
    "  font-weight: bold;\n",
    "}\n",
    "```\n",
    "This will set the font weight of all `li` elements that are direct children of the `ul` element inside the div with class `container` to bold.\n",
    "\n",
    "\n",
    "The **sibling combinator** allows us to select all `p` elements that are siblings of the `h1` element inside the div with class `container`. We can write the following selector:\n",
    "```css\n",
    ".container h1 ~ p {\n",
    "  font-style: italic;\n",
    "}\n",
    "```\n",
    "This will set the font style of all `p` elements that are siblings of the `h1` element inside the div with class `container` to italic.\n",
    "\n",
    "\n",
    "The **adjacent sibling combinator** allows us to select the `p` element that immediately follows the `h1` element inside the div with class `container`. We can write the following selector:\n",
    "```css\n",
    ".container h1 + p {\n",
    "  text-transform: uppercase;\n",
    "}\n",
    "```\n",
    "This will set the text transform of the `p` element that immediately follows the `h1` element inside the div with class `container` to uppercase."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "da5e364c",
   "metadata": {},
   "source": [
    "### Pseudo Class\n",
    "It is an addition to a CSS selector for selecting based on the **current state** of the element. These start with `:`, so for example `button:hover` would select buttons currently hovered over.\n",
    "\n",
    "### Pseudo Element\n",
    "It is an addition to a CSS selector for selecting a **specific portion** of the element. These start with `::`, so for example `p::first-letter` would select the first letter of paragraphs.\n",
    "\n",
    "`::before` and `::after` are special pseudo elements that **insert children before or after the content** of the element, allowing for styling before or after the content. This is oftentimes used with CSS `content` property, but not always.\n",
    "\n",
    "### Specificity\n",
    "It is the algorithm used by the browser to determine which CSS declarations to use when an element is selected by two rulesets with the same property.\n",
    "\n",
    "**Specificity** is roughly calculated by counting the number of each selector type involved in a selector and multiplying by a weight. These weights are as follows:\n",
    "* **Inline Styles**: 1000\n",
    "* **IDs**: 100\n",
    "* **Classes**: 10\n",
    "* **Pseudo-Classes**: 10\n",
    "* **Attributes**: 10\n",
    "* **Elements**: 1\n",
    "* **Pseudo-Elements**: 1\n",
    "\n",
    "### Absolute Unit\n",
    " A unit whose value is **not dependent** on something else, so its size will be constant regardless of the context. In general, the `px` unit is the only one of these used on the web.\n",
    "    \n",
    "\n",
    "### Relative Unit\n",
    " A unit whose value is **dependent** on something else. These are the most frequently used relative units:\n",
    "* **em**: Relative to the font size. For example, if the font size is `14px`, then `1.5em` would be `21px`. If the `em` unit is used to set font size, it will be relative to the parent's font size.\n",
    "\n",
    "\n",
    "* **rem**: Relative to the root element's font size. By default, this is usually `16px`, but it can be overridden by the user stylesheet. Moreover, the author stylesheets can change this by setting a font size on the html selector or the `:root` pseudo class. For example, by default `1.5rem` will be `24px`.\n",
    "\n",
    "\n",
    "* **%**: A percentage, usually of the parents value for the same property. For example, a width of `50%` would be half the size of the parent element's width.\n",
    "\n",
    "\n",
    "* **vw**: A percentage of the width of the viewport, for example `50vw` would be half of the width of the viewport.\n",
    "\n",
    "\n",
    "* **vh**: A percentage of the height of the viewport, for example `50vh` would be half of the height of the viewport.\n",
    "\n",
    "\n",
    "* **ch**: The number of characters on a line, based on the width of the \"0\" character in the element's font, not the number of characters on a line. This means that the width of `1ch` will vary depending on the font being used. This can be useful to prevent paragraphs from spanning more than ~70 characters in width, which can become hard to read. \n",
    "\n",
    "### Block Element\n",
    "An element with its `display` property set to `block` . These have a few key properties:\n",
    "* They start on new lines.\n",
    "* By default they span the entire width of their parent. This means that they create a \"block\" of content that forces other elements to be placed below them. \n",
    "* Block elements are commonly used for structural elements like headings, paragraphs, and lists.\n",
    "\n",
    "### Inline Element\n",
    "An element with its `display` property set to `inline` . These have a few key properties:\n",
    "* They do not start on a new line instead start immediately after the content before them.\n",
    "* They span the width of their content. This means that they \"flow\" alongside other inline elements and can be nested within block-level elements.\n",
    "* `width` and `height` properties have no effect on them.\n",
    "* Inline elements are commonly used for elements like links, emphasized text, and images.\n",
    "\n",
    "### Inline-Block Element\n",
    "An element with its `display` property set to `inline-block`. These have a few key properties:\n",
    "* They start immediately after the content before them, and do not start on a new line.\n",
    "* They span the width of their content by default, but they can have a width and height set like block-level elements.\n",
    "* They can be used for elements like buttons and input fields, which need to be inline but also need to be styled with a specific size."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf7b9f0a",
   "metadata": {},
   "source": [
    "### Box Model\n",
    "The **box model** refers to the way that the browser lays out elements on a web page. Each element is treated as a **rectangular box** that has four components: **content, padding, border** and **margin**. The box model is important to understand because it affects the size and position of elements on a web page, and can be used to create complex layouts.\n",
    "\n",
    "#### content\n",
    "This is the actual content of the box, such as text or an image.\n",
    "\n",
    "#### padding\n",
    "A property used to create extra space within an element, between the **content** and **border**. The `padding` CSS property\n",
    "isa shorthand for `padding-top` , `padding-right` , `padding-bottom` and `padding-left` in that order.\n",
    "\n",
    "\n",
    "#### border\n",
    "A property used to create a border around the content and padding of an element. The `border` CSS property is a\n",
    "shorthand for `border-color`, `border-style` and `border-width` , which it takes as space separated values in any\n",
    "order. For example, `border: 1px solid black` would create a one pixel, solid black border.\n",
    "\n",
    "A `border-radius` can also be used to create rounded corners on an element, regardless of if it has a border. This\n",
    "defines the radius of the corners, and a value of `50%` is often used on square elements to create a circle.\n",
    "\n",
    "Additionally, `border-top` , `border-right` , `border-bottom` and `border-left` can be used to set borders ona\n",
    "single side of an element.\n",
    " \n",
    "#### margin\n",
    "A property used to create extra space around an element. The `margin` CSS property is a shorthand for `margin-top` ,\n",
    "`margin-right` , `margin-bottom` and `margin-left` in that order.\n",
    "\n",
    "A value of `auto` can also be used to allow the browser to choose margins, which will usually center block elements\n",
    "horizontally.\n",
    "\n",
    "Adjacent horizontal margins will be added together to determine the space between elements. Vertical margins on the\n",
    "other hand will usually be collapsed, meaning only the larger margin value will be used.\n",
    "\n",
    "#### Examples\n",
    "Here are a few examples of the box model in action:\n",
    "\n",
    "##### Example 1 - Simple box with padding and border\n",
    "\n",
    "```html\n",
    "<div style=\"width: 200px; height: 100px; padding: 10px; border: 1px solid black;\">\n",
    "  This is some content inside a box with padding and a border.\n",
    "</div>\n",
    "```\n",
    "This code creates a `div` element that is 200 pixels wide and 100 pixels tall, with 10 pixels of padding on all sides and a 1 pixel solid black border around the content and padding.\n",
    "\n",
    "##### Example 2 - Box with margin and background color\n",
    "\n",
    "```html\n",
    "<div style=\"width: 300px; height: 150px; margin: 20px; background-color: gray;\">\n",
    "  This is some content inside a box with margin and a blue background color.\n",
    "</div>\n",
    "```\n",
    "\n",
    "This code creates a `div` element that is 300 pixels wide and 150 pixels tall, with 20 pixels of margin on all sides and a blue background color. \n",
    "\n",
    "##### Example 3 - Multiple boxes with collapsed margins\n",
    "\n",
    "```html\n",
    "<div style=\"margin-bottom: 20px; background-color: red;\">\n",
    "  This is box 1.\n",
    "</div>\n",
    "<div style=\"margin-top: 0; margin-bottom: 20px; background-color: green;\">\n",
    "  This is box 2.\n",
    "</div>\n",
    "<div style=\"margin-top: 0; background-color: blue;\">\n",
    "  This is box 3.\n",
    "</div>\n",
    "```\n",
    "\n",
    "This code creates three `div` elements with different background colors. Note that the vertical margins between the boxes are collapsed, so only a single 20 pixel margin is shown between each of the boxes."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ecb32911",
   "metadata": {},
   "source": [
    "### Box Sizing\n",
    "\n",
    "Box sizing is a CSS property that determines how an element's width and height are calculated. The default value for most elements is `content-box`, which only considers the width and height of the element's content. However, a value of `border-box` takes into account the padding and border of the element in addition to the content.\n",
    "\n",
    "For example, suppose you have a `div` element with a width of `200px`, padding of `20px`, and border of `5px`. If the `box-sizing` property is set to `content-box`, the total width of the element would be `250px` (i.e., 200px + 2 * 20px + 2 * 5px). On the other hand, if the `box-sizing` property is set to `border-box`, the total width would be `200px`, which includes the content, padding, and border."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "03bf2310",
   "metadata": {},
   "source": [
    "### position\n",
    "\n",
    "A CSS property for setting how the browser should position an element in the document. This defaults to `static` , but\n",
    "can take a variety of values:\n",
    "\n",
    "* **static**: This is the default value, and it means that the element is positioned according to the normal flow of the page.\n",
    "\n",
    "\n",
    "* **fixed**: The element is positioned relative to the viewport and removed from the normal flow of the document. The `top`, `left`, `right` and `bottom` properties can then be used to move the element.\n",
    "\n",
    "\n",
    "* **relative**: The element is positioned in the same place as it would be with **static**, however, it can be repositioned with `top`, `left`, `right` and `bottom` relative to its natural position on the document.\n",
    "\n",
    "\n",
    "* **sticky**: The element will act similar to a **relative** positioned element, but once it scrolls off screen it will stay fixed to the screen, essentially acting as `position: fixed` . This is particularly useful for menu bars that need to \"stick\" to the top of the screen as the user scrolls.\n",
    "\n",
    "\n",
    "* **absolute**: By default, this will act the same as **fixed**, except the element will be positioned relative to the document instead of the viewport. This means that, as the page is scrolled, it will move with the page rather than stay at the same viewport location. However, if any element above it in the DOM, oftentimes referred to as an ancestor, has a position value other than **static**, then it will be positioned relative to that nearest positioned ancestor.\n",
    "\n",
    "Here's an example:\n",
    "```html\n",
    "<style>\n",
    "\n",
    "/* Static positioning */\n",
    "div {\n",
    "  position: static;\n",
    "}\n",
    "\n",
    "/* Fixed positioning */\n",
    "#fixed {\n",
    "  position: fixed;\n",
    "  top: 0;\n",
    "  right: 0;\n",
    "}\n",
    "\n",
    "/* Relative positioning */\n",
    "#relative {\n",
    "  position: relative;\n",
    "  top: 10px;\n",
    "  left: 20px;\n",
    "}\n",
    "\n",
    "/* Sticky positioning */\n",
    "#sticky {\n",
    "  position: sticky;\n",
    "  top: 0;\n",
    "}\n",
    "\n",
    "/* Absolute positioning */\n",
    "#absolute {\n",
    "  position: absolute;\n",
    "  top: 50px;\n",
    "  left: 50px;\n",
    "}\n",
    "\n",
    "</style>\n",
    "\n",
    "\n",
    "<div>\n",
    "  This element is positioned statically.\n",
    "</div>\n",
    "\n",
    "<div id=\"fixed\">\n",
    "  This element is fixed to the top right corner of the viewport.\n",
    "</div>\n",
    "\n",
    "<div id=\"relative\">\n",
    "  This element is positioned 10 pixels down and 20 pixels to the right of its natural position in the document flow.\n",
    "</div>\n",
    "\n",
    "<div id=\"sticky\">\n",
    "  This element will stick to the top of the viewport once it scrolls off screen.\n",
    "</div>\n",
    "\n",
    "<div id=\"absolute\">\n",
    "  This element is positioned 50 pixels down and 50 pixels to the right of its nearest positioned ancestor.\n",
    "  <div style=\"position: relative;\">\n",
    "    This element is the nearest positioned ancestor of the absolute element.\n",
    "  </div>\n",
    "</div>\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2a5d1647",
   "metadata": {},
   "source": [
    "### float\n",
    "The **float** property in CSS is used to specify how an element should be positioned in relation to surrounding elements. When an element is floated, it is taken out of the normal flow of the page and positioned to the left or right of its container, with text and other content flowing around it. This is often used for layout purposes, such as creating multi-column designs or placing images alongside text.\n",
    "\n",
    "The float property can take the values of `left`, `right`, or `none`. By default, it is set to `none`. Here's an example of how to use the float property to position an element to the left:\n",
    "```css\n",
    "div {\n",
    "  float: left;\n",
    "}\n",
    "```\n",
    "In this example, the div element will be floated to the left of its container, with text and other content flowing around it to the right. Note that when an element is floated, its height is no longer taken into account when calculating the height of its parent element."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "be2ba304",
   "metadata": {},
   "source": [
    "### clear\n",
    "The **clear** property is used to specify whether an element should be allowed to float next to any preceding elements that have been floated. When an element is cleared, it is moved below any floated elements that precede it in the markup. The clear property has three possible values:\n",
    "\n",
    "* `none`: This is the default value, and it means that the element can float next to other elements.\n",
    "\n",
    "\n",
    "* `left`: This value means that the element cannot float to the left of any preceding floated elements.\n",
    "\n",
    "\n",
    "* `right`: This value means that the element cannot float to the right of any preceding floated elements."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c0264c5b",
   "metadata": {},
   "source": [
    "### Stacking Context\n",
    "**Stacking context** is a concept in CSS that refers to the order in which elements are displayed on the **z-axis**, and it is determined by a combination of factors including z-index, position, and other properties. Elements that share the same stacking context are positioned in a specific order, with those having a higher z-index value appearing on top of those with a lower value. \n",
    "\n",
    "Stacking contexts can be created by a variety of properties, including position, opacity, and more. The stacking context hierarchy can be complex, as it can be nested within other stacking contexts, and z-index values are used to determine the layering of elements with the same **stacking context parent**.\n",
    "\n",
    "For example:\n",
    "```html\n",
    "<style>\n",
    "\n",
    ".parent {\n",
    "  position: relative;\n",
    "  z-index: 1;\n",
    "}\n",
    "\n",
    ".child {\n",
    "  position: absolute;\n",
    "  width: 100px;\n",
    "  height: 100px;\n",
    "}\n",
    "\n",
    ".child1 {\n",
    "  background-color: red;\n",
    "  z-index: 2;\n",
    "  top: 0;\n",
    "  left: 0;\n",
    "}\n",
    "\n",
    ".child2 {\n",
    "  background-color: blue;\n",
    "  z-index: 1;\n",
    "  top: 50px;\n",
    "  left: 50px;\n",
    "}\n",
    "\n",
    "</style>\n",
    "\n",
    "\n",
    "<div class=\"parent\">\n",
    "  <div class=\"child child1\"></div>\n",
    "</div>\n",
    "<div class=\"child child2\"></div>\n",
    "```\n",
    "In this example, we have a parent element with a higher z-index value than its child element. The child element is positioned absolutely and given a lower z-index value than its sibling element that is not nested inside the parent element. As a result, the red child element is stacked above the blue child element, despite having a lower z-index value. This is because they have different stacking context parents."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5f53bc9a",
   "metadata": {},
   "source": [
    "### Flexbox\n",
    "\n",
    "A layout model, also known as the **Flexible Box Layout Module**, particularly useful for building responsive designs with row or column layouts. An element can be made a **flex container** with `display: flex` , and all of its direct children will automatically be laid out as **flex items**. It also simplifies layout for complex designs that need to adjust to different content sizes or user actions.\n",
    "\n",
    "For flex containers, these are some of the most common properties used to layout their flex items:\n",
    "\n",
    "* **flex-direction**: Determines which direction is the **main-axis**, either `row` or `column` . Additionally, `row-reverse` and `column-reverse` can be used to reverse the order of flex items.\n",
    "\n",
    "\n",
    "* **justify-content**: Determines how elements are positioned along the **main-axis** with possible values of `flex-start` , `flex-end`, `center` , `space-around` , `space-between` , and `space-evenly` .\n",
    "\n",
    "\n",
    "* **align-items**: Determines how elements are positioned along the **cross-axis** (the one not selected by `flex-direction` ). Possible values are `flex-start` , `flex-end`, `center`, `baseline` ,and `stretch`.\n",
    "\n",
    "\n",
    "* **flex-wrap**: Determines if flex items can wrap to new lines with possible values of `wrap` and `nowrap` . `wrap-reverse` can also be used to wrap flex items with the lines in reverse order.\n",
    "\n",
    "\n",
    "* **align-content**: Determines how multiple rows or columns of flex items are positioned along the **cross-axis** when flex items are wrapping on multiple lines. Possible values are `flex-start` , `flex-end`, `center` , `space-around` , `space-between`, and `stretch`. This property only applies when flex items are wrapped.\n",
    "\n",
    "\n",
    "* **flex-flow**: A shorthand for setting both `flex-direction` and `flex-wrap` properties in one declaration. For example, `flex-flow: row wrap;` would set the `flex-direction` to `row` and `flex-wrap` to `wrap`.\n",
    "\n",
    "\n",
    "* **gap**: Determines the amount of space between flex items. This can take one or two length values. If it is given two, they will be treated as a **row gap** and a **column gap** respectively. Alternatively, a `row-gap` and `column-gap` property can be specified to individually set the gap between rows and columns.\n",
    "\n",
    "\n",
    "* **justify-items**: Aligns flex items within a flex container when there is extra space in both the **main** and **cross-axis**. This property only applies when the flex container has a grid layout, which is a newer addition to the Flexbox specification.\n",
    "\n",
    "For flex items, these are some of the most common properties used to position themselves:\n",
    "\n",
    "* **align-self**: Overrides the `align-items` value used for the flex container.\n",
    "\n",
    "\n",
    "* **flex-basis**: Sets the initial size of the flex item along the **main-axis** (essentially this will act as width for the row axis and height for the column axis).\n",
    "\n",
    "\n",
    "* **flex-grow**: Determines if the flex item is able to grow into extra space. If the value is 0, the flex item will not grow. Otherwise, it will take up as much extra space as possible, with larger grow values taking more space proportionally. For example, if item A has a value of 1 and item B has a value of 2, then item B will take up twice as much extra space as item A (Note this does not mean it will be twice as large, only that it will take twice as much of the extra space).\n",
    "\n",
    "\n",
    "* **flex-shrink**: Determines if a flex item is able to shrink in the case that the flex items are too large for the container. Flex items with a value of 0 will not shrink. Otherwise they will all shrink proportionally based on their values, similar to flex grow. The higher the value, the more the flex item will potentially shrink.\n",
    "\n",
    "\n",
    "* **flex**: A shorthand property for `flex-grow`, `flex-shrink` , and `flex-basis` in that order.\n",
    "\n",
    "\n",
    "* **order**: Moves the flex-item to a different location amongst the other flex items rather than using the order defined in the DOM. All flex items default to having a value of 0. This means a value of -1 would move an item before all other items that have not changed their order. Likewise, a value of 1 would place the item at the end.\n",
    "\n",
    "Here's an example of Flexbox:\n",
    "```html\n",
    "<style>\n",
    "\n",
    ".flex-container {\n",
    "  display: flex;\n",
    "  justify-content: center;\n",
    "  align-items: center;\n",
    "  flex-wrap: wrap;\n",
    "}\n",
    ".flex-item {\n",
    "  background-color: lightblue;\n",
    "  margin: 5px;\n",
    "  padding: 10px;\n",
    "  flex-basis: 150px;\n",
    "}\n",
    "\n",
    "</style>\n",
    "\n",
    "\n",
    "<div class=\"flex-container\">\n",
    "  <div class=\"flex-item\">Flex item 1</div>\n",
    "  <div class=\"flex-item\">Flex item 2</div>\n",
    "  <div class=\"flex-item\">Flex item 3</div>\n",
    "  <div class=\"flex-item\">Flex item 4</div>\n",
    "  <div class=\"flex-item\">Flex item 5</div>\n",
    "  <div class=\"flex-item\">Flex item 6</div>\n",
    "</div>\n",
    "```\n",
    "\n",
    "#### Use Cases\n",
    "Here are a few use cases of how flexbox can be utilized:\n",
    "\n",
    "* **Creating a navigation menu**: Flexbox can be used to create a horizontal navigation menu that adjusts its layout based on the available space.\n",
    "\n",
    "* **Building a card layout**: Flexbox can be used to create a layout of cards that are arranged in a row or a column, with each card having a consistent size.\n",
    "\n",
    "* **Centering content**: Flexbox can be used to center content horizontally and/or vertically within a container, making it easier to position content on a web page.\n",
    "\n",
    "* **Building a footer**: Flexbox can be used to create a footer that sticks to the bottom of the page, regardless of the height of the content above it.\n",
    "\n",
    "* **Creating a flexible grid**: Flexbox can be used to create a grid that adjusts its layout based on the available space, making it easier to create responsive designs."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c757c345",
   "metadata": {},
   "source": [
    "### CSS Grid\n",
    "\n",
    "A layout model used for creating responsive layouts of multiple rows and columns. An element can be made a **grid\n",
    "container** with `display: grid` , and all of its direct children will automatically be laid out as **grid items** in a single **cell**.\n",
    "\n",
    "A rectangular subsection of a grid is known as a **grid area**. The dividers between each row and column are known as **grid\n",
    "lines**, and the rows and columns they create are called **tracks**.\n",
    "\n",
    "For grid containers, these are some of the most common properties used to layout their grid items:\n",
    "\n",
    "* **grid-template-columns**: Determines the number of columns and their sizes. The unit **fr** can be used as a **fractional unit** here to create a responsive design.\n",
    "\n",
    "\n",
    "* **grid-template-rows**: Determines the number of rows and their sizes. The unit `fr` can be used as a fractional unit here to create a responsive design.\n",
    "\n",
    "\n",
    "* **grid-template-areas**: Creates names for grid areas that grid items can place themselves in.\n",
    "\n",
    "\n",
    "* **justify-content**: Determines how grid tracks are aligned along the `inline-axis` (**row**) with possible values including `start`, `end`, `center`, `space-around`, `space-between` ,and `space-evenly` .\n",
    "\n",
    "\n",
    "* **align-content**: Determines how grid tracks are aligned along the `block-axis` (**column**) with possible values including `start`, `end`, `center`, `space-around` , `space-between` ,and `space-evenly` .\n",
    "\n",
    "\n",
    "* **align-items**: Determines how grid items are aligned in columns (called the **block-axis**). Possible values include `start` , `end`, `center` ,and `stretch`.\n",
    "\n",
    "\n",
    "* **justify-items**: Determines how grid items are aligned in rows (called the **inline-axis**). Possible values include `start` , `end`, `center` ,and `stretch`.\n",
    "\n",
    "\n",
    "* **place-items**: A shorthand for both `align-items` and `justify-items` . If one value is given, it will apply to both. If two values are given, they will apply to `align-items` and `justify-items` respectively.\n",
    "\n",
    " \n",
    "* **gap**: Determines the amount of space between grid items. This can take one or two length values. If it is given two, they will be treated as a row gap and a column gap respectively. Alternatively, a `row-gap` and `column-gap` property can be specified to individually set the gap between rows and columns.\n",
    "\n",
    "\n",
    "For grid items, these are some of the most common properties used to position themselves:\n",
    "\n",
    "* **grid-column-start**: Determines what column this item starts on, based on a line number.\n",
    "\n",
    "\n",
    "* **grid-column-end**: Determines what column this item ends on, based on a line number.\n",
    "\n",
    "\n",
    "* **grid-column**: A shorthand for both `grid-column-start` and `grid-column-end` specified in the format\n",
    "start / end.\n",
    "\n",
    "\n",
    "* **grid-row-start**: Determines what row this item starts on, based on a line number.\n",
    "\n",
    "\n",
    "* **grid-row-end**: Determines what row this item ends on, based on a line number.\n",
    "\n",
    "\n",
    "* **grid-row**: A shorthand for both `grid-row-start` and `grid-row-end` specified inthe format `start / end` .\n",
    "\n",
    "\n",
    "* **grid-area**: Places the item in a grid-area based on a name created in `grid-template-areas` .\n",
    "\n",
    "\n",
    "* **align-self**: Overrides the `align-items` value used for the grid container.\n",
    "\n",
    "\n",
    "* **justify-self**: Overrides the `justify-items` value used for the grid container.\n",
    "\n",
    "\n",
    "* **place-self**: A shorthand for both `align-self` and `justify-self` inthe same format as place-items .\n",
    "\n",
    "Here's an example of CSS Grid:\n",
    "```html\n",
    "<style>\n",
    "\n",
    ".container {\n",
    "  display: grid;\n",
    "  grid-template-columns: 1fr 1fr 1fr;\n",
    "  gap: 20px;\n",
    "}\n",
    "\n",
    ".item {\n",
    "  background-color: #eee;\n",
    "  padding: 20px;\n",
    "  text-align: center;\n",
    "}\n",
    "\n",
    "</style>\n",
    "\n",
    "\n",
    "<div class=\"container\">\n",
    "  <div class=\"item\">Column 1</div>\n",
    "  <div class=\"item\">Column 2</div>\n",
    "  <div class=\"item\">Column 3</div>\n",
    "</div>\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9c8d4083",
   "metadata": {},
   "source": [
    "### Image Sprite\n",
    "\n",
    "A group of images all included in a single image file. These images are usually split on the client using the CSS\n",
    "`background-image` property alongwith `background-position`. The primary benefit of sprites is to reduce the total file size and the number of files the client needs to download, which can decrease page load times."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "45cae055",
   "metadata": {},
   "source": [
    "### CSS Inheritance\n",
    "\n",
    "**CSS Inheritance** determines how elements choose a value when none has been explicitly declared in any stylesheet. All properties are either **inherited properties** or **non-inherited properties**. Inherited properties will take their parent's value in the case no value has been set for the property. Non-inherited properties on the other hand will be set to `initial` in this case.\n",
    "\n",
    "While the default groupings of inherited and non-inherited properties is usually all that's needed, this can be changed by\n",
    "using any of these values for any declaration:\n",
    "\n",
    "* **inherit**: The value should inherit from its parent, regardless of if it is normally an inherited property.\n",
    "\n",
    "\n",
    "* **initial**: The value should be set to the value defined in the CSS specification. Note this is oftentimes different from browser defaults.\n",
    "\n",
    "\n",
    "* **unset**: The value should be set to `inherit` if it is normally an inherited property, otherwise `initial` . This can be useful for \"resetting\" browser defaults from the user agent stylesheet.\n",
    "\n",
    "\n",
    "* **revert**: The value should revert back to the next stylesheet in the cascade. For author stylesheets, this would act as if the author did not write any declaration for the property, but it would still honor the user agent and user stylesheets as normal."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c85d02bf",
   "metadata": {},
   "source": [
    "### Mobile First Design (Responsive Designs)\n",
    "\n",
    "Building websites or applications with mobile devices as the primary use case, then scaling them up to larger devices with responsive CSS. In general, it is easier to scale a design up to larger screens than to scale it down to smaller screens. Along with the massive growth of mobile browsing, this makes mobile first design a great development workflow."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "62b5ab6b",
   "metadata": {},
   "source": [
    "### Transitions\n",
    "\n",
    "A CSS module for smoothly transitioning between values when a value is changed. Transitions can be defined with a\n",
    "combination of these properties:\n",
    "\n",
    "* **transition-property**: The name of the CSS property to transition.\n",
    "\n",
    "* **transition-duration**: How long the transition should take.\n",
    "\n",
    "* **transition-timing-function**: How the transition should progress. This can take a variety of keyword values, such as `linear` and `ease-in`, or custom values using the `cubic-bezier()` or `steps()` functions.\n",
    "\n",
    "* **transition-delay**: How long to wait before starting the transition.\n",
    "\n",
    "Alternatively, the `transition` property can be used as a shorthand for all of these values. The first time value will be\n",
    "used for the duration, and the second will be used for a delay. Other than that, the order does not matter.\n",
    "\n",
    "For example, this would set the width to smoothly transition linearly over one second, two seconds after the value is\n",
    "changed:\n",
    "\n",
    "`transition: width 1s linear 2s;`\n",
    "\n",
    "### Animations\n",
    "\n",
    "A CSS module for animating properties, very similar to **transitions**, but with a bit more control. An animation is defined\n",
    "using **keyframes** as well as these properties:\n",
    "\n",
    "* **animation-name**: The name of the **keyframes** animation.\n",
    "\n",
    "* **animation-duration**: How long the animation should take.\n",
    "\n",
    "* **animation-fill-mode**: If the element should stay in its animated position after the animation completes or if it should\n",
    "move to the starting position of the animation before it begins, specified with the `backwards` and `forwards` values\n",
    "respectively or `both` to follow the rules of both values.\n",
    "\n",
    "* **animation-direction**: If the animation should playin `normal` or `reverse` order. Avalue of alternate can also be used to switch between normal and reverse, or `alternate-reverse` can be used to do the same, but starting with the reverse direction.\n",
    "\n",
    "* **animation-iteration-count**: How many times to run the animation, or `infinite` to run the animation indefinitely.\n",
    "\n",
    "* **animation-play-state**: If the animation is currently `running` or `paused` . This is particularly useful for pausing an\n",
    "animation using JavaScript.\n",
    "\n",
    "* **animation-timing-function**: How the animation should progress through the keyframes. This can take a variety of keyword values, such as `linear` and `ease-in` , or custom values using the `cubic-bezier()` or `steps()` functions.\n",
    "\n",
    "* **animation-delay**: How long to wait before starting the animation.\n",
    "\n",
    "Alternatively, the `animation` property can be used as a shorthand for all of these values. The first time value will be used for the duration, and the second will be used for a delay. Other than that, the order usually will not matter assuming the `animation-name` is not using a conflicting keyword with another possible value.\n",
    "\n",
    "For example after a two second delay, this would run the move animation over three seconds with the ease timing\n",
    "function. The animation would continue to run indefinitely, alternating the order each time.\n",
    "\n",
    "`animation: move 3s ease infinite alternate 2s;`\n",
    " \n",
    "### @keyframes\n",
    "A keyword for defining points within an animation timeline. An animation is made up of a variety of keyframes, and the\n",
    "browser will fill in the spaces between the keyframes based on the timing function. Keyframes are defined using this syntax:\n",
    "\n",
    "```css\n",
    "@keyframes animation-name {\n",
    " from {\n",
    "    property: value;\n",
    "    property: value;\n",
    "  }\n",
    "\n",
    " 50% {\n",
    "\tproperty: value;\n",
    "\tproperty: value;\n",
    " }\n",
    "\n",
    " to {\n",
    "\tproperty: value;\n",
    "\tproperty: value;\n",
    " }\n",
    "}\n",
    "```\n",
    "\n",
    "The **from** and **to** keywords are equivalent to `0%` and `100%` respectively."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6bb9d1dc",
   "metadata": {},
   "source": [
    "### Custom Properties\n",
    "\n",
    "Also known as **variables**, these are used to keep track of repeated values in CSS. Custom properties always start with --\n",
    "and can be included in any ruleset. However, most commonly they are defined on the `:root` ruleset so the variables will\n",
    "be accessible throughout the website. Custom properties are then used with the `var()` CSS function. For example, this\n",
    "code defines a custom property called `--main-color` and uses it for a background color:\n",
    "\n",
    "```css\n",
    ":root {\n",
    "--main-color: #00334C;\n",
    "}\n",
    "\n",
    "main {\n",
    "background-color: var(--main-color) ;\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b7de0e53",
   "metadata": {},
   "source": [
    "### CSS Framework\n",
    "**CSS Frameworks** are pre-written code libraries that provide a standardized set of CSS rules, pre-built components, and responsive layout systems to make it easier for developers to create consistent, well-designed websites and web applications. These frameworks often include ready-to-use classes for common design patterns such as navigation menus, forms, and grids, as well as pre-built UI components like buttons, modals, and sliders. They can help to reduce development time and improve the maintainability of code by providing a consistent and tested set of styles and functionality that can be easily reused across projects. Examples of popular CSS frameworks include **Tailwind**, **Bootstrap**, **Foundation**, and **Materialize**.\n",
    "\n",
    "### Preprocessor\n",
    "**CSS preprocessors** are essentially scripting languages that extend the CSS syntax by adding features such as variables, functions, mixins, and nested rules. They are designed to make writing CSS more efficient and less repetitive, allowing developers to write code that is more organized and easier to maintain.\n",
    "\n",
    "Popular CSS preprocessors include **Sass**, **Less**, and **Stylus**. These preprocessors are compiled into regular CSS that can be interpreted by web browsers. By using a preprocessor, developers can write more modular and reusable CSS code, which can ultimately save time and improve code quality.\n",
    " \n",
    "### BEM\n",
    "The **Block, Element, Modifier** CSS methodology. This breaks CSS classes into three categories:\n",
    "\n",
    "* **Blocks**: Standalone elements with their own meaning. These are referenced simply by the name of the block such as `class=\"menu\"` .\n",
    "\n",
    "\n",
    "* **Elements**: Parts of a block without their own meaning. These are referenced by the name of the block, two underscores then the name of the element such as `class=\"menu__item\"` .\n",
    "\n",
    "\n",
    "* **Modifiers**: Flags to change styles for blocks or elements, such as `disabled` or `selected`. These are prefixed by the class they modify and two dashes, and they are included in addition to that original class such as `class=\"menu menu--disabled\"` .\n",
    "\n",
    "### OOCSS\n",
    "The **Object-Oriented** CSS methodology. This is based on object-oriented programming principles, which can be applied to\n",
    "CSS class design by treating UI components as objects. Styles are then given one of two categories:\n",
    "\n",
    "* **Structure**: \"Invisible\" properties such as width and margin.\n",
    "\n",
    "\n",
    "* **Skin**: \"Visible\" properties such as color and border.\n",
    "\n",
    "Along with separating structure and skin into classes, OOCSS also makes a clear distinction between **content** and\n",
    "**containers**. The idea here is that containers should function the same, regardless of the content inside of them. Moreover, content should not depend on the container it is nested within.\n",
    "\n",
    "### Atomic CSS\n",
    "\n",
    "A CSS methodology based on the idea of minimizing any repeated declarations. Rather than creating classes based on\n",
    "components, Atomic CSS creates utility classes based on single declarations. For example, in Atomic CSS a `margin-12`\n",
    "class might be created that adds 12 pixels of margin, rather than including that declaration on all of the components\n",
    "needing 12 pixels of margin.\n",
    "\n",
    "### SMACSS\n",
    "\n",
    "The **Scalable and Modular Architecture For CSS** methodology, usually pronounced as \"smacks\". This splits CSS into five\n",
    "different categories, each of which get their own file:\n",
    "\n",
    "* **Base**: Page defaults, usually just type selectors.\n",
    "\n",
    "\n",
    "* **Layout**: Major structural layout of the page, using ID and class selectors. The classes are usually prefixed with `l-` or `layout-` . For example, a navigation element might have the class `l-nav` .\n",
    "\n",
    "\n",
    "* **Module**: Smaller reusable components, usually using class selectors without any name prefixes.\n",
    "\n",
    "\n",
    "* **State**: Specific states for layouts or modules, such as disabled or selected states, usually using class selectors again.\n",
    "\n",
    "\n",
    "* **Theme**: Style rules for layouts and modules related to a theme, oftentimes based on user preferences such as a dark\n",
    "mode.\n",
    "\n",
    "### ITCSS\n",
    "\n",
    "The **Inverted Triangle** CSS methodology. This methodology is mostly focused on the order of CSS code, rather than\n",
    "having opinions on naming conventions. The primary idea here is to have generic styles first, which should have the largest reach across elements and the least specific selectors. The exact layers of the triangle can be changed to fit the needs of a specific project, but a general structure looks like this:\n",
    "\n",
    "* **Settings**: Global variables affecting the entire website.\n",
    "\n",
    "\n",
    "* **Tools**: Mixins and functions for use with **preprocessors**.\n",
    "\n",
    "\n",
    "* **Generic**: High level generic styles, usually to reset browser defaults for consistency across browsers.\n",
    "\n",
    "\n",
    "* **Elements**: Defaults for elements using type selectors.\n",
    "\n",
    "\n",
    "* **Objects**: The most generic classes, oftentimes for larger containers.\n",
    "\n",
    "\n",
    "* **Components**: Classes for individual UI components.\n",
    "\n",
    "\n",
    "* **Trumps**: `!important` overrides for when they are needed."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ea5ae75",
   "metadata": {},
   "source": [
    "### References\n",
    "\n",
    "* http://www.dontfeartheinternet.com/\n",
    "* https://www.internetingishard.com/\n",
    "* https://frontendmasters.com/bootcamp/\n",
    "* https://getbootstrap.com/"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}