Properties
Positioning
position - sets position type. each type has its own characteristics
top, right, bottom, left - properties used to position element
- auto - default value
inset - is a shorthand for top, right, bottom, left
z-index - is used to work with layers. might be negative number, positive number or 0
- auto - default value. auto is less than 1
5 Position Values
static - default
relative - element can be positioned relatively to its static position. positioning of such element doesn't affect nearby elements
absolute - element can be positioned relatively to the nearest non-static container
- element is being removed from the flow of the document
- element becomes a block
- width decreases to the width of content
- tricks:
- left: 0; right: 0; - stretch element. analog of "width: 100%"
- margin: 0 auto; - it is still possible to center absolute element
- to make absolute element scrollable, height should be set. e.g. max-height: 100%
fixed - element can be positioned relatively to the viewport
- by default stays on its static position
sticky - element sticks when it gets to the defined position relatively to the viewport
- works within parent element's borders
- unlike "position: fixed", sticky doesn't fall out of the elements flow
- element should be initially correctly placed. e.g. in case element should stick to bottom, it should be located at the end (bottom) of the container
- tricks:
- since sticky element doesn't fall out of the flow, it can be part of flex or grid layout. e.g. sticky can be used for constantly visible sidebar
Specifics
containing block issue - when filter or transform property is set on element, containing block is being created for absolute & fixed positioned descendants
- fixed element will be positioned relatively to the container (with filter or transform) instead of viewport
stacking context issue - if parent element has lower z-index than its sibling, child can't overflow that sibling
- child can still compete with its own siblings
- stacking contexts have hierarchy
Box Model
display
- block
- inline
- inline-block - see CSS Basic -> Box Model
- flex - see Flex
- grid - see Grid
- none - element disappears from page
"display: none" vs "visibility: hidden" vs "opacity: 0"
display: none - element fully disappears from page, but stays in DOM, so element still can be interacted with via JS. screen-readers do not read such element
visibility: hidden - element takes space, however user can't interact with it. screen-readers read such element
opacity: 0 - element takes space and user can interact with it. screen-readers read such element
width
- auto - default value. by default block takes the full width of container, i.e. width is 100%
- min-content - shrinks text content to the limit and sets this width
- max-content - extends text content and sets this width
- fit-content - same width as max-content, but not more than available space
- see Units for measuring units
height - sets the height of element
- auto - default value
- <percentages> - are calculated relatively to parent element
- there will be no effect of percentages if parent has no defined height (i.e. "height: auto") or only has min-height
- "position: absolute" is an exception. so it can get percentage-based height despite closest relative parent has it
- html & body height - by default are determined by the content. however this is not unified across browsers
- html, body { height: 100%; } - only after that direct child elements of body can get percentage-based height
max-width
- none - default
- tricks: element with "max-width" and "margin: 0 auto", but without "width" shrinks to the size of content
min-width
Hints
max-width overrides width, and is overridden by min-width
max-height
min-height
- tricks:
- "min-height: 100vh" for container + "height: 100%" for child - will not work. to fix, "height: 1px" should be set on container in addition to min-height
- flex fixes the given issue
margin - outer spacing of an element
- auto - take all available space
- 10% - the percentage for all margins is based on the width of the container
- -2px - negative margin can be useful to fix positioning for the element
- tricks:
- margin: 0 auto - center block horizontally
- margin-left: auto - move block to right side
padding - inner spacing of an element
box-sizing
- content-box - default value. this makes width & height apply only on content of an element
- border-box - this makes width & height apply to the whole block: content + paddings + borders
margin, padding, border-radius apply style on four sides or corners, and therefore can take 1 up to four values:
4px - same value for 4 sides
4px 8px - vertical + horizontal
4px 8px 16px - top, horizontal, bottom
4px 1px 12px 8px - top, right, bottom, left
Typography
font-family
- <family name>, <generic name> - syntax. quotes are optional
font-weight
- <numeric value> - 100 to 900
- lighter, bolder - adjust font-weight relatively to the parent
- normal - alias for 400
- bold - alias for 700. equals <strong> tag
in common terminology there are also aliases for other font-weight values, but they are not present within CSS specification. in particular:
light - alias for 300
medium - alias for 500
semibold - alias for 600
font-size
font-style
- italic - equals <em> tag
text-align - aligns text or inline elements inside block
- start, end - is preferable for text, as user might use right-to-left setting in browser
- left, center, right
- justify
text-indent - indent for the first line
text-decoration
- underline - equals to <u>
- line-through - equals to <s>
- overline - line over text
- none - remove decoration
- this is a shorthand for:
- text-decoration-line
- text-decoration-color
- text-decoration-style
- text-decoration-thickness
text-transform
- lowercase
- uppercase
- capitalize
- none
text-stroke - creates border for the text
- e.g. text-stroke: 4px navy;
- analog is possible with text-shadow
- this is a shorthand for:
- text-stroke-width
- text-stroke-color
line-height - set spacing between lines of one paragraph
- normal - default. depends on browser and font-family. is approximately 1.2
- <numeric value> - this value is multiplied on font-size. e.g. line-height: 1.5;
letter-spacing - set distance between characters
- 1rem / 1em
- 1px
- normal - default
List
list-style-image
list-style-position - position for markers
- outside - default value
- inside - <li> marker is aligned with <li> text
list-style-type - set style for the markers for <li> elements
- disc, circle, square
- decimal, georgian
- <unicode> - allows adding custom symbol or emoji
- none - remove list markers
list-style - is a shorthand for preceding list properties
- hints:
- since list properties are inherited, each of them can be set once on parent, i.e. <ul> or <ol>
Decor
Background
background-color
- <color value> - see CSS Basic for more
- transparent
- currentColor
background-image: url("address")
background-repeat
- repeat - default value
- repeat-x
- repeat-y
- space - add space between images
- no-repeat
- <horizontal> <vertical> - two-value syntax
background-attachment
- fixed - background is fixed relatively to the viewport. i.e. it doesn't move on scroll
- scroll
- local
Hints
fixed background can cause performance issues on scroll, since browser needs to constantly repaint such background
this is the reason why fixed can be ignored on mobile devices
an alternative is to use separate element or pseudo-element for such background and set position: fixed to it
background-position
- <horizontal or vertical> - one-value syntax. when used, "center" is default for second axis
- top - equals "center top"
- center - equals "center center"
- 50% - equals "50% center" and just "center"
- <horizontal> <vertical> - two-value syntax
- right bottom - default. stick to right and bottom
- 10px 20px - 10px from left, 20px from top
- right 10px bottom 20px - 10px from right, 20px from bottom
- percents are neither relative to container, nor to image. offset for X-axis, set with percents, is calculated as: (container width - image width) * percent
- is a shorthand for background-position-x & background-position-y
background - is a shorthand for all preceding properties
- it is allowed to add multiple backgrounds for an element. they should be separated with commas. first background is closest to the viewer
- e.g. background: linear-gradient(to bottom, purple, transparent), url("https://picsum.photos/200");
- background-color is allowed to have only one value. for "background", single color code is allowed to be in the end of list only
div {
height: 324px;
background-color: pink;
background-image: url('https://picsum.photos/100'), url('https://picsum.photos/200');
background-repeat: no-repeat;
background-position: 8px 12px, 108px 112px;
}
background-size
- 90% - one-value syntax. 90 percents for both width and height. percents are relative to container
- 160px 80px - two-value syntax. width + height
- contain - fit background to full width or full height of container. original ratio is preserved, background is fully visible
- cover - cover container fully. original ratio is preserved, background is cropped
- tricks:
- calc(min(480px, 100%)) - a way to set max-width for background
object-fit - analog of background-size for the images added with <img> tag
- fill - stretch image
- contain
- cover
object-position - analog of background-position
- center
fill - set SVG color
- filter property can be used to set color to SVG inserted into <img> tag
Border
border-width
- <horizontal and vertical> - one-value syntax
- <horizontal> <vertical> - two-value syntax
border-style
- solid
- dashed
- dotted
- double
- ridge
border-color
border - a shorthand for all preceding properties
- e.g. border: 2px solid cyan;
- none - no border
border-image - set image or gradient as border
border-radius
- 8px - rounding starts in 8 pixels from the corner
- 50% - make element round. percentages are relative to the width & height of the element
- 8px / 16px - slash allows setting individual radius for each axis. 8px on horizontal border and 16px on vertical border
- the radius applies to the whole background, i.e. element edges will be cropped
- to set border radius explicitly for the corners, the following properties are offered:
- border-top-left-radius: <horizontal> <vertical>
- border-top-right-radius
- border-bottom-right-radius
- border-bottom-left-radius
- tricks:
- border-top-left-radius: 100% - this will result in increase from bottom-left to top-right corner
- if additionally border-bottom-right will be set, it will take as much space as it requires, up to 50%
outline - is a separate border drawn outside the element, which is used to add element focus indicator
- none - remove outline
- it doesn't affect layout, so may overlap other elements
- it is not a part of the element's dimensions
- is a shorthand for:
- outline-color
- outline-style
- outline-width
- tricks:
- * { outline: 1px solid #f00 !important; } - rule to detect element causing horizontal scrollbar issue
Shadow
box-shadow - adds shadow effect around element's frame
- <inset> <offset-x> <offset-y> <blur-radius> <spread-radius> <color> - syntax. inset, blur-radius and spread-radius values are optional
- inset - keyword used to direct shadow to the inside of an element
- offset-x - horizontal offset. positive values offset to right, negative - to left
- offset-y - vertical offset. positive values offset to bottom, negative - to top
- blur-radius - the more value, the more blur, i.e. the shadow becomes bigger and lighter. is set in pixels, only positive
- spread-radius - the more value, the farther shadow spreads from the box. it spreads in all directions. is set in pixels, might be negative
- multiple comma-separated shadows can be applied to one element
- MDN's box shadow generator
- e.g.
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); - basic shadow
- box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); - light material shadow
- tricks:
- transition: box-shadow 0.3s cubic-bezier(.25,.8,.25,1); - transition for the shadow
text-shadow
- <offset-x> <offset-y> <blur-radius> <color> - syntax
- e.g. text-shadow: 1px 1px 2px lightblue;
Filter
filter - applies graphical effects to an element
- none - default
- url(<SVG filter element>) - there is a possibility to set SVG filter element
- multiple filters can be applied on one element. comma is not needed
backdrop-filter - applies graphical effects to the area behind an element
- result is visible only when element background is fully or partially transparent
- e.g. backdrop-filter: blur(10px); - can be used for modal window in glassmorphic design
- note: this property is performance-intensive, since browser needs to compose several layers. weak mobile devices can experience laggy UI interactions
Filter Functions
blur() - make element blurred
- e.g. filter: blur(8px)
contrast(percent)
greyscale(percent)
- e.g. filter: greyscale(100%) - black & white completely
drop-shadow()
- e.g. filter: drop-shadow(4px 4px 0px rgba(0, 0, 0, .2));
filter functions accepting percent value can also accept coefficient value. e.g. 50% is equal to 0.5
Other
Overflow
overflow - controls the visibility of content which doesn't fit into a container
- visible - default
- hidden - not visible
- scroll - content can be scrolled. both scrollbars are always visible
- auto - similar to scroll, but it adds scrollbars only when necessary
- this is a shorthand for:
- overflow-x
- overflow-y
white-space - controls the wrapping behaviour of text
- normal - default
- nowrap - all text in one line
- pre - preserve spaces and line-breaks. equals <pre>
- pre-wrap - works like pre, but adds automatic line-breaks if text does not fit the container
word-break
- normal - default
- keep-all
- break-word
- break-all - break words on all lines. text will be stretched across the entire container width
- use case: "break-all" works nice for long links
overflow-wrap
- normal - default. text is broken only on whitespaces, i.e. spaces between words
- break-word - compared to word-break: break-all, it breaks words only if necessary to prevent overflow, but still prefers wrapping at whitespaces
- anywhere
long words within inline elements (but non flex children) are broken by characters by default, without any additional CSS rules
Hints
overflow-wrap: break-word might not work for single long word. there are also issues when container has dynamic width
in general, yes, CSS rules for overflowing words are pretty confusing
hyphens - allows to break words with hyphen
- manual - default. breaks words on hard and soft hyphens
- auto - browser automatically breaks words. soft hyphens, if present, can override automatic hyphenation points
- none - words are broken at all
- soft hyphen (SHY) - invisible hyphen, which is used to mark a place where word break is possible. ­ - HTML entity
text-overflow - allows to mark that text doesn't fit the container
- ellipsis - display three dots "..." at the end
- ellipsis is only possible for one line of text. for more, -webkit-line-clamp can do the work
- hints:
- works nice in pair with flex and "overflow: hidden". "overflow: hidden" might be needed for both flex container and flex item
-webkit-line-clamp - allows to limit the amount of rows, text will be wrapped on. three dots are added in case of overflow
.risky-text {
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
scroll-behavior - set the behaviour of scroll when it is triggered via JS
- auto - default. content is scrolled instantly
- smooth - content is scrolled smoothly
Scroll Snap
scroll snap module - allows controlling scroll behaviour
- it can be applied on containers with "overflow: scroll" and "overflow: auto"
For Container
scroll-snap-type - set the type and direction of scrolling
- x mandatory
- y proximity
scroll-padding - can be used when content shouldn't snap right to the edge of the container
For Children
scroll-snap-align - set the position that scrolling will snap to
- start
- end
- center
scroll-margin
More Properties
cursor - set the appearance of cursor
- auto - equals "default", unless specific content provides its own default value. e.g. for text content default value is "text"
- default - a classic arrow
- pointer - specifies clickable segment
- not-allowed - specifies non-clickable segment
- text - specifies either selectable text or text input
- progress - is used to demonstrate loading process
- move - specifies an item which can be moved
- grab - drag & drop is possible
- grabbing - drag & drop in progress
- copy - specifies an item which can be copied
- ew-resize - horizontal resize
- ns-resize - vertical resize
- zoom-in - specifies an item which can be zoomed in
- zoom-out - specifies an item which can be zoomed out
- help - question mark
- none - no cursor
pointer-events
- none - events will not trigger on such element
user-select - controls whether text can be selected
- auto
- none
resize - sets whether element can be resized and how. works with all elements overflow of which is not "visible"
- both
- horizontal
- vertical
- none
float - places element on left or right side of the container
- left
- right
- none
- floating elements are being removed from the normal flow, however still occupy space in it
- it can be used to wrap text around an image
clear - sets whether an element must be moved below floating elements that precede it
- left - only below elements floating on the left side
- right - only below elements floating on the right side
- both
- none
- float & clear have no effect on flex items
tab-size - width of tab character in pre-formatted text
- 8 - default value
- 5 - set tab size to the width of 5 spaces
- 0 - remove indentation
aspect-ratio - sets width-to-height ratio of an element
- 1 / 1 - square
- 16 / 9 - some custom value
clip-path - set which part of an element is visible
Scrollbar
scrollbar-width - set width for scrollbar
- auto - default
- thin
- none - remove scrollbar
scrollbar-color - set color for scrollbar
- purple lightblue - first applies to thumb (moving part), second to track (background)
scrollbar-gutter - manage reserved space for the scrollbar
- auto - default
- stable
- stable both-edges
scrollbar properties are not supported in Safari. ::-webkit-scrollbar placeholder should be used there instead
e.g. ::-webkit-scrollbar { display: none; } - remove scrollbar in Safari. scrollbar can also be hidden with negative right margin
Modules
motion-page - allows to animate graphical object along a custom path, i.e. straight or curve line
- e.g. animation of plane flying over map
proposed in this article hierarchy of CSS property groups can be used during styling for ordering, to favour consistency:
- positioning
- block
- typography
- decor
- animation
- other