Over 10,000 5-star reviews on Trustpilot, Reviews.io, the App Store & GoogleFive green stars
Printed on Fuji paper in professional UK photo labs
Every order checked by a trained technician
Printing 7 days a week · Order prints by 3.15pm for same-day printing
|
|
|
|
Back
Photo Prints
Family looking at photo prints at homeView All Photo Prints
Back
Photo Cards + Postcards
Personalised photo postcard printed and posted by PostSnapPostcards

Design 1 - London

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.

<div id="configurator-container-445a18a8"> <style> #configurator-container-445a18a8 { max-width: 800px; margin: 0 auto; box-sizing: border-box; text-align: left; } .selection-group { margin-bottom: 20px; padding: 15px; border: 1px solid #eee; border-radius: 5px; background-color: #fdfdfd; } .selection-group p { font-weight: 600; margin-top: 0; margin-bottom: 10px; color: #333; } .options-grid { display: flex; flex-wrap: wrap; gap: 10px; } .option-button { display: inline-block; box-sizing: border-box; font-family: 'Poppins', sans-serif; font-size: 14px; font-weight: 500; line-height: 20px; min-width: 95px; text-align: center; cursor: pointer; margin-bottom: 10px; margin-right: 10px; border-radius: 0; -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, outline-color 0.15s ease, box-shadow 0.15s ease; color: rgb(73, 74, 75); background-color: white; border: 1px solid rgb(201, 201, 201); outline: 1px solid transparent; padding: 10px 15px; box-shadow: none; } .option-button:hover:not(.active):not(.disabled) { border-color: #999; } .option-button.active { color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); border: 2px solid rgb(0,0,0); outline: 2px solid white; outline-offset: -1px; box-shadow: 0 0 0 1px black; padding: 10px 15px; font-weight: 500; } .option-button.disabled { color: #aaa; background-color: #f8f8f8; border: 1px solid #e0e0e0; outline: 1px solid transparent; opacity: 0.6; cursor: not-allowed; padding: 10px 15px; box-shadow: none; } #configurator-container-445a18a8 #product-info { margin-top: 20px; padding: 15px; border-radius: 5px; border: 1px solid #ddd; } #configurator-container-445a18a8 #product-info p { margin: 8px 0; } .price-container { display: flex; align-items: center; font-size: 16px; } .price-label { margin-right: 8px; } .currency-symbol { font-weight: 500; color: #ff5a5f; } .actual-price { font-weight: 500; color: #ff5a5f; } #configurator-container-445a18a8 a#create-button { display: block; width: 100%; padding: 12px; background-color: #4b5566; color: white !important; border: none; border-radius: 5px; font-size: 16px; font-family: 'Poppins', sans-serif; font-weight: 500; cursor: pointer; margin-top: 15px; transition: background-color 0.3s; text-decoration: none; text-align: center; } #configurator-container-445a18a8 a#create-button.disabled { background-color: #ccc; cursor: not-allowed; pointer-events: none; } #configurator-container-445a18a8 a#create-button:not(.disabled):hover { background-color: #3a4250; } </style> <script> (function() { const productsData = [{"design_id":4069,"design_slug":"a4-portrait-13mm-unmounted-caption-design-1-a4-london","product_id":1157,"product_slug":"a4-portrait-13mm-unmounted-caption","product_name":"Framed Caption Print - A4 (21x30cm) - 13mm frame","size":"A4","frame_width":"13mm","orientation":"Portrait","price":20.0,"editor_url":"https://preview.post-snap.com/app/create/framed-caption-prints/a4-portrait-13mm-unmounted-caption/a4-portrait-13mm-unmounted-caption-design-1-a4-london","preview_url":"https://eclipse-engine.s3.amazonaws.com/g/uploads/design_asset-374B-5B0C-B25B-34D5-58FC.jpg"},{"design_id":4091,"design_slug":"a4-portrait-20mm-unmounted-caption-design-1-a4-london","product_id":1158,"product_slug":"a4-portrait-20mm-unmounted-caption","product_name":"Framed Caption Print - A4 (21x30cm) - 20mm frame","size":"A4","frame_width":"20mm","orientation":"Portrait","price":25.0,"editor_url":"https://preview.post-snap.com/app/create/framed-caption-prints/a4-portrait-20mm-unmounted-caption/a4-portrait-20mm-unmounted-caption-design-1-a4-london","preview_url":"https://eclipse-engine.s3.amazonaws.com/u/uploads/design_asset-DAC7-DE04-1630-D40E-612D.jpg"}]; const showOrientationSelector = false; const sizesList = ["A4"]; const frameWidthsList = ["13mm","20mm"]; const updateMainImageEnabled = true; const container = document.getElementById('configurator-container-445a18a8'); if (!container) return; // Check URL parameters for pre-selection const urlParams = new URLSearchParams(window.location.search); const slugParam = urlParams.get('slug'); // Try to find product by slug let preselectedProduct = null; if (slugParam) { preselectedProduct = productsData.find(p => p.product_slug === slugParam || p.design_slug === slugParam); } // Initialize state with smart defaults or from URL let selectedOrientation = preselectedProduct ? preselectedProduct.orientation : 'Portrait'; // Filter products by orientation for initial setup const productsForOrientation = (showOrientationSelector && selectedOrientation) ? productsData.filter(p => p.orientation === selectedOrientation) : productsData; // Get available sizes for this orientation (ordered by sizesList) const availableSizes = sizesList.filter(sz => productsForOrientation.some(p => p.size === sz)); // Default to first available size (or from URL preselection) let selectedSize = preselectedProduct ? preselectedProduct.size : (availableSizes.length > 0 ? availableSizes[0] : null); // Default to first available frame width for this size/orientation (or from URL preselection) const availableFrameWidths = frameWidthsList.filter(fw => productsForOrientation.some(p => p.size === selectedSize && p.frame_width === fw) ); let selectedFrameWidth = preselectedProduct ? preselectedProduct.frame_width : (availableFrameWidths.length > 0 ? availableFrameWidths[0] : null); let selectedFrameColor = 'black'; function ensureValidSelection() { const productsForOrientation = showOrientationSelector && selectedOrientation ? productsData.filter(p => p.orientation === selectedOrientation) : productsData; // Ensure selected size is valid for this orientation const firstAvailableSize = sizesList.find(sz => productsForOrientation.some(p => p.size === sz)); if (!selectedSize || !productsForOrientation.some(p => p.size === selectedSize)) { selectedSize = firstAvailableSize || null; } // Ensure selected frame width is valid for size/orientation const productsForSize = productsForOrientation.filter(p => p.size === selectedSize); const firstAvailableFrameWidth = frameWidthsList.find(fw => productsForSize.some(p => p.frame_width === fw) ); if (!selectedFrameWidth || !productsForSize.some(p => p.frame_width === selectedFrameWidth)) { selectedFrameWidth = firstAvailableFrameWidth || null; } } function init() { ensureValidSelection(); updateUI(); attachEventListeners(); } function updateUI() { ensureValidSelection(); if (showOrientationSelector) { updateOrientationButtons(); } updateAvailability(); updatePrice(); updateMainImage(); updateCTA(); } function updateOrientationButtons() { container.querySelectorAll('[data-orientation]').forEach(btn => { btn.classList.toggle('active', btn.dataset.orientation === selectedOrientation); }); } function updateAvailability() { // Filter products by orientation first (if orientation selector is shown) const productsForOrientation = showOrientationSelector ? productsData.filter(p => p.orientation === selectedOrientation) : productsData; // Update size buttons - show/hide based on availability for this orientation container.querySelectorAll('[data-size]').forEach(btn => { const size = btn.dataset.size; const hasSize = productsForOrientation.some(p => p.size === size); btn.style.display = hasSize ? '' : 'none'; btn.disabled = !hasSize; btn.classList.toggle('active', selectedSize === size); btn.classList.toggle('disabled', !hasSize); }); // Update frame width buttons container.querySelectorAll('[data-frame-width]').forEach(btn => { const fw = btn.dataset.frameWidth; const hasFrameWidth = productsForOrientation.some(p => p.size === selectedSize && p.frame_width === fw); btn.disabled = !hasFrameWidth; btn.classList.toggle('active', selectedFrameWidth === fw); btn.classList.toggle('disabled', !hasFrameWidth); }); // Update color options container.querySelectorAll('[data-color]').forEach(btn => { btn.classList.toggle('active', btn.dataset.color === selectedFrameColor); }); } function updatePrice() { const productsForOrientation = showOrientationSelector ? productsData.filter(p => p.orientation === selectedOrientation) : productsData; const product = productsForOrientation.find(p => p.size === selectedSize && p.frame_width === selectedFrameWidth ); const priceEl = container.querySelector('#actual-price'); if (priceEl) { if (product) { priceEl.textContent = product.price.toFixed(2); } else { priceEl.textContent = 'N/A'; } } } function updateMainImage() { if (!updateMainImageEnabled) return; const productsForOrientation = showOrientationSelector ? productsData.filter(p => p.orientation === selectedOrientation) : productsData; const product = productsForOrientation.find(p => p.size === selectedSize && p.frame_width === selectedFrameWidth ); const mainImage = document.querySelector('#main-image'); console.log('[FCP] updateMainImage', { mainImageFound: !!mainImage, productFound: !!product, previewUrl: product?.preview_url, selectedOrientation, selectedSize, selectedFrameWidth }); if (mainImage && product && product.preview_url) { // Override any existing srcset/sizes so the preview URL is used immediately mainImage.src = product.preview_url; if (mainImage.hasAttribute('srcset')) mainImage.removeAttribute('srcset'); if (mainImage.hasAttribute('sizes')) mainImage.removeAttribute('sizes'); console.log('[FCP] Image updated to:', product.preview_url); } } function updateCTA() { const productsForOrientation = showOrientationSelector ? productsData.filter(p => p.orientation === selectedOrientation) : productsData; const product = productsForOrientation.find(p => p.size === selectedSize && p.frame_width === selectedFrameWidth ); const ctaBtn = container.querySelector('#create-button'); if (ctaBtn) { if (!product) { ctaBtn.classList.add('disabled'); ctaBtn.removeAttribute('href'); ctaBtn.onclick = (e) => e.preventDefault(); } else { ctaBtn.classList.remove('disabled'); const url = product.editor_url + '?frame=' + selectedFrameColor; ctaBtn.href = url; // Navigate in same window - no onclick override needed } } } function attachEventListeners() { // Orientation buttons if (showOrientationSelector) { container.querySelectorAll('[data-orientation]').forEach(btn => { btn.addEventListener('click', function() { selectedOrientation = this.dataset.orientation; // Reset size and frame width to smart defaults for this orientation const productsForOrientation = productsData.filter(p => p.orientation === selectedOrientation); if (productsForOrientation.length > 0) { // Keep current size if available, otherwise use first available based on sizesList ordering const sizeAvailable = productsForOrientation.some(p => p.size === selectedSize); if (!sizeAvailable) { const firstAvailable = sizesList.find(sz => productsForOrientation.some(p => p.size === sz)); selectedSize = firstAvailable || productsForOrientation[0].size; } // Keep current frame width if available for this size/orientation const frameAvailable = productsForOrientation.some(p => p.size === selectedSize && p.frame_width === selectedFrameWidth ); if (!frameAvailable) { const productsForSize = productsForOrientation.filter(p => p.size === selectedSize); selectedFrameWidth = productsForSize.length > 0 ? productsForSize[0].frame_width : productsForOrientation[0].frame_width; } } ensureValidSelection(); updateUI(); }); }); } // Size buttons container.querySelectorAll('[data-size]').forEach(btn => { btn.addEventListener('click', function() { if (this.disabled) return; selectedSize = this.dataset.size; // When size changes, ensure frame width is valid for this orientation/size const productsForOrientation = showOrientationSelector ? productsData.filter(p => p.orientation === selectedOrientation) : productsData; const productsForSize = productsForOrientation.filter(p => p.size === selectedSize); if (productsForSize.length > 0) { const frameValid = productsForSize.some(p => p.frame_width === selectedFrameWidth); if (!frameValid) { selectedFrameWidth = productsForSize[0].frame_width; } } ensureValidSelection(); updateUI(); }); }); // Frame width buttons container.querySelectorAll('[data-frame-width]').forEach(btn => { btn.addEventListener('click', function() { if (this.disabled) return; selectedFrameWidth = this.dataset.frameWidth; ensureValidSelection(); updateUI(); }); }); // Color options container.querySelectorAll('[data-color]').forEach(btn => { btn.addEventListener('click', function() { selectedFrameColor = this.dataset.color; updateUI(); }); }); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })(); </script> <div class="selection-group"> <p>Size:</p> <div class="options-grid"> <button type="button" class="option-button" data-size="A4">A4</button> </div> </div> <div class="selection-group"> <p>Frame Thickness:</p> <div class="options-grid"> <button type="button" class="option-button" data-frame-width="13mm">13mm</button> <button type="button" class="option-button" data-frame-width="20mm">20mm</button> </div> </div> <div class="selection-group"> <p>Frame Colour:</p> <div class="options-grid"> <button type="button" class="option-button" data-color="black">Black</button> <button type="button" class="option-button" data-color="white">White</button> <button type="button" class="option-button" data-color="natural">Natural</button> </div> </div> <div id="product-info"> <p class="price-container"> <span class="price-label">Price:</span> <span class="currency-symbol">£</span> <span id="actual-price" class="actual-price">N/A</span> </p> <a id="create-button" href="#" role="button">Personalise Your Print</a> </div> </div>

