Skip to content
System nominalUTC --:--:--Articles 080

6 Free WordPress Themes That Do Not Ruin a Photograph

Six free themes compared on what they do to an uploaded photograph: the sizes they generate, the layout width they impose, and what they hold back.

Priya Raghunathan · @praghunathan

Frontend and accessibility

Topic
FE
Section
Frontend & Accessibility
Published
16 OCT 2026
Reading time
9 MIN
Words
2168W
Technical cover graphic for 6 Free WordPress Themes That Do Not Ruin a Photograph
Generated schematic — FE series, REV 2.6.

A photographer uploads a 6,000-pixel-wide frame, looks at the published page, and something is wrong. The skin tones have gone flat, or the horizon is off-centre in a crop that was not asked for, or the image is soft because the page is serving a copy that was resized down and then enlarged again by the browser. None of that is the photograph's fault and most of it is not the theme's either. It is what WordPress does to every upload, and what the theme then does with the result.

So this is not a list of themes that look nice. Six free themes are compared on the only question that matters to a portfolio: what happens to a photograph after you upload it. Each entry gives the version, the last-updated date and the active install count read from its wordpress.org listing on 2026-10-16, and the image behaviour was read out of the theme's own source rather than its marketing page.

ThemeVersionLast updatedActive installsIts own image sizes
Twenty Twenty-Five1.52026-05-201+ millionnone
Ollie1.6.52026-10-086,000+none
Blocksy2.1.602026-10-15300,000+none for posts
Kadence1.5.22026-07-24500,000+none
Neve4.2.162026-10-07200,000+930 x 620, cropped
Fotografie2.5.52026-10-103,000+five, including 1920 x 1080

WordPress generates five files for every upload, before the theme does anything

Upload one JPEG and WordPress writes several copies of it. The intermediate sizes are thumbnail, medium, medium_large and large, and the shipped defaults behind them are 150, 300, 768 and 1024 pixels on the long edge. Every extra image size registered by a theme or a plugin adds another file. A 6,000-pixel original therefore becomes a handful of smaller files plus, in most installs, a scaled-down "full" size: WordPress 7.0.7 resizes any upload wider than 2,560 pixels and treats the resized copy as the full size, which is controlled by the big_image_size_threshold filter.

Then the theme's content width enters. When WordPress prints an image it also prints a srcset listing the available copies and a sizes attribute telling the browser how wide the image will be rendered. That sizes value is calculated from the width the theme declares for its content column. A theme with a 645-pixel content width and a 3,000-pixel image available is a theme whose sizes attribute hands the browser a reason to download the smaller copy. Get that number wrong and the browser either downloads three times more data than it needs or upscales a soft file into a large frame.

There is a ceiling on this, and it is also core behaviour: the srcset candidates drop anything wider than 2,048 pixels unless the theme raises it, through the max_srcset_image_width filter. Your 4,000-pixel export is stored, and it is not offered to the browser.

One query answers most of this

The sizes a theme generates are visible in the media library, and in code. Run the snippet below on a staging copy to see which sizes the upload pipeline is actually producing, then compare each width against the widest layout the theme offers.

add_action( 'admin_notices', function () {
    $meta = wp_get_attachment_metadata( 123 ); // the attachment you just uploaded.

    if ( empty( $meta['sizes'] ) ) {
        return;
    }

    printf(
        '<p>Full: %dpx. Generated: %s</p>',
        (int) $meta['width'],
        esc_html( implode( ', ', array_map(
            function ( $size ) {
                return $size['width'] . 'x' . $size['height'];
            },
            $meta['sizes']
        ) ) )
    );
} );

If that list contains widths the theme never renders, they are costing disk and upload time for nothing. If it contains nothing between 1,024 pixels and your full-size export, the theme is relying on core's sizes and your hero image is being served at 1,024 pixels on a 1,600-pixel screen.

A block theme reads your layout from theme.json, a classic theme from PHP

The distinction that decides image behaviour is not block editor against classic editor. It is where the layout numbers live. A block theme carries a theme.json file that declares the content width and the wide width, and it ships no PHP that registers image sizes. Twenty Twenty-Five declares 645 pixels for content and 1,340 for wide, and its own source contains no image-size registration at all. Ollie declares 740 and 1,260 and is the same. Both send the browser a consistent width, and the image pipeline belongs entirely to core, which is the most predictable arrangement available.

A classic theme sets the content width in PHP, often through a content_width global, and can add its own crops. Neve registers a single neve-blog size at 930 by 620 pixels and hard-crops it, then uses it as the default thumbnail. That crop is a decision made for you: a vertical portrait or a wide panorama placed in a blog card will be cut to 3:2. For a blog it is a sensible default. For a portfolio, it is the exact class of damage this article is about.

Fotografie, a classic theme aimed at photographers, goes further and registers five sizes: 533 square, 640 square, 1,920 by 1,080, 864 square, and a 1,148 by 574 thumbnail, all cropped. Its own content width filters are 756 pixels for the default layout, 1,376 for the front page template and 1,070 in a fourth case. Those crops are what make its grid layouts line up perfectly, and they are also why an image placed in the wrong slot comes back cropped in a way you did not choose.

Twenty Twenty-Five is 1.5, last updated 2026-05-20, with more than a million active installations. Its source contains no image-size registration and no bundled JavaScript file, which is unusual among the six and worth something on a portfolio page where every kilobyte is a photograph you could have served instead. It is a block theme, so the layout width is declared rather than coded, and it is maintained by the WordPress project.

Where it stops being enough: a portfolio is not a blog, and this theme does nothing to help you build one. There is no gallery treatment, no lightbox, no masonry grid and no photography-oriented template, only the block editor's media blocks. The last release was also five months before this was checked, so a fix would arrive on the project's schedule rather than yours.

