Side-by-side: center crop vs focus-point crop
Default 50% 50%
With focus point
Click anywhere to set focus point
Click on the image to move the focus point. Watch the crops above update.
How it works
TYPO3's cropVariants TCA configuration lets editors define a
focus area
— the region of the image that matters most.
TYPO3 stores it as {x, y, width, height} ratios (0–1).
The math to convert this to CSS:
centerX = (focusArea.x + focusArea.width / 2) * 100%
centerY = (focusArea.y + focusArea.height / 2) * 100%
→ object-position: centerX centerY;
Combined with object-fit: cover, the browser keeps the focus
point visible regardless of container size. 97%+ global browser support.
No JavaScript required.
TYPO3 integration guide
Step 1 — Enable focusArea on your crop variants via
TCA override:
$GLOBALS['TCA']['tt_content']['types']['textmedia']
['columnsOverrides']['assets']['config']
['overrideChildTca']['columns']['crop']['config'] = [
'cropVariants' => [
'default' => [
'title' => 'Desktop',
'allowedAspectRatios' => [
'16:9' => ['title' => '16:9', 'value' => 16 / 9],
'4:3' => ['title' => '4:3', 'value' => 4 / 3],
'free' => ['title' => 'Free', 'value' => 0.0],
],
'focusArea' => [
'x' => 1/3, 'y' => 1/3,
'width' => 1/3, 'height' => 1/3,
],
],
],
];
Step 2 — Create a ViewHelper that reads the focus area and returns a CSS value (full source):
final class FocusPositionViewHelper extends AbstractViewHelper
{
public function render(): string
{
$image = $this->arguments['image'];
$cropJson = $image->getProperty('crop');
$collection = CropVariantCollection::create($cropJson);
$focusArea = $collection->getFocusArea($variantName);
if ($focusArea->isEmpty()) {
return '50% 50%';
}
$focus = $focusArea->asArray();
$crop = $collection->getCropArea($variantName)->asArray();
// Remap focus center into cropped coordinate space
$x = ($focus['x'] + $focus['width'] / 2 - $crop['x'])
/ $crop['width'] * 100;
$y = ($focus['y'] + $focus['height'] / 2 - $crop['y'])
/ $crop['height'] * 100;
return sprintf('%.2f%% %.2f%%', clamp($x), clamp($y));
}
}
Step 3 — Use a CSS custom property in your Fluid partial:
<f:image image="{image}" cropVariant="{cropVariant}" width="1200"
additionalAttributes="{style: '--focus-position:{fp:focusPosition(image:image, cropVariant:cropVariant)}'}"
class="focus-image" />
Step 4 — Two lines of CSS:
.focus-image {
object-fit: cover;
object-position: var(--focus-position, 50% 50%);
}
That's it. Editors drag the focus area in the TYPO3 crop dialog, the ViewHelper computes the position, CSS does the rest. No JavaScript, no extension, no layout shift.
Full working sitepackage: github.com/wazum/typo3-focus-point