Portfolio Page Masonry

I released a new version (free) (30 – May – 2026). You can check it here

Description: Portfolio Page to Masonry layout

 

#1. First, you need to change Portfolio Page to Grid: Overlay layout

#2. Use this code to Custom CSS

/* Portfolio Masonry Styles - @tuanphan */
.portfolio-masonry {
  animation: fadein 1s 0.15s backwards;
  display: block !important;
  grid-template-columns: none !important;
}

.portfolio-masonry .grid-item {
  margin-bottom: 10px !important;
  break-inside: avoid;
  transition: all 0.3s ease;
  height: auto !important;
  position: relative !important;
  padding-bottom: 0 !important;
  box-sizing: border-box !important;
}

.portfolio-masonry .grid-item:first-child {
  margin-top: 0 !important;
}

.portfolio-masonry .grid-item .grid-image {
  position: relative !important;
  overflow: hidden;
  width: 100%;
  margin: 0;
  line-height: 0;
  padding-bottom: 0 !important;
}

.portfolio-masonry .grid-item .grid-image-inner-wrapper {
  position: relative !important;
  top: auto !important;
  left: auto !important;
  bottom: auto !important;
  right: auto !important;
  width: 100% !important;
  height: auto !important;
}

.portfolio-masonry .grid-item img {
  width: 100% !important;
  height: auto !important;
  display: block !important;
  position: static !important;
  object-fit: cover !important;
}

.portfolio-masonry .grid-item .portfolio-overlay,
.portfolio-masonry .grid-item .portfolio-text {
  position: absolute !important;
  top: 0 !important;
  left: 0 !important;
  width: 100% !important;
  height: 100% !important;
  z-index: 99;
}

.portfolio-masonry .grid-item .portfolio-text {
  z-index: 100;
  display: flex;
  align-content: center;
  justify-content: center;
  flex-direction: column;
  padding: 7%;
  text-align: center;
  transition: opacity ease 200ms;
}

.portfolio-masonry .grid-item .portfolio-text .portfolio-title {
  margin-top: 0;
  padding-top: 0;
  margin-bottom: 0;
  font-size: 20px !important;
}

@keyframes fadein {
  from { 
    opacity: 0; 
    transform: translateY(20px); 
  }
  to { 
    opacity: 1; 
    transform: translateY(0); 
  }
}

@media (max-width: 767px) {
  .portfolio-masonry {
    column-count: 2;
    column-gap: 10px;
    column-fill: balance;
    padding: 0 10px;
  }
  .portfolio-masonry .grid-item {
    margin-bottom: 10px !important;
    display: inline-block !important;
    width: 100% !important;
  }
}

@media (min-width: 768px) {
  .portfolio-masonry {
    column-count: 3;
    column-gap: 10px;
    column-fill: balance;
    padding: 0 15px;
  }
  .portfolio-masonry .grid-item {
    margin-bottom: 10px !important;
    display: inline-block !important;
    width: 100% !important;
  }
}

.portfolio-masonry#gridThumbs .portfolio-text {
  width: calc(~"100% - 40px") !important;
  height: calc(~"100% - 40px") !important;
  padding: 20px !important;
}
/* END Portfolio Masonry Styles - @tuanphan */

 

#3. Use this code to Portfolio Page Header Injection

<script>
(function(){function getImageAspectRatio(img){const dimensions=img.getAttribute('data-image-dimensions');if(!dimensions)return 1;const[width,height]=dimensions.split('x').map(d=>parseFloat(d));return height/width}
function initPortfolioMasonry(container,options={}){container.classList.add('portfolio-masonry');const items=[...container.querySelectorAll('.grid-item')];items.forEach((item,index)=>{const img=item.querySelector('img[data-src], img[src]');const wrapper=item.querySelector('.grid-image-inner-wrapper');const gridImage=item.querySelector('.grid-image');if(img&&wrapper){item.style.height='auto';item.style.position='relative';item.style.paddingBottom='0';if(gridImage){gridImage.style.paddingBottom='0'}
wrapper.style.position='relative';wrapper.style.top='auto';wrapper.style.left='auto';wrapper.style.bottom='auto';wrapper.style.right='auto';wrapper.style.width='100%';wrapper.style.height='auto';wrapper.style.paddingBottom='0';img.style.position='static';img.style.width='100%';img.style.height='auto';img.style.objectFit='none';img.style.display='block'}
item.style.animationDelay=(index*0.1)+'s'});if(options.shuffle){const shuffled=items.sort(()=>Math.random()-0.5);shuffled.forEach(item=>container.appendChild(item))}
setTimeout(()=>{items.forEach(item=>{item.style.opacity='1';item.style.transform='translateY(0)'})},100)}
function initPortfolioMasonryPlugin(options={}){const defaultOptions={shuffle:!1,selector:'#gridThumbs, .portfolio-grid-overlay'};const config=Object.assign(defaultOptions,options);let containers=[];let selector=config.selector;if(config.containerIDs){selector=[];config.containerIDs.split(',').forEach(id=>{const cleanId=id.replace(/#|\./,'');if(config.ignoreContainerIDs){selector.push(`:not([id="${cleanId}"])`)}else{selector.push(`[id="${cleanId}"]`)}});if(config.ignoreContainerIDs){selector='.portfolio-grid-overlay'+selector.join('')}else{selector=selector.join(',')}}
containers=[...document.querySelectorAll(selector)];containers.forEach(container=>{if(!container.classList.contains('portfolio-masonry')){initPortfolioMasonry(container,config)}})}
function domReady(callback){if(document.readyState==='interactive'||document.readyState==='complete'){callback()}else{document.addEventListener('DOMContentLoaded',callback)}}
function ajaxReady(callback){const ajaxBody=document.querySelector('body[data-ajax-loader]');if(ajaxBody){const observer=new MutationObserver(mutations=>{if(mutations[0].attributeName==='data-ajax-loader'&&ajaxBody.getAttribute('data-ajax-loader')==='loaded'){callback()}});observer.observe(ajaxBody,{attributes:!0})}else{window.addEventListener('mercury:load',callback)}}
function dynamicDataReady(callback){}
function init(options={}){domReady(()=>initPortfolioMasonryPlugin(options));ajaxReady(()=>initPortfolioMasonryPlugin(options));dynamicDataReady(()=>initPortfolioMasonryPlugin(options));window.addEventListener('load',()=>{setTimeout(()=>initPortfolioMasonryPlugin(options),100)});window.addEventListener('resize',()=>{setTimeout(()=>initPortfolioMasonryPlugin(options),200)})}
window.portfolioMasonry={init};setTimeout(()=>{console.log('Portfolio Masonry: Starting auto init...');init()},100)})()
</script>

#3. To change space between items, change these.

Buy me a coffee