Next-Gen App & Browser Testing Cloud
Trusted by 2 Mn+ QAs & Devs to accelerate their release cycles

To move an image in HTML, use CSS rather than HTML itself. The five working methods, from most to least recommended in 2026, are CSS transform translate(), CSS position with top/left/right/bottom, CSS margin, CSS float, and CSS @keyframes animation for motion over time. Avoid the deprecated <marquee> tag - it has been dropped from the HTML5 spec and is being removed from modern browsers.
HTML defines what is on a page; CSS defines where and how it appears. The old align attribute on <img> (align="left", align="middle") is obsolete and ignored by modern browsers. The <marquee> tag is non-standard and removed from the HTML Living Standard. Every reliable technique for moving an image in 2026 is a CSS technique - applied either inline via style="...", in a <style> block, or in an external stylesheet.
All examples below use an external class so the markup stays clean, but the same property declarations work inline if you need a one-off offset.
transform: translate(x, y) shifts an element by an exact pixel or percentage offset without affecting any other element in the layout. It is GPU-accelerated, works in every modern browser, and is the modern default for moving a single element.
<img src="logo.png" alt="Site logo" class="move-it">
<style>
.move-it {
transform: translate(60px, 120px);
}
</style>Variations:
/* Move only on the X axis */
.move-x { transform: translateX(80px); }
/* Move only on the Y axis */
.move-y { transform: translateY(-40px); }
/* Combine with other transforms */
.shifted-and-tilted { transform: translate(60px, 120px) rotate(8deg); }
/* Use percentages relative to the element's own size */
.center-self { transform: translate(-50%, -50%); }Why it is the default choice: the original layout box is left in place (so nothing shifts around it), the transform is hardware-accelerated, and the same property animates smoothly via transition.
The position property changes how an element is anchored. Set it to relative to nudge an element from its normal spot, or absolute / fixed to take it out of normal flow and place it anywhere on the page or viewport.
<div class="card">
<img src="logo.png" alt="Site logo" class="badge">
</div>
<style>
.card {
position: relative;
width: 300px;
height: 200px;
background: #f4f6f8;
}
.badge {
position: absolute;
top: 12px;
right: 12px;
width: 48px;
}
</style>The parent uses position: relative so that the badge's absolute coordinates are measured from the card, not from the page. Without the relative parent, the badge would jump to the top-right corner of the document.
When to use each value:
| position value | Behaviour |
|---|---|
| static (default) | Image stays in normal flow; top/left/etc. are ignored. |
| relative | Stays in normal flow but offsets from its original spot. |
| absolute | Removed from flow; positioned relative to the nearest positioned ancestor. |
| fixed | Pinned to the viewport; stays in place when the page scrolls. |
| sticky | Acts like relative until a scroll threshold, then sticks like fixed. |
margin is the simplest way to push an image without changing its position. It works in normal flow, so other elements may move to make room - that is sometimes exactly what you want.
<img src="logo.png" alt="Site logo" class="nudge">
<style>
.nudge {
margin-top: 24px;
margin-left: 80px;
}
</style>Use auto to centre horizontally inside a block parent:
.center {
display: block;
margin-left: auto;
margin-right: auto;
}Use negative margins to overlap or pull an image into a neighbouring element:
.pull-up { margin-top: -32px; }margin is fine for layout-level positioning. For pixel-perfect placement that does not disturb neighbours, prefer Method 1 or Method 2.
float: left or float: right pulls an image to one side and lets surrounding text flow around it. This is the traditional "magazine layout" use case for moving an image relative to a paragraph.
<p class="article">
<img src="cover.jpg" alt="Article cover" class="float-it">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua...
</p>
<style>
.float-it {
float: left;
width: 200px;
margin: 0 16px 8px 0;
}
</style>Clearing a float so the next element does not also wrap:
.clear { clear: both; }Modern layouts often replace float with Flexbox or Grid - but float remains the right tool when you genuinely want inline text to wrap an image.
Use @keyframes to animate an image's position over time - for a banner that slides in, an icon that bobs, or a hover effect that nudges an element.
<img src="rocket.png" alt="Rocket" class="lift-off">
<style>
@keyframes liftOff {
0% { transform: translateY(0); }
100% { transform: translateY(-200px); }
}
.lift-off {
animation: liftOff 2s ease-out forwards;
}
</style>Hover-triggered animation using transition:
.slide-on-hover {
transition: transform 0.4s ease-in-out;
}
.slide-on-hover:hover {
transform: translateX(40px);
}transform is the property to animate. Animating top/left works but forces layout recalculations on every frame, which can drop frame rate on lower-end devices.
| Method | Best for | Affects siblings? | Animatable? |
|---|---|---|---|
| transform: translate() | Pixel-perfect single-element offsets, animation | No | Yes (smooth, GPU-accelerated) |
| position (relative / absolute / fixed) | Overlaying badges, fixed-to-viewport elements, dropdowns | relative: no, absolute/fixed: no | Yes (less smooth than transform) |
| margin | Layout-level offsets, centring with auto | Yes (pushes neighbours) | Yes but causes reflow |
| float | Wrapping text around an image | Yes (text reflows) | No (toggle on/off) |
| @keyframes / transition | Motion over time, hover effects, sliding panels | No (when animating transform) | Yes (designed for it) |
Quick rule: for a one-off offset, reach for transform. For overlapping badges, use position: absolute inside a position: relative parent. For text wrapping, use float. For motion, animate transform with @keyframes or transition.
position: static, which ignores top, right, bottom, and left properties. Apply position: relative, absolute, or fixed to enable positional movement.position: absolute is positioned relative to its nearest positioned ancestor. If no parent element has a positioning value set, it defaults to the <html> element. Add position: relative to the intended parent container to correctly anchor the image.transform: translate() instead.<marquee> element has been deprecated and removed from the HTML Living Standard. Modern implementations should use CSS animations with @keyframes and transform for scrolling effects.top and left can reduce performance. For smoother and more efficient animations, use transform: translate(), which benefits from hardware acceleration and minimizes layout recalculations.clear: both to the following container or use modern layout systems such as Flexbox or CSS Grid for more predictable alignment.CSS positioning and animation work consistently in Chrome, Edge, Firefox, Safari, and Opera. The places to watch: iOS Safari sometimes treats position: fixed differently inside scrolling containers; backdrop-filter and certain transform 3D variants need vendor prefixes in older browsers; and scroll-behavior plus position: sticky behave differently when combined with overflow: hidden ancestors.
Visually verifying your image placement across browser and OS combinations is non-negotiable for a production site. You can run your page against 3,000+ real browser and device combinations using TestMu AI's Cross Browser Testing platform, including live interactive sessions on Chrome, Safari, Firefox, and Edge from a single browser tab.
You cannot, reliably. The legacy align attribute on <img> is obsolete. The <marquee> tag is non-standard and being removed. Every working method in 2026 uses CSS - either in a stylesheet, a <style> block, or an inline style="..." attribute.
transform: translate() shifts the rendered pixels without changing the element's layout box, so nothing around it moves. position: relative with top/left also offsets the element visually but keeps its layout box at the original spot. position: absolute removes the element from normal flow entirely. For most pixel-level offsets, transform is the cleanest choice.
Yes. Combine a transition with a hover state:
.hover-shift { transition: transform 0.3s ease; }
.hover-shift:hover { transform: translateX(20px); }Browsers still render <marquee> for backwards compatibility, but it is non-standard, has been removed from the HTML Living Standard, and may be dropped at any time. Replace it with a CSS @keyframes animation that moves transform.
Set the image to display: block and use margin-left: auto; margin-right: auto;, or wrap it in a flex container with justify-content: center. For a dedicated walkthrough, see How To Center An Image In Html.
You are probably using fixed pixel offsets where percentages or vw/vh units would scale with the viewport. Combine transform: translate(%, %) with media queries to keep placement proportional. Responsive image techniques are covered in How To Make Images Responsive.
KaneAI - Testing Assistant
World’s first AI-Native E2E testing agent.

TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance