diff --git a/app/(main)/learn/basics/selectors-specificity/page.tsx b/app/(main)/learn/basics/selectors-specificity/page.tsx index 843c2d0..6674d84 100644 --- a/app/(main)/learn/basics/selectors-specificity/page.tsx +++ b/app/(main)/learn/basics/selectors-specificity/page.tsx @@ -593,7 +593,7 @@ const Kata: NextPage = () => (
  • How specificity works.
  • - A good selector has a low specificity and conveys the design intention + A good selector has a low specificity and conveys the design intention.
  • diff --git a/app/(main)/learn/basics/the-box-model-and-layouts/border-box-model.svg b/app/(main)/learn/basics/the-box-model-and-layouts/border-box-model.svg new file mode 100644 index 0000000..dbe5d34 --- /dev/null +++ b/app/(main)/learn/basics/the-box-model-and-layouts/border-box-model.svg @@ -0,0 +1,17 @@ + + + + + + + + ContentmarginpaddingborderWidthheight diff --git a/app/(main)/learn/basics/the-box-model-and-layouts/box-model.png b/app/(main)/learn/basics/the-box-model-and-layouts/box-model.png deleted file mode 100644 index 4f0f1bd..0000000 Binary files a/app/(main)/learn/basics/the-box-model-and-layouts/box-model.png and /dev/null differ diff --git a/app/(main)/learn/basics/the-box-model-and-layouts/box-model.svg b/app/(main)/learn/basics/the-box-model-and-layouts/box-model.svg new file mode 100644 index 0000000..f3f8bb0 --- /dev/null +++ b/app/(main)/learn/basics/the-box-model-and-layouts/box-model.svg @@ -0,0 +1,17 @@ + + + + + + + + ContentmarginpaddingborderheightWidth \ No newline at end of file diff --git a/app/(main)/learn/basics/the-box-model-and-layouts/devtools.png b/app/(main)/learn/basics/the-box-model-and-layouts/devtools.png index 7966811..b064da3 100644 Binary files a/app/(main)/learn/basics/the-box-model-and-layouts/devtools.png and b/app/(main)/learn/basics/the-box-model-and-layouts/devtools.png differ diff --git a/app/(main)/learn/basics/the-box-model-and-layouts/layouts.svg b/app/(main)/learn/basics/the-box-model-and-layouts/layouts.svg new file mode 100644 index 0000000..977c18e --- /dev/null +++ b/app/(main)/learn/basics/the-box-model-and-layouts/layouts.svg @@ -0,0 +1,17 @@ + + + + + + + + FlowFlexTableGridThe defaultlayout ! \ No newline at end of file diff --git a/app/(main)/learn/basics/the-box-model-and-layouts/outer-inner-display-type.svg b/app/(main)/learn/basics/the-box-model-and-layouts/outer-inner-display-type.svg new file mode 100644 index 0000000..41e0570 --- /dev/null +++ b/app/(main)/learn/basics/the-box-model-and-layouts/outer-inner-display-type.svg @@ -0,0 +1,17 @@ + + + + + + + + display: ;[outer][inner][outer][inner] \ No newline at end of file diff --git a/app/(main)/learn/basics/the-box-model-and-layouts/page.tsx b/app/(main)/learn/basics/the-box-model-and-layouts/page.tsx index ac98f34..ad90616 100644 --- a/app/(main)/learn/basics/the-box-model-and-layouts/page.tsx +++ b/app/(main)/learn/basics/the-box-model-and-layouts/page.tsx @@ -8,7 +8,18 @@ import { NextKataButton } from 'components/NextKataButton'; import { Editor } from 'components/Editor'; import { KataQuestions } from 'components/KataQuestions'; import { PAGES } from 'services/pages'; -import boxModelImage from './box-model.png'; +import { + Table, + TableBody, + TableCell, + TableHeader, + TableHeaderCell, + TableRow, +} from 'components/Table'; +import BoxModelImage from './box-model.svg'; +import OuterInnerDisplayTypeImage from './outer-inner-display-type.svg'; +import BorderBoxModelImage from './border-box-model.svg'; +import LayoutsImage from './layouts.svg'; import devToolsImage from './devtools.png'; const Kata: NextPage = () => ( @@ -29,15 +40,22 @@ const Kata: NextPage = () => ( Definition

    - Every DOM element (even text) is modelized in CSS by a box, and{' '} + Every node of{' '} + + the render tree + {' '} + (even text) is modelized by a box, and{' '} it is really important to understand how this box system works to master layout techniques and every little detail about CSS.

    A box showing how width, height, padding, border and margin are related to each other + } + alt="" + caption="Schema of the Box model" + style={{ maxWidth: '30rem' }} />

    @@ -63,97 +81,73 @@ const Kata: NextPage = () => ( for every CSS property there is a difference between the specified value in your CSS code and the value that is actually computed by the browser. - {' '} - Most of the time the specified and computed values will be the same but in - a lot of cases the browser will override the specified value. +

    - The box model properties will impact (or not) the box characteristics{' '} - depending on the display mode. + A quick demonstration: the browser might not honor the width property if there + is a min-width property. Thus, the width specified property and actual box + characteristics will be different.

    - - -
    - The display property -

    - You can change the display mode with the display CSS property. We’ll see it - more in depth in the next kata but for now remember that there are two main display modes:{' '} - block and inline. -

    - -
    -
    - block -
    -
    - The box will extend in the line direction to fill the space available in its container. - The width and height properties are respected. -
    + +.box { + border: 1px solid black; + padding: 10px; + min-width: 300px; + width: 100px; /* Does not work! */ +} + -
    - inline -
    -
    - The width and height properties do not apply. -
    -
    +
    Box
    `} + /> +
    -

    - All elements have a default display mode. For instance, div, h1{' '} - and p are block by default while a, strong and{' '} - span are inline. -

    +
    + The box-sizing property .box { border: 1px solid black; padding: 10px; - margin: 10px; } - -.block { display: block; } -.inline { display: inline; } -Block box -Inline box`} +
    Box
    `} solution={` -Block box -Inline box`} +
    Box
    `} />

    - In the above example, something is not really intuitive: if you inspect the first box with - the dev tools, we end up with a distance from border to border included of 222px. Let’s - bring up the box model again: + In the above example, something is not really intuitive: if you inspect the box with the dev + tools, we end up with a distance from border to border included of 122px. Let’s bring up the + box model again:

    A box showing how width, height, padding, border and margin are related to each other + } + alt="" + caption="Schema of the Box model" + style={{ maxWidth: '30rem' }} />

    - We get 222px because: 1px from left border + 10px from left{' '} - padding + 200px from width + 20px from right padding{' '} - + 1px from right border = 222px. This is not intuitive because most humans will + We get 122px because: 1px from left border + 10px from left{' '} + padding + 100px from width + 20px from right padding{' '} + + 1px from right border = 122px. This is not intuitive because most humans will consider a box what is delimited by the borders. But fear not!{' '} There is an alternate box model.

    @@ -161,43 +155,51 @@ const Kata: NextPage = () => (

    The default box model is the content-box model. The other box model is the{' '} border-box model. In this model, the width and height characteristics{' '} - are defined as content + padding + border. By setting the box-sizing property, - you can change the model used. + are defined as content + padding + border. +

    + + + } + alt="" + caption="Schema of the border box model" + style={{ maxWidth: '30rem' }} + /> + +

    + By setting the{' '} + + box-sizing + {' '} + property, you can change the box model used for this box.

    .box { border: 1px solid black; padding: 10px; margin: 10px; - width: 200px; - height: 200px; + width: 100px; + height: 100px; } - -.block { display: block; } -.inline { display: inline; } -Block box -Inline box`} +
    Box
    `} solution={` -Block box -Inline box`} +
    Box
    `} />

    @@ -214,65 +216,243 @@ const Kata: NextPage = () => ( display: block; border: 1px solid black; padding: 10px; - width: 200px; - height: 200px; + width: 100px; + height: 100px; } -Block box`} +Box`} + /> +

    + +
    + Layouts + +

    + The box characteristics are computed from the CSS properties depending on the + current layout. +

    + +

    + There are four main layouts to know: Flow, Table, Flex and Grid. We will see each of them in + following katas.{' '} + + After learning all the main layouts, you’ll have a good understanding of which one is the + more adapted to your specific case. + +

    + + + } + alt="" + caption="The most common layouts" /> + +

    + + A layout is a set of rules and CSS properties to dictate how boxes will interact with each + other. + +

    + +

    Let me list some implications of this definition:

    + + + +

    + You should see layouts as a toolbox: within the context of a layout, you’ll + be able to predict how elements will place next to each other. You don’t like a layout’s + ruleset? Change your toolbox and use another layout. +

    - Help! I broke the box model + + The display property + + +

    + + You can switch between layouts with the{' '} + + display + {' '} + property. + {' '} + This property have two possible syntaxes: +

    + + + +

    + In this kata we’ll learn this property with its full, two values syntax to better understand + what happens. This syntax specify the outer display type and the{' '} + inner display type. +

    + +
    +
    + The outer display type +
    +
    + This defines how the element should behave in the context of the parent layout,{' '} + if the parent layout is Flow. Possible values are block and{' '} + inline. If the parent layout is not Flow, the outer display type is ignored. +
    +
    + The inner display type +
    +
    + This defines how the element’s children will lay out. Possible values include{' '} + flow, table, flex, grid and many + more... +
    +
    -

    If you played a bit with the live editor, you may have noticed two issues.

    + + } + alt="" + caption="The outer and inner display types" + style={{ maxWidth: '20rem' }} + /> + +

    Think of it like this:

    + + + +

    For legacy reason we usually use shorthands, for instance:

    + + + + + Shorthand + Two-value syntax + + + + + {[ + ['block flow', 'block'], + ['inline flow', 'inline'], + ['block flex', 'flex'], + ['inline grid', 'inline-grid'], + ].map(([fullSyntax, shorthand]) => ( + + + {shorthand} + + + {fullSyntax} + + + ))} + +
    + +

    + Shorthands are not a bad thing and you should continue to use them, however + the two value syntax is better for learning purposes. +

    +.container { + flex-direction: column; + align-items: center; + gap: 10px; +} .box { border: 1px solid black; padding: 10px; - margin: 10px; - width: 200px; - height: 200px; } - -.block { display: block; } -.inline { display: inline; } +.child { + width: 50px; + height: 50px; +} -Block box -Inline box`} +
    +
    Box 1
    +
    Box 2
    +
    Box3
    +
    `} solution={` -Block box -Inline box`} +
    +
    Box 1
    +
    Box 2
    +
    Box3
    +
    `} /> -

    No worries! We’re going to understand what happens in the next two katas:

    - - +

    + We will see the Flex layout in a further kata, our next goal is learning the Flow layout + (the default layout!). +

    @@ -280,15 +460,22 @@ const Kata: NextPage = () => ( diff --git a/app/(main)/learn/basics/the-flow-layout/boxes-grouping.svg b/app/(main)/learn/basics/the-flow-layout/boxes-grouping.svg new file mode 100644 index 0000000..c53f0e2 --- /dev/null +++ b/app/(main)/learn/basics/the-flow-layout/boxes-grouping.svg @@ -0,0 +1,17 @@ + + + + + + + + Unwrapped textUnwrapped textBlock-level boxesInline-level boxesBlock Formatting ContextAnonymous block-level boxAnonymousinline-level box \ No newline at end of file diff --git a/app/(main)/learn/basics/the-flow-layout/flow-layout.svg b/app/(main)/learn/basics/the-flow-layout/flow-layout.svg new file mode 100644 index 0000000..9f44e68 --- /dev/null +++ b/app/(main)/learn/basics/the-flow-layout/flow-layout.svg @@ -0,0 +1,17 @@ + + + + + + + + Image \ No newline at end of file diff --git a/app/(main)/learn/basics/the-flow-layout/flow-recursion.svg b/app/(main)/learn/basics/the-flow-layout/flow-recursion.svg new file mode 100644 index 0000000..7834612 --- /dev/null +++ b/app/(main)/learn/basics/the-flow-layout/flow-recursion.svg @@ -0,0 +1,17 @@ + + + + + + + + Block Formatting Contextdisplay: block flow;In the flow display: block flow;display: inline flow;display: inline flow;In the flow In the flow In the flow display: block flex;display: block flow;In the flow Not in the flow \ No newline at end of file diff --git a/app/(main)/learn/basics/the-flow-layout/formatting-contexts.png b/app/(main)/learn/basics/the-flow-layout/formatting-contexts.png deleted file mode 100644 index 59e5c16..0000000 Binary files a/app/(main)/learn/basics/the-flow-layout/formatting-contexts.png and /dev/null differ diff --git a/app/(main)/learn/basics/the-flow-layout/inner-outer-display.png b/app/(main)/learn/basics/the-flow-layout/inner-outer-display.png deleted file mode 100644 index 4671d8f..0000000 Binary files a/app/(main)/learn/basics/the-flow-layout/inner-outer-display.png and /dev/null differ diff --git a/app/(main)/learn/basics/the-flow-layout/layouts.png b/app/(main)/learn/basics/the-flow-layout/layouts.png deleted file mode 100644 index e601385..0000000 Binary files a/app/(main)/learn/basics/the-flow-layout/layouts.png and /dev/null differ diff --git a/app/(main)/learn/basics/the-flow-layout/page.tsx b/app/(main)/learn/basics/the-flow-layout/page.tsx index e405dd7..795821b 100644 --- a/app/(main)/learn/basics/the-flow-layout/page.tsx +++ b/app/(main)/learn/basics/the-flow-layout/page.tsx @@ -6,260 +6,213 @@ import { Image } from 'components/Image'; import { PAGES } from 'services/pages'; import { Editor } from 'components/Editor'; import { Exercise } from 'components/Exercise'; -import { - Table, - TableBody, - TableCell, - TableHeader, - TableHeaderCell, - TableRow, -} from 'components/Table'; import { KataQuestions } from 'components/KataQuestions'; import TypographyImage from 'app/(main)/learn/basics/styling-text-custom-fonts/typography.svg'; import anonymousBoxImage from './anonymous-box.png'; -import layoutsImage from './layouts.png'; -import formattingContextsImage from './formatting-contexts.png'; -import innerOuterDisplayImage from './inner-outer-display.png'; +import FlowLayoutImage from './flow-layout.svg'; +import FlowRecursionImage from './flow-recursion.svg'; +import BoxesGroupingImage from './boxes-grouping.svg'; const Kata: NextPage = () => ( <> {PAGES.FlowLayout.title} +

    + Prerequisite: knowledge from the{' '} + Box model and Layout kata is necessary to + understand the concept of outer/inner display types. +

    +

    - Read this kata carefully. It may be the most important kata of the dojo as it - addresses the most commonly misunderstood concepts of CSS and thus is one of the biggest - sources of CSS frustration. + The Flow layout is the basic default layout and is optimized for the primary role of a webpage + (like this one): display lines of text content with eventual boxes (such as images) between + paragraphs.

    -
    - What is a layout? + } + alt="" + caption="A simple representation of the Flow layout" + style={{ maxWidth: '20rem' }} + /> -

    - So far, we’ve learned CSS properties to style one element and change its color, - width, font size... but web pages are made of hundreds, often thousands of elements. -

    +

    + + This may be the most important part of the dojo. The Flow layout is the default layout and + thus applies almost everywhere in a web page. By learning it correctly, many CSS + frustrations will disappear. + +

    + +
    + The Block Formatting Context (BFC)

    - - A layout is a set of rules and CSS properties that dictates how multiple{' '} - elements will interact between each other. - {' '} + The Flow layout always happens in a{' '} + + Block Formatting Context + + . A BFC is created in certain conditions, including by:

    -

    Let me list some implications of this definition:

    -
    • - A layout rules how CSS properties will interact. It may use specific CSS properties (such - as flex-direction for the flex layout),{' '} - - but it will also make use of standard properties (width,{' '} - margin...) - + The root html element
    • - Layout having different sets of rules, this means that a{' '} - - CSS value (such as width: auto;) can behave differently in the context of - different layouts - + Flex and Grid items if they are neither Flex nor Grid nor Table containers themselves
    • - It also means that some layout-specific properties (such as float) will be - completely useless in the context of other layouts + Elements with position: fixed or position: absolute
    • - Layout rulesets can introduce very specific behaviors (such as margin collapsing) - that will not be transposed to other layouts + Elements having the flow-root inner display type +
    • +
    • + + And many other cases that you can find on MDN +
    • -
    • Each CSS layout has its own CSS specification
    -

    - You should see layouts as a toolbox: within the context of a layout, you’ll - be able to predict how elements will place next to each other. You don’t like a layout’s - ruleset? Change your toolbox and use another layout. -

    - -

    - There are four main layouts: flow (the default one), flex, grid, - and table. There are others, but they are more anecdotic.{' '} - - As flow is the default layout and you won’t use flex on every single DOM - element ever, you MUST master it. There is no way around it. Let me repeat - that: No. Way. Around. It. - {' '} - This is the goal of this kata. -

    - -

    - Other layouts will be addressed in the second part of the dojo. After learning all the main - layouts, you’ll have a good understanding of which one is the more adapted to your specific - case. -

    - -

    - Again,{' '} - - a layout is a set of rules and CSS properties that dictates how multiple{' '} - elements will interact between each other. - {' '} -

    -
    - -
    - The formatting contexts - -

    - Hold on to your butts, because this kata is probably the most difficult part of this whole - website but also the most important. -

    - -

    - The flow layout introduces a concept: the formatting context. Think of it as a - mini-layout inside the flow layout. The spec says that there are two formatting - contexts in the flow layout: -

    - -
    -
    - The block formatting context -
    -
    - Block boxes are laid out vertically, one after the other, beginning at the top of a - containing block. -
    -
    - The inline formatting context -
    -
    - Inline boxes are laid out horizontally, one after the other, beginning at the top of a - containing block. -
    -
    +

    Inside a BFC, the browser will recursively crawl every nested element:

    -

    - We’ll see how each formatting context works further down, but for now, keep in mind that - there are block and inline contexts. -

    - -

    - For this dojo, we will be working in English but take note that in other languages the - writing mode of the page could change and invert the block and inline directions to - horizontal and vertical respectively. -

    - -

    Let’s sum up what we’ve learned:

    +
      +
    • + + If the element has a flow inner display type, the browser will flag the + element and its children as participating in the flow layout. + {' '} + We also say that the elements are in the flow. It will then scan the inner + display type of the children and continue. +
    • +
    • + If the element have something else than the flow inner display type, the + element itself will participate in the flow but its children will not be added to the flow + and the browser will stop there. +
    • +
    A drawing showing the four main layouts and the formatting contexts under the flow layout + } + alt="" + caption="Will the box be in the flow or not?" + style={{ maxWidth: '30rem' }} />

    - How do I know which formatting context applies? This is one of the most - confusing parts of CSS, because it is implicit. There are four rules: + + Reminder: most elements will have a default display value that will make them participate + in the flow. +

    -
      -
    1. - A formatting context always applies inside a block container box. We will see - later how to create a new block container box but the <html>{' '} - element creates the higher one in the box tree -
    2. -
    3. - A block container box having only inline-level boxes as children will - have an inline formatting context -
    4. +
      • - A block container box having only block-level boxes as children will - have a block formatting context + Elements such as <p>, <section> or{' '} + <div> will have a default of display: block flow;{' '} + (shorthand: display: block;)
      • - There can be no mixup between block-level boxes and inline-level boxes{' '} - in a block container box + Elements such as <strong>, <em> or{' '} + <span> will have a default of display: inline flow;{' '} + (shorthand: display: inline;)
      • -
    +

    - (Yes I know that using block container box and block-level box is super - confusing but those are the exact terms in the spec.) + When every nested element is scanned, the browser ends up with a soup of boxes that + participate in the flow and that will be used for the layout algorithm.

    +
    + +
    + Inline and block boxes grouping

    + Once the browser have determined which boxes will participate in the flow,{' '} - But what are block-level and inline-level boxes? - {' '} - Remember, in CSS everything is a box. - Text-related elements such as <strong>, <em> or{' '} - <span> will create inline-level boxes. Other elements such as{' '} - <p>, <section> or <div> will create - block-level boxes. + it looks at their outer display type (which is either block or{' '} + inline) and create block-level boxes and inline-level boxes{' '} + accordingly. + +

    + +

    + One more definition: we call a block container box any box that will contain{' '} + block-level boxes or inline-level boxes. (Yes I know that using{' '} + block container box and block-level box is super confusing but those are + the exact terms in the spec.)

    -html { - border: 1px solid red; -} -html .child { - border: 1px solid black; -} +.parent { border: 1px solid red; } +.child { border: 1px solid black; } -Inline-level -boxes -in a block container box`} +
    + Inline-level + boxes + in a block container box +
    `} /> -html { - border: 1px solid red; -} -html .child { - border: 1px solid black; -} +.parent { border: 1px solid red; } +.child { border: 1px solid black; } -
    Block-level
    -
    boxes
    -
    in a block container box
    `} +
    +
    Block-level
    +
    boxes
    +
    in a block container box
    +
    `} /> +

    + There is only one rule with block container boxes: a block container boxes{' '} + must contain only block-level boxes or only inline-level boxes.{' '} + + There can be no mixup between block-level boxes and inline-level boxes in a block + container box + +

    +

    What if I have some text that is not wrapped in inline elements such as{' '} <span>? {' '} - In order to fix the rule of the inline formatting context (it must contain only inline-level - boxes), the browser creates anonymous inline-level boxes around unwrapped text. You can’t - select them with CSS but you can still inspect them with the dev tools. + In order to have only inline-level boxes in the parent block container box, the browser + creates anonymous inline-level boxes around unwrapped text. You can’t select them with CSS + but you can still inspect them with the dev tools.

    -html { - border: 1px solid red; -} -html .child { - border: 1px solid black; -} +.parent { border: 1px solid red; } +.child { border: 1px solid black; } -Anonymous inline-level -boxes -in a block container box`} +
    + Anonymous inline-level + boxes + in a block container box +
    `} /> <span> and{' '} <block>? {' '} - In order to fix the rule of the block formatting context (it must contain only block-level - boxes), the browser creates anonymous block-level boxes around inline-level children. Again, + In order to have no mixup of block-level boxes and inline-level boxes in the block container + box, the browser creates anonymous block-level boxes around inline-level children. Again, you can’t select them with CSS and you can’t inspect them with the dev tools (but trust me, they are here).

    -html { - border: 1px solid red; -} -html .child { - border: 1px solid black; -} - - -Anonymous block-level -
    boxes
    -in a -block container box`} - /> - -

    - One thing that must be cleared up before going forward is that all these layout rules are - about boxes, not elements. DOM elements can create inline and block-level - boxes, but then you can forget about the DOM and only think in term of boxes. -

    - -

    - Furthermore, when creating boxes the browser will look at all the descendants in the DOM - tree.{' '} - - By default, every element will be handled by its nearest parent block container box - - . We say that it will participate in the parent’s formatting context, or that it’s{' '} - in the flow. That’s why the example below renders exactly the same as the example - above, even if the DOM is different. All boxes are handled by the nearest block container - box (created by the <html> element). -

    - - -html { - border: 1px solid red; -} -html .child { - border: 1px solid black; -} +.parent { border: 1px solid red; } +.child { border: 1px solid black; } - -Anonymous block-level
    boxes
    -in a -block container box`} +
    + Anonymous block-level +
    boxes
    + in a + block container box +
    `} />

    - If we try to sum up all of this, the browser takes all the elements, turns them into boxes - (block-level and inline-level boxes), arrange them in a block container box, introduces - anonymous block-level and inline-level boxes and creates formatting contexts accordingly. + If we try to sum up all of this, the browser takes all elements participating in the flow in + a block formatting context, turns them into boxes (block-level and inline-level boxes), + arrange them in block container boxes and introduces anonymous block-level and inline-level + boxes accordingly.

    A drawing showing squares and lines at the top to represent block and inline boxes, and at the bottom the same squares and lines arranged in boxes and formatting contexts + } + alt="" + caption="An example of block-level and inline-level boxes grouping" + style={{ maxWidth: '30rem' }} /> -
    - -
    - Mastering the formatting contexts

    @@ -354,36 +271,32 @@ in a -html { - border: 1px solid red; -} -html .child { - border: 1px solid black; -} +.parent { border: 1px solid red; } +.child { border: 1px solid black; } -Inline-level -boxes -in a block container box`} +

    + Inline-level + boxes in a + block container box +
    `} solution={` -Inline-level -boxes
    this is a block!
    -in a block container box`} +
    + Inline-level + boxes
    this is a block!
    in a
    + block container box +
    `} />

    Remember, we are dealing with boxes here.{' '} - A formatting context doesn’t care about DOM elements. It only cares about block-level - boxes and inline-level boxes. + The Flow layout doesn’t care about DOM elements. It only cares about block-level boxes and + inline-level boxes. {' '} The browser will see five boxes to group together:

    @@ -396,125 +309,24 @@ html .child {
  • The block-level box created by the <div> element
  • -
  • - An empty anonymous inline-level box resulting from the split of the middle{' '} - <span> -
  • +
  • An anonymous inline-level box containing the " in a" text
  • An inline-level box created by the last <span>
  • - Thus, the <div> breaks the inline formatting context and forces a block + Thus, the <div> breaks the "no-mixup rule" and forces a block formatting context by introducing anonymous block-level boxes around the groups of inline-level boxes. The browser tries to reconcile other CSS properties in the most logical way possible. Here, you can see that there is a border on the bottom, left and top sides of - the first anonymous inline-level box and the right border is on the last anonymous and empty - inline-level box (increase the border’s width if it is not clear enough). -

    - -

    - - To change the default behavior of DOM elements, you must use the{' '} - - display - {' '} - property. - {' '} - This property has two possible syntaxes: - display: [outer] [inner]; property is most commonly used with shorthands ( - block, inline, flex...) but here we’ll learn it with - its full syntax to understand what happens. -

    - -
      -
    • - display: [shorthand];: the old syntax, supported by all browsers -
    • -
    • - display: [outer] [inner];: the new, full syntax,{' '} - - supported by Firefox and Safari but not Chrome (yet) - -
    • -
    - -

    - In this kata we’ll learn this property with its full, two values syntax to better understand - what happens.{' '} - - If you are on Chrome, you can temporarily switch to Firefox/Safari or use this matching - table to achieve the same results: - -

    - - - - - Two-value syntax - Shorthand - - - - - {[ - ['block flow', 'block'], - ['inline flow', 'inline'], - ['block flow-root', 'flow-root'], - ['inline flow-root', 'inline-block'], - ].map(([fullSyntax, shorthand]) => ( - - - {fullSyntax} - - - {shorthand} - - - ))} - -
    - -

    - Now that we’ve cleared up these two syntax, let’s see how the{' '} - display: [outer] [inner] property works. -

    - -
    -
    - The outer display type -
    -
    - This defines how the element should behave in the context of its parent. Possible values - are block and inline. -
    -
    - The inner display type -
    -
    - This defines how the element’s children will lay out. Possible values are{' '} - flow (participate in the parent’s formatting context), flow-root{' '} - (create an independent formatting context using the flow layout), and other layout - keywords such as flex and grid. -
    -
    - -

    - Thus, a <span> element defaults to display: inline flow;{' '} - (same as display: inline;) and a <div> element defaults to{' '} - display: block flow; (same as display: block;). + the first anonymous inline-level box and the right border is on the last anonymous + inline-level box.

    - A table of display types combining outer display inline and block with inner display flow and flow-root -

    - Now, let’s say we have a paragraph of elements forming an inline formatting context. We also - have a block element, for instance a button, that we want to inline in our text. + Now, let’s say we have a paragraph with inline-level boxes. We also have a block element, + for instance a button, that we want to inline in our text. How can we do this?

    button in the middle of i parent) but also implicitly setting the inner display type to flow. If the inner display type is flow, the children of our button will participate in the parent flow. The only child of our button is an unwrapped text, therefore an anonymous - inline-level box, therefore an inline formatting context will apply everywhere and our - button will lose some of its block-level box properties that we want to keep. By choosing{' '} - flow-root, we force the creation of an independent block formatting context. + inline-level box, therefore our button will lose some of its block-level box properties that + we want to keep. +

    + +

    + By choosing flow-root, we force the creation of an independent Block Formatting + Context. The BFC will introduce a root block container box that will honor block-level boxes + properties.

    - Good! At this stage, you should have a good grasp of when and where formatting contexts - apply, and how to switch between them. + Good! At this stage, you should have a good grasp of how block-level boxes and + inline-level boxes are organized, and how to alter this organization. {' '} Don’t hesitate to let your brain cool off and think about it twice. I’m repeating myself but it probably is the most confusing concept about CSS, and it is really important to truly{' '} understand it.

    + +

    + We then move on to the final part of the layout algorithm.{' '} + + Right now, we have a boxes tree with block container boxes containing only block-level + boxes or only inline-level boxes. + +

    +
      +
    1. + Inside a block container box containing only block-level boxes, the + browser will apply block formatting +
    2. +
    3. + Inside a block container box containing only inline-level boxes, the + browser will apply inline formatting +
    4. +
    +
    - The block formatting context + Block formatting

    - Now that you know what are formatting contexts and where they apply, we can learn their - rules. Remember, a{' '} - - layout is a set of rules and CSS properties that dictates how multiple{' '} - elements will interact between each other, - {' '} - and a formatting context is a mini-layout inside the flow layout. Let’s learn the rules of - the block formatting context. + When a block container box has only block-level boxes as children,{' '} + block formatting applies:

      @@ -631,9 +461,9 @@ This is some text that has a
      button
      in the middle of i
    -html { +.container { border: 1px solid red; } div { @@ -641,18 +471,19 @@ div { } -
    Block-level box A
    -
    -
    Block-level box B
    -
    Block-level box C
    -
    -
    Block-level box D
    -
    Block-level box E
    +
    +
    Block-level box A
    +
    +
    Block-level box B
    +
    Block-level box C
    +
    +
    Block-level box D
    +
    Block-level box E
    +
    -
    -`} +
    `} solution={` -
    Block-level box A
    - -
    -
    Block-level box B
    - - Inline part -
    Block-level box C
    - - -
    -
    Block-level box D
    -
    Block-level box E
    +
    +
    Block-level box A
    + +
    +
    Block-level box B
    + + Inline part +
    Block-level box C
    + + +
    +
    Block-level box D
    +
    Block-level box E
    +
    `} @@ -685,10 +518,11 @@ div {
    - The inline formatting context + Inline formatting

    - Next, we learn the rules for the inline formatting context. Let’s bring up the schema from{' '} + When a block container box has only inline-level boxes as children,{' '} + inline formatting applies. Let’s bring up the schema from{' '} the styling text kata to understand what is the line height and the baseline:

    @@ -704,17 +538,40 @@ div {
    • - Boxes are laid out on the baseline one after the other horizontally in the writing - direction + Boxes are laid out one after the other horizontally in the writing direction (left to + right in English, but could be right to left in other languages such as Arabic)
    • If there is not enough space, the boxes break into a new line
    • You can’t set width or height on inline boxes
    • -
    • The height of a line is defined by the tallest box in it
    • Margins work only in the inline direction
    + + html { + border: 1px solid red; + } + .box { + border: 1px solid black; + height: 100px; /* doesn't work :( */ + width: 100px; /* doesn't work :( */ + margin-bottom: 200px; /* doesn't work :( */ + margin-right: 30px; /* works */ + } + + +
    + Some line of text.
    + Text of this box is really nice. This is also a very long line that should wrap at the end of the line.
    +
    `} + /> + +
      +
    • The height of a line is defined by the tallest box in it
    • +
    + @@ -722,26 +579,18 @@ html { border: 1px solid red; } .first { - margin-right: 30px; /* works */ - margin-bottom: 200px; /* doesn't work :( */ - height: 3rem; /* doesn't work :( */ + border: 1px solid black; } .second { + border: 1px solid black; }
    - Some line of text.
    - Some line of text.
    Some line of text.
    Text of the first line is really nice.
    Some line of text.
    - Some line of text.
    - Some line of text.
    - But the text of the second line looks better. - Some line of text.
    - Some line of text.
    - Some line of text.
    + But the text of the second line looks better.
    Some line of text.
    `} solution={`
    - Some line of text.
    - Some line of text.
    Some line of text.
    Text of the first line is really nice.
    Some line of text.
    - Some line of text.
    - Some line of text.
    - But the text of the second line looks better. - Some line of text.
    - Some line of text.
    - Some line of text.
    + But the text of the second line looks better.
    Some line of text.
    `} /> @@ -782,9 +623,9 @@ html { vertical-align {' '} property sets how an inline-level box should behave in the vertical direction. Possible - values are baseline (the default), top (the box will stick to - the top of the line), bottom (same but at the bottom of the line),{' '} - middle (centers vertically inside the line,{' '} + values are baseline (the default, will align the baselines of the boxes),{' '} + top (the box will stick to the top of the line), bottom (same + but at the bottom of the line), middle (centers vertically inside the line,{' '} which is not the same as baseline! @@ -792,6 +633,7 @@ html { values: + html { @@ -882,87 +724,42 @@ And here is another line. In the HTML it has an empty line before it, but it doe

    Ooof! That was a hard one. Now you should have enough knowledge to truly understand and use - the flow layout! In the next katas, we’ll focus on edge case behaviors that break - the flow layout such as overflowing content and positioned elements. + the Flow layout!

    • - - Layouts are rulesets that enable developers to place elements relative to each other - -
    • -
    • - There are four main layouts: flow (the default one), flex, grid - , and table -
    • -
    • - The flow layout has two mini-layouts: the block formatting context and the{' '} - inline formatting context -
    • -
    • - The formatting contexts are applied at the block container box level. The{' '} - <html> element creates a block container box,{' '} - display: flow-root; is another way to create one -
    • -
    • - Inside a block container box, the browser turns all DOM elements into block-level - and element-level boxes (including all descendants, by default they{' '} - participate in the parent formatting context) -
    • -
    • - A block (or inline) formatting context will be used if all children are{' '} - block (or inline)-level boxes -
    • -
    • The browser fixes the box tree with anonymous block-level and inline-level boxes
    • -
    • - The display: [outer] [inner]; property changes the{' '} - outer display type and inner display type of an element + The Flow layout happens in a Block Formatting Context (BFC) created by the{' '} + flow-root inner display type{' '} + + and many other cases that you can find on MDN + + .
    • - The outer display type tells the browser if the element should behave as a - block-level or inline-level box in the context of its parent block container box + All nested boxes in a BFC that have the flow inner display type and + their children will participate in the layout.
    • - The inner display type tells the browser what layout should apply inside the - element. For instance, flow, flow-root, flex, and{' '} - grid are all valid values + Inside a BFC, the browser will group block-level and inline-level boxes so that there is + no mix of block-level and inline-level boxes using anonymous block-level and{' '} + anonymous inline-level boxes.
    • - You’ll always see and use those shorthands: -
        -
      • - display: block; is the same as display: block flow; -
      • -
      • - display: inline; is the same as display: inline flow; -
      • -
      • - display: inline-block; is the same as{' '} - display: inline flow-root; -
      • -
      • - display: flex; is the same as display: block flex; -
      • -
      • - display: inline-flex; is the same as display: inline flex; -
      • -
      • - (same thing with grid and table) -
      • -
      + Block (or inline) formatting will be used if all children of a{' '} + block container box are block (or inline)-level boxes.
    • - The rules of the block formatting context are: + The rules of block formatting are:
      • Boxes lay out vertically and consume all the space in the inline direction
      • Margins collapse between adjacent boxes that don’t have content between them
    • - The rules of the inline formatting context are: + The rules of inline formatting are:
        -
      • Boxes are laid out horizontally on the baseline
      • +
      • Boxes are laid out horizontally with their baselines aligned
      • There are restrictions on width, height and{' '} margin diff --git a/components/Table/Table.module.scss b/components/Table/Table.module.scss index dca0615..3e1b7c1 100644 --- a/components/Table/Table.module.scss +++ b/components/Table/Table.module.scss @@ -8,7 +8,7 @@ .table { border-collapse: collapse; - width: 100%; + margin: 0 auto; } .table-header-cell { diff --git a/services/skills.tsx b/services/skills.tsx index 5e9ed55..596a031 100644 --- a/services/skills.tsx +++ b/services/skills.tsx @@ -99,35 +99,39 @@ export const SKILLS = { }, 'box-model-alternatives': { skill: 'What are the two possible box models?', - kataUrl: PAGES.TheBoxModel.url() + '#i-broke-the-box-model', + kataUrl: PAGES.TheBoxModel.url() + '#box-sizing-property', }, 'box-model-layout': { skill: 'In CSS, what is a layout?', - kataUrl: PAGES.TheBoxModel.url() + '#definition', + kataUrl: PAGES.TheBoxModel.url() + '#layouts', }, 'box-model-common-layouts': { skill: 'What are the most common layouts?', - kataUrl: PAGES.TheBoxModel.url() + '#definition', + kataUrl: PAGES.TheBoxModel.url() + '#layouts', }, 'box-model-outer-inner-display': { skill: 'What are the outer and inner display types?', - kataUrl: PAGES.TheBoxModel.url() + '#mastering-formatting-contexts', + kataUrl: PAGES.TheBoxModel.url() + '#display', + }, + 'flow-layout-block-formatting-context': { + skill: 'What is a Block Formatting Context?', + kataUrl: PAGES.FlowLayout.url() + '#block-formatting-context', }, 'flow-layout-boxes': { skill: 'How inline and block boxes are laid out in the Flow layout?', - kataUrl: PAGES.FlowLayout.url() + '#definition', + kataUrl: PAGES.FlowLayout.url() + '#inline-block-boxes-grouping', }, - 'flow-layout-block-formatting-context': { - skill: 'What are the rules of the block formatting context?', - kataUrl: PAGES.FlowLayout.url() + '#block-formatting-context', + 'flow-layout-block-formatting': { + skill: 'What are the rules of block formatting?', + kataUrl: PAGES.FlowLayout.url() + '#block-formatting', }, 'flow-layout-margin-collapsing': { skill: 'How does margin collapsing work?', - kataUrl: PAGES.FlowLayout.url() + '#block-formatting-context', + kataUrl: PAGES.FlowLayout.url() + '#block-formatting', }, - 'flow-layout-inline-formatting-context': { - skill: 'What are the rules of the inline formatting context?', - kataUrl: PAGES.FlowLayout.url() + '#inline-formatting-context', + 'flow-layout-inline-formatting': { + skill: 'What are the rules of inline formatting?', + kataUrl: PAGES.FlowLayout.url() + '#inline-formatting', }, } satisfies { [key: string]: Skill };