Borislav Hadzhiev
Wed Mar 10 2021·7 min read
Photo by Evan Brockett
Most of the time - if you need to set height, set a min height because when you set a specific height things can overflow when you make the screen more narrow (mobile screen). Or when the content increases, someone adds an extra paragraph and it overflows.
By default the height of an element is determined by the content that's inside of it. If you add more content the height grows. Min-height means the height can't be less than the specified amount, but if it needs to grow with the content it will.
You should still set a height on icons / images to avoid cumulative layout shift.
The size of an element is influenced by it's containing block. If we set the width of an element using percentages, that is a percentage of its containing block's width.
If we set width 80%
on an element, that means 80%
of its parent's total
width.
When we use position: absolute;
the containing block of an element is no
longer its parent, but instead its nearest ancestor which has position other
than static. If there is no ancestor element with position other than static,
the containing block is the root html element.
When using position:fixed;
the containing block of that element is the
viewport.
With box-sizing: border-box;
the size is not determined by the content or the
content-box
(it's called CONTENT box because you just set the size of the
CONTENT), but by the border-box
(includes the content, padding and border).
.box { box-sizing: border-box; width: 100px; padding: 20px; border: 10px solid red; margin: 10px; }
In the above example the 100px
width includes - the border, padding
and content. It's called BORDER box because inside your border - you have
your border, your padding and your content.
Margin is not included in the border-box
because margin is space between
elements, not the element itself.
Set the box-sizing
to border-box
for all elements and pseudo elements:
*, *::before, *::after { box-sizing: border-box; }
Anything related to typography
will be inherited from the children -
font-size
, font-family
, text-decoration
, text-align
, color
. That's why
we often place font-family
or font-size
or font-weight
on our html
element - because they're inherited from the children of that element. You can
overwrite the inherited properties by explicitly specifying them on the child
element.
Anything that is set by default by the browser, i.e. links
, headings
,
won't inherit.
Nothing related to layout is inherited - margin
, padding
, height
, width
,
position
are not inherited by children.
By default button
, input
, select
, textarea
elements don't inherit
anything because of the browser defaults. You can explicitly specify that you
want these elements to inherit:
a { color: inherit; } button, input, select, textarea { font-family: inherit; }
The cascade looks at:
important
is frowned upon and sloppy.#ids
or
.class .innerClass
selectors. Because when we raise specificity if we need
to override it in the future it can be annoying. If we eliminate specificity
and use just classes tailwind style, we have less things to think about. And
if we don't have specificity wars we don't have to use !important
anyway..css
file.red { background: red; } .blue { background: blue; }
<div class="blue red">Hi there</div>
It doesn't matter what order you put the classes in the class string, but the
order they appear in your .css
file. So the .blue
definition will override
the .red
one.
If a selector comes after another equal selector, it tends to win.
In a website everything is a box within a box, within a box. Everything participates in a formatting context.
There are rules for how elements behave when inside a specific formatting context.
Understanding these rules is very important when trying to create and manage layouts.
Inline Formatting context - elements like span
, strong
, em
, links
.
Block level elements either contain other Block level elements, or Inline
elements, but not both. If we have a paragraph
or a div
, they can either
contain other block level elements or they can contain inline elements, but
not both.
<div> lorem ipsum <p>dolor sit</p> amet consectur </div>
The browser takes the inline text and converts it to block level elements behind the scenes. It wraps the text on top and bottom and the text becomes block level elements.
Inside of Block formatting context, your content is laid out one on top of each
other, even if there is room, they won't try to squeeze in. Even if you set
width of 30%
on 2 divs
, they won't try to be on the same line next to one
another, they'll be still placed one on top of the other.
100px
, the margins will collapse and it
will only be 100px
of margin between the divs. The bigger margin wins and
remains, the smaller margin is collapsed.If you create a new block formatting context, you can stop margins from collapsing. Ways to create a block formatting context include:
Using floats
Position absolute
, fixed
and inline-block
overflow
of anything except visible
using columns
flex
and grid
items
display flow-root
When you display: flex;
you are establishing the flex
formatting
context. It is similar to a block formatting context, but with a few
differences:
Z-index influences the way html elements stack on top of one another. When we
use positioning we start overlaying elements on top of one another. A higher
z-index
pushes the element higher in the stack and a lower number - lower.
Z-index can't be used in isolation, we need other properties to use z-index
.
When there is no z-index
applied, and no positioning, html elements stack in
the order they appear in the HTML. The last element wins and is rendered on top
of the other. This is also true if elements have an equal z-index
.
When we apply a position other than static
(the default) to an element, it
will be rendered on top.
We can apply z-index
only to positioned elements (not static). Z-index doesn't
have effect on elements with static position. Z-index can also be negative
value - i.e. -10
.
The default z-index
is 0
.
We can also use z-index
on flex
and grid
items.
When we create a new stacking context, we isolate the z-index
to that group of
elements in the stacking context. So when we create a new stacking context
z-index
is no longer relative to the root html element, it's relative to that
individual stacking context.
You can influence the way flexbox updates the size of the flex
items with the
properties:
Flex-basis is the size of a flex item on the main axis. The main axis in
flex changes according to the flex-direction
property. So flex-direction
changes the direction flex-basis
works in. If you had a flex-direction
column - flex-basis
would be looking at the height
instead of the width
.
By default flex-direction
is row
and flex-basis
looks at the width
property.
The default of flex-basis
is auto
. If we don't set a flex-basis
on a
flex-item, the default behavior is to set the flex-basis
to auto
, so it
looks at the content of an element. The content inside of a flex item dictates
how big the flex item is displayed. If the content is the same and
flex-direction
is row then the widths are equal. If one of the flex-items has
less content - flexbox assumes it doesn't need as much room.
If you set flex-basis
to 100%, all flex items become equal. We're saying
all flex-items should be 100% of the parent's size, but they can't all be 100%
of the parent's size, that's where the default value of flex-shrink
comes in -
elements are shrunk by equal proportions and now they're the same size.
Flex-shrink - allows / disallows flex items to shrink as the viewport narrows.
The default value for flex-shrink
is 1
. If flex-shrink
is a number greater
than 0 - the flex item is allowed to shrink (become smaller) than its actual
size if there isn't enough room. Without flex-shrink
and flex-wrap
elements
would overflow out of the side and flexbox layout would not be very useful.
So with flex-basis
, we're saying how big a flex item should be and with
flex-shrink
positive integer - we're allowing the flex item ot be smaller than
that. If flex-shrink
is set to 0, it means the flex-item
is not allowed to
shrink.
Flex-grow defines the ability for a flex item to grow if necessary. It dictates what amount of the available space inside the flex container the item should take up.
If all flex items have flex-grow
set to 1
, every child will be set to an
equal size inside the flex container. If you were to give one of the children a
flex-grow
of 2
, that flex item would take twice as much space.
Default value for flex-grow
is 0
, which means elements are not allowed to
grow by default.