Fluid Images

Lecture notes: the calc() function, responsive images, max-width, object-fit and fluid video

1. The calc() function

The calc() function lets you perform arithmetic operations with different units of measurement directly in CSS. The browser computes the result on the fly.

/* Problem: two columns + gap = more than 100% */
.sidebar { width: 40%; }
.content {
width: calc(60% - 20px);
margin-left: 20px;
}

Supported operations: +, -, *, /. You can mix units: calc(100% - 20px), calc(50vh + 2rem).

Don’t overuse calc()! In most cases you can get by with Flexbox or box-sizing:
border-box
. Excessive use of calc() makes the code harder to read.

Why doesn’t box-sizing: border-box solve the problem?

border-box only accounts for padding and border in the element’s width. The outer margin is not included in the calculation, so 60% + margin-left: 20px will still exceed 100%.

2. Centering an absolute element

A classic task: place an element exactly in the center of its parent block.

Method 1: position + transform (universal)

.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

Why it works:

  1. top: 50%; left: 50% — shifts the element’s top-left corner to the center of the parent
  2. translate(-50%, -50%) — shifts the element back by half of its own dimensions
Key advantage: the percentages in translate() are calculated from the dimensions of the element itself (not the parent). That’s why the centering works regardless of the element’s size.

Method 2: Flexbox

.parent {
display: flex;
justify-content: center;
align-items: center;
}

The difference between the approaches:

Method Where the styles are set When to use
position + transform On the child element Modal windows, overlay elements
Flexbox On the parent element General content centering

Why is margin-left: -50px a bad approach?

It hard-wires the offset to a specific element size. If the size changes, the centering breaks. transform: translate(-50%, -50%) works with any dimensions.

3. transform — transforming elements

The transform property lets you apply various visual transformations to an element:

Function What it does
translate(x, y) Shifts the element along the X and Y axes
rotate(deg) Rotates the element
scale(n) Enlarges/shrinks the element
skew(x, y) Skews the element (turns a rectangle into a parallelogram)
Don’t confuse them: transform is a transformation (translation, rotation, and so on). transition is an animated transition between states. These are different properties that are often used together.

4. Content and background images

Type Technology When to use
Content <img> An image that changes from page to page: a product photo, an avatar, an article cover
Background background-image A decorative image tied to the design: a header background, an abstract texture
The main question: will this image be changed through the admin panel? If so, it’s a content image (<img>), even if visually it looks like a background (for example, an article cover).

5. object-fit and object-position

The object-fit and object-position properties are the counterparts of background-size and background-position, but for the <img> and <video> tags.

img {
width: 200px;
height: 200px;
object-fit: cover;
object-position: center center;
}
Value Behavior
cover Fills the block completely, cropping the excess. Proportions are preserved
contain Fits the image completely, leaving “bars.” Proportions are preserved
fill (default) Stretches to the given dimensions. Proportions are not preserved
none The image keeps its real size

object-position sets the point relative to which the image is scaled: top center, bottom right, and so on. The default is center center.

6. Optimizing image loading

A comparison of how different hiding methods behave for content and background images:

Hiding method <img> background-image ::before
display: none Loads Depends on the browser Does not load
opacity: 0 Loads Loads Loads
visibility: hidden Loads Loads Loads
Conclusion: no CSS hiding method prevents an <img> from loading. Optimization requires a different approach — lazy loading.

7. Lazy loading — deferred loading

The idea: don’t load an image until the user has scrolled to it on the page.

The data-attribute approach

<!-- The image won't load — src is empty -->
<img src=""
data-src="photo.jpg"
alt="Description"
class="lazy">

How it works:

  1. The src attribute is empty or contains a low-quality placeholder image
  2. The real address is stored in data-src (a data attribute does not affect loading)
  3. JavaScript tracks scrolling and, when the image enters the visible area, copies data-srcsrc
  4. Only after that does the browser begin loading

Native lazy loading

<img src="photo.jpg"
loading="lazy"
alt="Description">
The modern approach: the loading="lazy" attribute is supported by all modern browsers and does not require JavaScript. The browser itself defers loading of images that are outside the visible area.

8. Fluid images — max-width: 100%

The core technique for fluid content images:

img {
max-width: 100%;
height: auto;
}
Property Behavior
width: 100% The image is always stretched to the full width of the parent (even if it’s smaller)
max-width: 100% The image does not exceed the width of the parent, but is not enlarged beyond its real size
The standard approach: set max-width: 100% on the image, and control the dimensions through the parent block. This gives you a universal class that can be applied to any picture.

With width: 100% a small image will stretch and lose quality. With max-width:
100%
it keeps its real size if the parent is larger.

9. background-size for background images

The background-size property controls the size of a background image:

Value Behavior
cover Fills the entire block, cropping the excess
contain Fits it completely, leaving bars
A value in px or % A fixed size (for example, 600px auto — width 600px, automatic height)
100% Width = width of the block, automatic height

Combined with background-position: center, we get an image that scales correctly when the block’s dimensions change.

10. Summary table

Topic Key point
calc() Arithmetic in CSS with mixed units; don’t overuse it
Centering an absolute element top: 50%; left: 50%; transform: translate(-50%, -50%) — the universal method
object-fit The counterpart of background-size for <img> and <video>
Content vs. background If it changes through the admin panel → content (<img>)
Fluid <img> max-width: 100%; height: auto; — the standard approach
Lazy loading Native: loading="lazy"; with JS: data-srcsrc
transform Translation, rotation, scaling; translate(%) is calculated from the element itself

Vitalii Kaplia

Founder, Web Developer & WordPress Expert

I became interested in programming back in 1997. The first acquaintance with a future profession was using Visual Basic. In…

More about author

A digital product engineer and web solutions architect

Free consultation + cost calculation

Let’s discuss your project?

Free consultation + cost calculation

More interesting articles

Customer login

This site uses cookies

We use cookies to personalize content and ads, provide social media features, and analyze our traffic. We also share information about your use of our website with our social media, advertising, and analytics partners, who may combine it with other information you have provided to them or collected when you use their services. By continuing to use our site, you consent to our use of cookies and accept our Privacy Policy and Terms of Use.

Virtual assistant
Hi! I'm the KAPLIA.PRO virtual assistant! I can tell you about our services, portfolio projects, ballpark pricing, and how we work — from websites and eCommerce to web apps, CRMs, bots, and AI agents. Ask away!

By continuing with the AI assistant, I agree to the site’s terms of use and privacy policy.

AI assistant may make mistakes in responses