You may also like

Create a personalised framed collage print with up to 12 photos. We print your montage as a single sheet with adjustable internal dividers, then we frame it — so there’s nothing to arrange at home.

Framed Collage Photo Prints — Showcase Up to 12 Photos in One Frame

Framed Collage Pictures

Turn a collection of your favourite moments into one beautiful framed collage photo print.
Perfect for family highlights, travel adventures, or milestone memories, our collage prints let you display up to 12 photos in a single ready-to-hang frame.
Professionally printed on premium photo paper and mounted in a stylish wooden frame, these multi-photo prints are designed to make a statement in any room.

Crystal-Clear Quality for Every Photo

Each collage is printed on professional photo paper for crisp detail and rich colour.
From close-ups to landscapes, your photos are reproduced with lifelike clarity and depth, giving your montage a polished, gallery-quality finish.

Flexible Layout Options

Our easy online collage maker allows you to arrange up to 12 photos on one print.
Adjust the thickness and curve of the grid lines between images to create the look you love — from bold dividers to subtle spacing.
With square, portrait, and landscape formats, it’s simple to design a layout that suits your photos and your space.

Photo Frames That Elevate Your Story

Choose from premium wooden frames in Black, White or Natural.
Every frame comes with crystal-clear acrylic glazing (lighter and safer than glass) and hanging brackets and so arrives fully assembled, ready to hang straight out of the box. The A5 and A4 frames even include a leg to stand the frame up on a sideboard or mantelpiece.A3 framed prints are wall hung only.

Photo Frame Sizes & Formats

Available in A5, A4, A3, and 30×30 cm square formats.
Our framed collage prints include compact sizes which are ideal for desks, shelves, or gifting, while larger frames create striking wall art.
A5 and A4 frames include both an easel stand and wall hanging kit, while A3 and larger formats are designed for wall display.

Fast UK Frame Production & Delivery

  • Production time: 2–3 working days after order approval
  • Delivery options:
    • Standard: 3–5 working days after production
    • Express: 1–2 working days after production

Every framed collage is carefully packaged for safe delivery to your door.

How to Order Your Framed Collage Photo Print

  1. Choose your size, format and frame options
  2. Upload up to 12 photos from your device
  3. Customise your collage layout — adjust grid lines, crop and preview
  4. Confirm and place your order
  5. Relax while we professionally print, frame and deliver your collage print

Why Choose Our Framed Collage Photo Prints?

  • Display up to 12 photos in one stylish frame
  • Adjustable grid spacing for a custom look
  • Premium printing and professional frames
  • Made in the UK, delivered fast & securely
  • A perfect gift or keepsake for family and friends