Ollie is 1.6.5, published 2026-10-08, with around 6,000 active installations and 36 reviews averaging 100%. It registers no image sizes, bundles no JavaScript, and declares 740 pixels for content with 1,260 for wide. For a photographer who wants a mostly blank block canvas and will build the pages in the editor, it is the least opinionated option here.

Where it stops being enough: 6,000 installs is a small user base, so you are relying on one maintainer and a small community when something breaks. It also carries no gallery or portfolio patterns aimed at photographs, so the layout is your work. Check its support forum activity before you build a business site on it, and keep a staging copy of the site so a theme update can be tested against your own images.

Blocksy controls lazy loading, which the core themes leave to WordPress

Blocksy is 2.1.60, updated 2026-10-15, with around 300,000 active installations and 873 reviews averaging 100%. It is not a block theme in the strict sense; it is a customiser-driven theme that ships a theme.json and a large settings interface. What earns it a place here is inc/classes/lazy-loading.php, which filters WordPress's own lazy-loading decision and adds decoding="async" and fetchpriority="low" to images inside defined "zones", while leaving an image alone when its fetch priority is already high. That is more control over how images load than the core themes give you, and it is configurable from the performance settings screen.

Where it stops being enough: the same file is the reason to be careful. A theme that decides when an image is lazy and when it is not can get the hero image wrong, and a hero image that is lazy-loaded is the most common cause of a slow largest contentful paint on a portfolio page. Test the first screen with the browser's network panel. The wider risk is the theme's size: its PHP, CSS and JavaScript add up to several megabytes in the download, which is not what is delivered to the browser but is what gets updated every few weeks.

Kadence and Neve are the two general-purpose options that scale, and they take opposite approaches to the same problem.

Kadence is 1.5.2, last updated 2026-07-24, last updated 2026-07-24, with around 500,000 active installations and 455 reviews averaging 98%. It registers no image sizes of its own, declares its content and wide widths through theme.json as calculated values, and exposes those widths in the customiser, so the number that feeds the sizes attribute is yours to set. It also carries an image-sizes component whose filters adjust the sizes attribute for content images and post thumbnails; those two filters are commented out in 1.5.2, so the behaviour you get is core's. It is the theme I would choose for a photographer who wants a familiar settings screen, a real support community and no surprises in the image pipeline.

Neve is 4.2.16, updated 2026-10-07, with around 200,000 active installations and 1,283 reviews averaging 94%. It has no theme.json, sets a 1,200-pixel content width in PHP, and registers the neve-blog 930 by 620 crop described above. It also marks header and logo images with a skip-lazy class, which is the correct small detail: the thing at the top of the page should not wait for a scroll. Use it for a blog with photography in it, not for a portfolio.

Fotografie is the only theme here built for photographs, crops included

Fotografie is 2.5.5, updated 2026-10-10, with around 3,000 active installations and 25 reviews averaging 96%. It is a classic theme with a front-page template, a slider slot, and the five registered sizes listed above. For a working photographer who wants a portfolio layout assembled this week rather than built from blocks, it is the fastest route of the six, and its sizes are generous where it matters: a 1,920 by 1,080 slider size is enough for a full-width hero on most laptops.

Where it stops being enough: the crops are mandatory. Its grid depends on square thumbnails and a 16:9 slider, so a vertical frame or a 4:5 portrait will be cropped to fit. It also has the smallest install base in this list, at around 3,000 sites, which is a real support risk for a theme whose last release was a week before this was checked. If you shoot in more than one aspect ratio, a block theme with no registered sizes will treat your images better than this one does.

What none of these six will fix

The theme decides the widths and the crops. It does not decide what you uploaded. A 6 MB JPEG straight from a camera is a 6 MB file no matter which of these themes is active, and compression is a plugin's job, not a theme's. Nor does the theme choose the format: if you export JPEG and nothing converts it to WebP or AVIF, the browser downloads JPEG. Watermarking, colour management and the ICC profile are all outside this as well, and a theme that resizes an image is not a theme that preserves the profile you embedded for print.

There is one more limit. A theme cannot make a 1,200-pixel export sharp on a 5K display, and upscaling is the browser's decision. Upload the largest version you are willing to serve, let WordPress generate the smaller copies, and check which width the browser picked.

Monday: pick one, then test it with your own worst photograph

  1. Decide the answer to one question first: do you want the theme to crop for you, or not. If not, choose Twenty Twenty-Five, Ollie, Kadence or Blocksy. If yes, Fotografie or Neve.
  2. Build the portfolio page with three images: your widest panorama, your tallest portrait, and a photograph with a face near an edge. Those three find every bad crop.
  3. Look at the page in the browser's network panel and note which file width was downloaded for the largest image on the page. If it is bigger than the space it occupies, the theme's content width or the image size you inserted is wrong.
  4. Check the theme's wordpress.org page for the last-updated date and write it next to the version you installed.
  5. Add image compression separately. A theme is not a delivery pipeline.

A free theme is enough for a portfolio, and the one you choose decides two things: how wide your images may be, and whether anything gets cropped. Both are visible in the theme's source before you install it. When the constraint is a page template no free theme ships, that is a different purchase. Paid WordPress themes for photographers: portfolios that load fast covers the templates and the delivery layer, and says when the free route is still the right one.

Priya Raghunathan · @praghunathan

Frontend and accessibility

Reviews interfaces for what happens when JavaScript fails, the keyboard is the only input, and the connection is slow. Focused on Core Web Vitals, semantic markup and progressive enhancement.

Continue

Related in Frontend & Accessibility