CSS Width & Height
What are Width and Height?
The width and height properties determine the size of an element on screen. CSS supports various size units and functions that allow flexible and responsive layouts.
A correct understanding of sizing is the key to building layouts that stay stable across different screen sizes and content.
CSS Size Units
| Unit | Description | Example |
|---|---|---|
px |
Pixel — absolute size | width: 300px |
% |
Percentage of the parent | width: 50% |
em |
Relative to the element's font-size | width: 20em |
rem |
Relative to the root font-size | width: 20rem |
vw |
1% of viewport width | width: 50vw |
vh |
1% of viewport height | width: 50vh |
vmin |
1% of the smaller viewport dimension | width: 50vmin |
vmax |
1% of the larger viewport dimension | width: 50vmax |
Main Sizing Properties
width and height
Determine the exact size of an element. The default value is auto.
width: 300px;
height: 200px;
min-width / max-width
Limit the minimum and maximum size of an element.
min-width: 200px;
max-width: 800px;
min-height / max-height
Limit the minimum and maximum height of an element.
min-height: 300px;
max-height: 600px;
fit-content
The element's size adjusts to fit its content, but does not exceed the specified maxWidth.
width: fit-content;
max-width: 300px;
clamp()
A CSS function that returns a value within a range of minimum, preferred, and maximum. Very useful for responsive design.
width: clamp(200px, 50%, 800px);
/* Minimum: 200px, Preferred: 50%, Maximum: 800px */
Code Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS Width & Height</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
background-color: #f5f5f5;
padding: 20px;
color: #333;
}
h1 {
margin-bottom: 25px;
}
.section {
background-color: white;
border-radius: 8px;
padding: 20px;
margin-bottom: 25px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
}
h2 {
margin-bottom: 15px;
color: #2c3e50;
}
p {
line-height: 1.6;
color: #555;
margin-bottom: 10px;
}
code {
background-color: #f0f0f0;
padding: 2px 6px;
border-radius: 3px;
font-size: 13px;
}
/* === Width with Units === */
.unit-grid {
display: flex;
flex-direction: column;
gap: 10px;
}
.unit-box {
background-color: #3498db;
color: white;
padding: 10px;
font-size: 13px;
font-weight: bold;
text-align: center;
}
.w-300px { width: 300px; }
.w-50pct { width: 50%; }
.w-20em { width: 20em; }
.w-20rem { width: 20rem; }
.w-50vw { width: 50vw; }
/* === Min/Max Width === */
.minmax-demo {
border: 2px dashed #e74c3c;
padding: 10px;
margin-bottom: 10px;
}
.minmax-box {
background-color: #2ecc71;
color: white;
padding: 10px;
font-size: 13px;
font-weight: bold;
text-align: center;
min-width: 150px;
max-width: 400px;
width: 60%;
}
/* === Min/Max Height === */
.height-demo {
display: flex;
gap: 15px;
flex-wrap: wrap;
}
.height-box {
background-color: #9b59b6;
color: white;
padding: 10px;
font-size: 12px;
font-weight: bold;
text-align: center;
width: 150px;
}
.h-min { min-height: 100px; }
.h-max { max-height: 100px; overflow: hidden; }
.h-minmax { min-height: 80px; max-height: 200px; overflow: auto; }
/* === fit-content === */
.fit-content-demo {
border: 2px dashed #e67e22;
padding: 10px;
margin-bottom: 10px;
}
.fit-box {
background-color: #e67e22;
color: white;
padding: 10px;
font-size: 13px;
font-weight: bold;
width: fit-content;
max-width: 300px;
}
/* === clamp() === */
.clamp-grid {
display: flex;
flex-direction: column;
gap: 10px;
}
.clamp-box {
background-color: #1abc9c;
color: white;
padding: 10px;
font-size: 13px;
font-weight: bold;
text-align: center;
width: clamp(200px, 50%, 600px);
}
.clamp-box-2 {
background-color: #e74c3c;
width: clamp(150px, 40vw, 500px);
}
/* === Height Auto === */
.auto-height-grid {
display: flex;
gap: 15px;
flex-wrap: wrap;
align-items: flex-start;
}
.auto-box {
background-color: #34495e;
color: white;
padding: 15px;
font-size: 13px;
font-weight: bold;
text-align: center;
width: 150px;
}
.auto-height {
height: auto;
}
.fixed-height {
height: 120px;
}
/* === Responsive Container === */
.container-demo {
max-width: 100%;
}
.container-box {
background-color: #2c3e50;
color: white;
padding: 20px;
text-align: center;
font-weight: bold;
width: 100%;
max-width: 800px;
margin: 0 auto;
}
.container-fluid {
background-color: #3498db;
color: white;
padding: 20px;
text-align: center;
font-weight: bold;
width: 100%;
margin-top: 10px;
}
/* === Viewport Units Demo === */
.viewport-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
gap: 10px;
}
.viewport-box {
background-color: #f39c12;
color: white;
padding: 10px;
font-size: 11px;
font-weight: bold;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.vw-box { width: 20vw; height: 60px; }
.vh-box { width: 120px; height: 15vh; }
.vmin-box { width: 20vmin; height: 20vmin; }
.vmax-box { width: 15vmax; height: 60px; }
/* === Aspect Ratio === */
.aspect-grid {
display: flex;
gap: 15px;
flex-wrap: wrap;
}
.aspect-box {
background-color: #8e44ad;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 13px;
font-weight: bold;
}
.aspect-1-1 { width: 120px; aspect-ratio: 1 / 1; }
.aspect-16-9 { width: 200px; aspect-ratio: 16 / 9; }
.aspect-4-3 { width: 180px; aspect-ratio: 4 / 3; }
</style>
</head>
<body>
<h1>CSS Width & Height</h1>
<!-- Width with Units -->
<div class="section">
<h2>Width with Various Units</h2>
<p>Differences in using px, %, em, rem, and vw units:</p>
<div class="unit-grid">
<div class="unit-box w-300px">width: 300px — Fixed width</div>
<div class="unit-box w-50pct">width: 50% — Half of parent width</div>
<div class="unit-box w-20em">width: 20em — Relative to element font-size</div>
<div class="unit-box w-20rem">width: 20rem — Relative to root font-size</div>
</div>
</div>
<!-- Min/Max Width -->
<div class="section">
<h2>Min/Max Width</h2>
<p>Limiting the minimum and maximum size of an element:</p>
<div class="minmax-demo">
<div class="minmax-box">
min-width: 150px | width: 60% | max-width: 400px
</div>
</div>
<p style="font-size: 13px; color: #888;">
This box has a width of 60% of its parent, with a minimum of 150px and a maximum of 400px. Try resizing the browser to see the change.
</p>
</div>
<!-- Min/Max Height -->
<div class="section">
<h2>Min/Max Height</h2>
<p>Limiting the minimum and maximum height of an element:</p>
<div class="height-demo">
<div class="height-box h-min">
min-height: 100px<br><br>Short text
</div>
<div class="height-box h-max">
max-height: 100px<br><br>Very long text will be clipped with overflow hidden because of the maximum height limit set on this element.
</div>
<div class="height-box h-minmax">
min-height: 80px<br>max-height: 200px<br><br>Very long text will be displayed with scrolling because it uses overflow auto to handle content that exceeds the maximum limit.
</div>
</div>
</div>
<!-- fit-content -->
<div class="section">
<h2>fit-content</h2>
<p>Size adapts to the content, but does not exceed the maxWidth limit:</p>
<div class="fit-content-demo">
<div class="fit-box">
Short
</div>
<div class="fit-box" style="margin-top: 10px;">
This is text long enough to demonstrate how fit-content works with a maxWidth limit
</div>
</div>
</div>
<!-- clamp() -->
<div class="section">
<h2>clamp() — Responsive Without Media Queries</h2>
<p><code>clamp(minimum, preferred, maximum)</code> makes the size automatically flexible:</p>
<div class="clamp-grid">
<div class="clamp-box">
clamp(200px, 50%, 600px)
</div>
<div class="clamp-box clamp-box-2">
clamp(150px, 40vw, 500px)
</div>
</div>
<p style="font-size: 13px; color: #888;">
The width adapts to the viewport: minimum 200px, preferred 50%, maximum 600px. Very useful for responsive typography and containers.
</p>
</div>
<!-- Height Auto vs Fixed -->
<div class="section">
<h2>Height: Auto vs Fixed</h2>
<p>height: auto adapts to the content, while a fixed height stays put:</p>
<div class="auto-height-grid">
<div class="auto-box auto-height">
auto<br><br>This text will make the box grow automatically according to the amount of content inside it.
</div>
<div class="auto-box fixed-height">
height: 120px<br><br>Text that is too long will overflow the set limit.
</div>
</div>
</div>
<!-- Responsive Container -->
<div class="section">
<h2>Responsive Container</h2>
<p>Combining width, max-width, and margin for a responsive container:</p>
<div class="container-demo">
<div class="container-box">
max-width: 800px | margin: 0 auto
</div>
<div class="container-fluid">
width: 100% — Full width
</div>
</div>
</div>
<!-- Viewport Units -->
<div class="section">
<h2>Viewport Units</h2>
<p>Units based on the browser viewport size:</p>
<div class="viewport-grid">
<div class="viewport-box vw-box">20vw</div>
<div class="viewport-box vh-box">15vh</div>
<div class="viewport-box vmin-box">20vmin</div>
<div class="viewport-box vmax-box">15vmax</div>
</div>
<p style="font-size: 12px; color: #888; margin-top: 10px;">
vw = 1% viewport width, vh = 1% viewport height, vmin = smaller of vw/vh, vmax = larger of vw/vh
</p>
</div>
<!-- Aspect Ratio -->
<div class="section">
<h2>Aspect Ratio</h2>
<p>Keeping element aspect ratios consistent:</p>
<div class="aspect-grid">
<div class="aspect-box aspect-1-1">1:1</div>
<div class="aspect-box aspect-16-9">16:9</div>
<div class="aspect-box aspect-4-3">4:3</div>
</div>
</div>
</body>
</html>
Code Explanation
- Width with different units — Five blue boxes showing the differences between units:
300px— Fixed width, does not change on resize50%— Always half the width of the parent element20em— Relative to the element's own font-size20rem— Relative to the root (html) font-size-
50vw— 50% of the browser viewport width -
Min/Max Width — A green box with
min-width: 150px,width: 60%, andmax-width: 400px. Its actual width will always be between 150px and 400px. -
Min/Max Height — Three purple boxes:
min-height: 100px— At least 100px, can stretch if the content is largermax-height: 100px; overflow: hidden— At most 100px, excess content is clipped-
min-height: 80px; max-height: 200px; overflow: auto— A 80-200px range, excess content gets a scrollbar -
fit-content — An orange element that sizes itself based on its content, but does not exceed
max-width: 300px. -
clamp() — A function that makes an element responsive without a media query:
clamp(200px, 50%, 600px)means a minimum of 200px, preferred 50%, maximum 600px. -
Aspect Ratio — Purple elements with a locked aspect ratio: 1:1 (square), 16:9 (widescreen), 4:3 (traditional).
Everyday Use Cases
<!DOCTYPE html>
<html lang="en">
<head>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: Arial, sans-serif;
background-color: #f5f5f5;
}
/* === Responsive Blog Layout === */
.blog-header {
background-color: #2c3e50;
color: white;
padding: 40px 20px;
text-align: center;
}
.blog-header h1 {
font-size: clamp(24px, 4vw, 42px);
margin-bottom: 10px;
}
.blog-header p {
font-size: clamp(14px, 2vw, 18px);
opacity: 0.7;
max-width: 600px;
margin: 0 auto;
line-height: 1.6;
}
.blog-container {
max-width: 720px;
margin: 0 auto;
padding: 40px 20px;
}
.blog-article {
background-color: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
margin-bottom: 30px;
}
.blog-article h2 {
font-size: clamp(20px, 3vw, 28px);
margin-bottom: 15px;
color: #2c3e50;
}
.blog-article p {
line-height: 1.8;
color: #555;
margin-bottom: 16px;
}
.blog-image {
width: 100%;
height: auto;
aspect-ratio: 16 / 9;
background-color: #ddd;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
color: #999;
font-size: 14px;
margin-bottom: 20px;
}
/* === Image Gallery === */
.gallery {
max-width: 900px;
margin: 0 auto;
padding: 40px 20px;
}
.gallery h2 {
font-size: 24px;
margin-bottom: 20px;
text-align: center;
color: #2c3e50;
}
.gallery-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 15px;
}
.gallery-item {
aspect-ratio: 1;
background-color: #3498db;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
font-size: 14px;
}
.gallery-item-wide {
grid-column: span 2;
aspect-ratio: 2 / 1;
}
</style>
</head>
<body>
<div class="blog-header">
<h1>Blog SkillVersitas</h1>
<p>Articles about CSS, web development, and other coding tips.</p>
</div>
<div class="blog-container">
<div class="blog-article">
<h2>Understanding CSS Sizing for a Perfect Layout</h2>
<div class="blog-image">Article Image (16:9)</div>
<p>
In CSS, the width and height properties are not just pixel numbers.
There are many units that can be used to create responsive
and flexible layouts.
</p>
<p>
Use <code>clamp()</code> to create responsive sizes without
media queries. Use <code>max-width</code> to limit the width of the content
so it remains readable on very wide screens.
</p>
</div>
</div>
<div class="gallery">
<h2>Gallery</h2>
<div class="gallery-grid">
<div class="gallery-item">1</div>
<div class="gallery-item">2</div>
<div class="gallery-item gallery-item-wide">3 (Wide)</div>
<div class="gallery-item">4</div>
<div class="gallery-item">5</div>
<div class="gallery-item">6</div>
</div>
</div>
</body>
</html>
In the blog example above:
- Responsive typography using clamp() — the title scales from 24px to 42px depending on the viewport
- Blog container using max-width: 720px; margin: 0 auto to center it and limit the reading width
- Blog image using aspect-ratio: 16/9 to stay proportional even before the content exists
- Gallery using CSS Grid with minmax(200px, 1fr) for an automatically responsive layout
Important Tips
-
Avoid
width: 100%withoutbox-sizing: border-box— padding and border will make the element wider than its parent. -
max-widthis safer thanwidth— the element can shrink if available space is limited. -
height: autois the default — let the height adjust to the content unless you have a specific reason. -
Use
clamp()for responsive sizing without media queries. -
Viewport units are useful for full-screen sections, but avoid them for body text — the size can be too small or too large.
Conclusion
widthandheightdetermine element size using various units:px,%,em,rem,vw,vh, and more.min-width/max-widthandmin-height/max-heightconstrain the size range of an element.clamp(min, preferred, max)makes sizing responsive automatically without media queries.fit-contentadjusts the size based on the content within a maximum limit.- Viewport units (
vw,vh,vmin,vmax) are based on the browser window size. aspect-ratiokeeps the aspect ratio consistent for images and videos.- Always consider
box-sizing: border-boxso padding and border do not add to the element's width.