Photo Gallery with Albums A Better Way to Organize and Display Your Photos
This article presents the function of the module that allows to retrieve a list of photos from a predefined URL. The album works on the principle of a link leading to a subpage, from which the list of photos will be loaded into the gallery module. In simple terms: the links lead to pages that contain separate lists of photos. The following example illustrates the basic use of the module:
<nav class="gallery gallery-row">
<a href="blog-gallery-album-first.html" class="gallery-thumbnail gallery-album"><img src="uploads/images/blog/galeria/galeria-m-01.jpg" alt="Miniatura zdjęcia"></a>
<a href="blog-gallery-album-second.html" class="gallery-thumbnail gallery-album"><img src="uploads/images/blog/galeria/galeria-m-02.jpg" alt="Miniatura zdjęcia"></a>
<a href="blog-gallery-album-third.html" class="gallery-thumbnail gallery-album"><img src="uploads/images/blog/galeria/galeria-m-03.jpg" alt="Miniatura zdjęcia"></a>
<a href="blog-gallery-album-fourth.html" class="gallery-thumbnail gallery-album"><img src="uploads/images/blog/galeria/galeria-m-04.jpg" alt="Miniatura zdjęcia"></a>
<a href="blog-gallery-album-fifth.html" class="gallery-thumbnail gallery-album"><img src="uploads/images/blog/galeria/galeria-m-05.jpg" alt="Miniatura zdjęcia"></a>
</nav>
.compsoul-gallery-div, .compsoul-gallery-small, .compsoul-gallery-small,
.compsoul-gallery-big, .compsoul-gallery-hash, .compsoul-gallery-hash-test,
.compsoul-gallery-comment, .compsoul-gallery-comment-inside, .compsoul-gallery-comment-mix, .compsoul-gallery {
display: inline-block;
position: relative;
}
.compsoul-gallery-div:after, .compsoul-gallery-small:after, .compsoul-gallery-small:after,
.compsoul-gallery-big:after, .compsoul-gallery-hash:after, .compsoul-gallery-hash-test:after,
.compsoul-gallery-comment:after, .compsoul-gallery-comment-inside:after, .compsoul-gallery-comment-mix:after, .compsoul-gallery:after {
bottom: 0;
content: "";
left: 0;
position: absolute;
right: 0;
top: 0;
}
.compsoul-gallery {
display: inline-block;
max-width: 80%;
}
.compsoul-gallery-container {
background: rgba(25, 25, 25, 0.96);
bottom: 0;
font-size: 8px;
left: 0;
position: fixed;
right: 0;
top: 0;
will-change: auto;
z-index: 10;
}
.compsoul-gallery-container .compsoul-hidden {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
position: absolute;
padding: 0;
width: 1px;
}
.compsoul-gallery-container.compsoul-active {
animation: gallery-container 0.2s linear;
will-change: opacity;
}
.compsoul-gallery-container.compsoul-inactive {
animation: gallery-container-close 0.2s linear forwards;
will-change: opacity;
}
@keyframes gallery-container {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes gallery-container-close {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.compsoul-gallery-container button {
background: none;
border: none;
cursor: pointer;
font-size: inherit;
line-height: 0;
margin: 0;
padding: 0;
}
.compsoul-gallery-content {
bottom: 0;
position: absolute;
left: 0;
right: 0;
top: 0;
z-index: 0;
}
.thumbnails-active .compsoul-gallery-content {
bottom: 120px;
}
.thumbnails-inactive .compsoul-gallery-content {
bottom: 0;
}
.compsoul-gallery-content .compsoul-gallery-item {
height: 80vh;
height: calc(100vh - 172px);
left: 50%;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
user-select: none;
visibility: hidden;
width: 80vw;
width: calc(100vw - 204px);
will-change: auto;
z-index: 0;
}
.compsoul-gallery-item.compsoul-active, .compsoul-gallery-item.compsoul-prev, .compsoul-gallery-item.compsoul-next {
opacity: 1;
transform: translate(-150vw, -50%);
transition: opacity 0.3s ease-out, transform 0.3s ease-out;
visibility: visible;
will-change: opacity, transform;
z-index: 1;
}
.compsoul-gallery-item.compsoul-fade {
opacity: 0;
transition: opacity 0.2s ease-out;
visibility: visible;
will-change: opacity;
}
.compsoul-direction-prev .compsoul-gallery-item.compsoul-prev,
.compsoul-direction-next .compsoul-gallery-item.compsoul-next {
transition: unset;
will-change: auto;
}
.compsoul-resize .compsoul-gallery-item.compsoul-prev {
animation: compsoul-resize-prev 0.1s linear forwards;
}
@keyframes compsoul-resize-prev {
from {
transform: translate(-150vw, -50%);
}
to {
transform: translate(-150vw, -50%);
}
}
.compsoul-resize .compsoul-gallery-item.compsoul-next {
animation: compsoul-resize-next 0.1s linear forwards;
}
@keyframes compsoul-resize-next {
from {
transform: translate(50vw, -50%);
}
to {
transform: translate(50vw, -50%);
}
}
.compsoul-gallery-item.compsoul-next {
transform: translate(50vw, -50%);
}
.compsoul-gallery-item.compsoul-active {
transform: translate(-50%, -50%);
}
.compsoul-disorderly .compsoul-gallery-item,
.compsoul-disorderly .compsoul-gallery-item.compsoul-prev,
.compsoul-disorderly .compsoul-gallery-item.compsoul-next {
opacity: 0;
transition: unset;
visibility: hidden;
will-change: auto;
z-index: 2;
}
.compsoul-disorderly .compsoul-gallery-item.compsoul-past {
animation: disorderly-past 0.2s linear;
will-change: opacity, transform, visibility;
z-index: 3;
}
@keyframes disorderly-past {
0% {
opacity: 1;
transform: translate(-50%, -50%);
visibility: visible;
}
99% {
opacity: 0;
transform: translate(-50%, -50%);
visibility: visible;
}
100% {
opacity: 0;
transform: translate(-50%, -50%);
visibility: hidden;
}
}
.compsoul-disorderly .compsoul-gallery-item.compsoul-active {
animation: disorderly-active 0.2s linear;
opacity: 1;
visibility: visible;
will-change: opacity, transform, visibility;
z-index: 4;
}
@keyframes disorderly-active {
0% {
opacity: 0;
transform: translate(-50%, -50%);
visibility: hidden;
}
1% {
opacity: 0;
transform: translate(-50%, -50%);
visibility: visible;
}
100% {
opacity: 1;
transform: translate(-50%, -50%);
visibility: visible;
}
}
.compsoul-gallery-item .compsoul-gallery-image {
display: inline-block;
left: 50%;
opacity: 0.001;
overflow: hidden;
position: relative;
top: 50%;
transform: translate(-50%, -50%);
transform-origin: top left;
will-change: auto;
width: auto;
z-index: 1;
}
.compsoul-gallery-item.compsoul-active .compsoul-gallery-image {
transition: opacity 0.2s 0.2s linear, transform 0.2s linear;
will-change: opacity;
}
.compsoul-gallery-item .compsoul-gallery-image:before {
bottom: 0;
content: "";
left: 0;
position: absolute;
right: 0;
top: 0;
}
.thumbnails-show .compsoul-gallery-image {
transform: scale(0.8) translate(-50%, -50%);
}
.thumbnails-show .compsoul-gallery-item.compsoul-active .compsoul-gallery-image {
will-change: transform;
}
.compsoul-gallery-item.compsoul-loaded .compsoul-gallery-image {
opacity: 1;
}
.compsoul-gallery-item .compsoul-gallery-image img {
display: block;
max-height: 80vh;
max-height: calc(100vh - 172px);
max-width: 80vw;
max-width: calc(100vw - 204px);
}
.compsoul-gallery-item .compsoul-gallery-comment {
background: rgba(0, 0, 0, 0.6);
bottom: 0;
color: #f2f2f2;
font-family: Calibri, Candara, Segoe, Segoe UI, Optima, Arial, sans-serif;
font-size: 2em;
left: 0;
padding: 2em;
position: absolute;
right: 0;
transform: translate(0, 100%);
transition: transform 0.2s 0.4s linear;
z-index: 1;
}
.compsoul-disorderly .compsoul-gallery-item .compsoul-gallery-comment {
transform: translate(0, 0);
transition: unset;
}
.compsoul-gallery-item.compsoul-active.compsoul-loaded .compsoul-gallery-comment {
transform: translate(0, 0);
}
.compsoul-gallery-item .compsoul-gallery-comment.compsoul-inactive {
display: none;
}
.compsoul-loader {
left: 50%;
opacity: 0;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
z-index: 0;
}
.compsoul-loader:before, .compsoul-loader:after {
animation: compsoul-loading 1s linear infinite;
animation-play-state: paused;
border: 0.5em solid #f2f2f2;
border-radius: 100%;
content: "";
display: block;
filter: blur(1px);
height: 8em;
left: 50%;
opacity: 0;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
width: 8em;
}
.compsoul-gallery-item.compsoul-active .compsoul-loader,
.compsoul-gallery-item.compsoul-prev .compsoul-loader,
.compsoul-gallery-item.compsoul-next .compsoul-loader {
transition: opacity 0.2s linear;
}
.compsoul-gallery-item.compsoul-active .compsoul-loader {
opacity: 1;
}
.compsoul-gallery-item.compsoul-loaded .compsoul-loader {
opacity: 0;
}
.compsoul-gallery-item.compsoul-active.compsoul-loading .compsoul-loader:before,
.compsoul-gallery-item.compsoul-active.compsoul-loading .compsoul-loader:after {
animation-play-state: running;
}
.compsoul-loader:after {
animation-delay: 0.5s;
}
@keyframes compsoul-loading {
0% {
opacity: 0;
transform: translate(-50%, -50%) scale(0);
}
50% {
opacity: 1;
transform: translate(-50%, -50%) scale(0.5);
}
100% {
opacity: 0;
transform: translate(-50%, -50%) scale(1);
}
}
.compsoul-gallery-full-screen {
background: #000;
bottom: 0;
font-size: 0;
position: absolute;
left: 0;
opacity: 0;
overflow: auto;
right: 0;
top: 0;
transition: opacity 0.2s linear;
z-index: -1;
}
.compsoul-gallery-full-screen.compsoul-active {
z-index: 1;
}
.compsoul-zoom .compsoul-gallery-full-screen {
opacity: 1;
}
.compsoul-zoom-out .compsoul-gallery-full-screen {
opacity: 0;
transition-delay: 0.2s;
}
.compsoul-gallery-full-screen img {
display: block;
margin: 0 auto;
opacity: 0;
transition: opacity 0.2s 0.2s linear;
}
.compsoul-zoom .compsoul-gallery-full-screen img {
opacity: 1;
}
.compsoul-zoom-out .compsoul-gallery-full-screen img {
opacity: 0;
transition-delay: unset;
}
.compsoul-logo, .compsoul-gallery-close, .compsoul-gallery-next, .compsoul-gallery-prev, .thumbnails-toggle, .compsoul-gallery-progress, .compsoul-gallery-zoom {
cursor: pointer;
height: 7em;
outline: 1px solid rgba(242, 242, 242, 0);
overflow: hidden;
position: absolute;
right: 4em;
top: 2em;
transform: translate(0);
transition: outline 0.2s linear;
width: 7em;
}
.compsoul-logo {
box-sizing: border-box;
left: 4em;
right: auto;
transition: unset;
width: 8em;
}
.compsoul-logo svg {
fill: #f2f2f2;
top: 50%;
position: relative;
transform: translate(0, -50%);
transition: fill 0.2s linear;
}
.compsoul-logo:focus-within {
outline: none;
}
.compsoul-logo:hover svg, .compsoul-logo:focus-within svg {
fill: #e7a14f;
}
.compsoul-logo:focus-within, .compsoul-gallery-close:focus-within, .compsoul-gallery-next:focus-within, .compsoul-gallery-prev:focus-within, .thumbnails-toggle:focus-within, .compsoul-gallery-progress:focus-within, .compsoul-gallery-zoom:focus-within {
outline-color: rgba(242, 242, 242, 0.8);
}
.compsoul-gallery-close:before, .compsoul-gallery-next:before, .compsoul-gallery-prev:before, .thumbnails-toggle:before, .compsoul-gallery-progress:before, .compsoul-gallery-zoom:before, .compsoul-gallery-close:after, .compsoul-gallery-next:after, .compsoul-gallery-prev:after, .thumbnails-toggle:after, .compsoul-gallery-progress:after, .compsoul-gallery-zoom:after {
background: #111;
bottom: 0;
content: "";
position: absolute;
left: 0;
right: 0;
top: 0;
z-index: -2;
}
.compsoul-gallery-close:after, .compsoul-gallery-next:after, .compsoul-gallery-prev:after, .thumbnails-toggle:after, .compsoul-gallery-progress:after, .compsoul-gallery-zoom:after {
background: none;
z-index: 1;
}
.compsoul-gallery-close button, .compsoul-gallery-next button, .compsoul-gallery-prev button, .thumbnails-toggle button, .compsoul-gallery-progress button, .compsoul-gallery-zoom button {
outline: 0;
position: relative;
z-index: -1;
}
.compsoul-gallery-close button:before, .compsoul-gallery-close button:after, .compsoul-gallery-next button:before, .compsoul-gallery-prev button:before {
border-top: 0.25em solid #f2f2f2;
border-right: 0.25em solid #f2f2f2;
box-sizing: content-box;
content: "";
cursor: pointer;
display: inline-block;
height: 1em;
padding: 0 0 0.25em 0.25em;
width: 1em;
}
.compsoul-gallery-close {
z-index: 2;
}
.compsoul-gallery-close button {
cursor: pointer;
height: 6em;
left: 50%;
position: absolute;
top: 50%;
transform: translate(-50%, -50%) rotate(45deg);
width: 6em;
}
.compsoul-gallery-close button:before, .compsoul-gallery-close button:after {
bottom: 1.625em;
left: 1.625em;
position: absolute;
transform: rotate(0deg);
}
.compsoul-gallery-close button:before {
border: none;
border-bottom: 0.25em solid #f2f2f2;
border-left: 0.25em solid #f2f2f2;
left: auto;
padding: 0.25em 0.25em 0 0;
right: 1.625em;
top: 1.625em;
}
.compsoul-gallery-close button:after {
border-top: 0.25em solid #f2f2f2;
border-right: 0.25em solid #f2f2f2;
padding: 0 0 0.25em 0.25em;
}
.compsoul-gallery-zoom {
right: 28em;
}
.compsoul-gallery-zoom button {
cursor: pointer;
height: 100%;
position: relative;
width: 100%;
}
.compsoul-gallery-zoom button:before {
border: 0.25em solid #f2f2f2;
border-radius: 100%;
content: "";
height: 1.25em;
left: 50%;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
width: 1.25em;
}
.compsoul-gallery-zoom button:after {
background: #f2f2f2;
border-radius: 0 0 0.25em 0.25em;
content: "";
height: 1em;
left: 50%;
margin: 1em 0 0 -1.5em;
position: absolute;
top: 50%;
transform: rotate(45deg) translate(-50%, -50%);
width: 0.25em;
}
.compsoul-gallery-progress {
right: 20em;
}
.compsoul-gallery-progress button {
cursor: pointer;
height: 100%;
position: relative;
width: 100%;
}
.compsoul-gallery-progress button:before {
border-bottom: 1em solid transparent;
border-left: 1.2em solid #f2f2f2;
border-top: 1em solid transparent;
border-radius: 0.2em;
content: "";
height: 0;
left: 50%;
opacity: 1;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
transition: opacity 0.2s 0.2s linear;
width: 0;
}
.compsoul-gallery-progress.compsoul-active button:before {
opacity: 0;
transition-delay: unset;
}
.compsoul-gallery-progress button:after {
animation: gallery-progress 6s linear forwards;
animation-play-state: paused;
color: #f2f2f2;
content: "10";
font-size: 1.6em;
left: 50%;
opacity: 0;
position: absolute;
top: 50%;
transition: opacity 0.2s linear;
transform: translate(-50%, -50%);
}
.compsoul-gallery-progress.compsoul-active button:after {
opacity: 1;
transition-delay: 0.2s;
}
.compsoul-gallery-progress.compsoul-play button:after {
animation-delay: 0.4s;
animation-play-state: running;
}
.compsoul-gallery-progress.compsoul-unset button:after {
animation: unset;
}
@keyframes gallery-progress {
0% {
content: "10";
}
9% {
content: "9";
}
18% {
content: "8";
}
27% {
content: "7";
}
36% {
content: "6";
}
45% {
content: "5";
}
54% {
content: "4";
}
63% {
content: "3";
}
72% {
content: "2";
}
81% {
content: "1";
}
90% {
content: "0";
}
100% {
content: "0";
}
}
.compsoul-gallery-next, .compsoul-gallery-prev {
opacity: 0;
right: 4em;
top: 50%;
transform: translate(0, -50%);
transition: opacity 0.2s linear, outline 0.2s linear;
}
.compsoul-gallery-next.compsoul-active, .compsoul-gallery-prev.compsoul-active {
opacity: 1;
}
.compsoul-gallery-prev {
left: 4em;
}
.compsoul-gallery-next button, .compsoul-gallery-prev button {
left: 50%;
position: absolute;
top: 50%;
transform: translate(-1em, -50%);
}
.compsoul-gallery-prev button {
transform: translate(-0.5em, -50%);
}
.compsoul-gallery-next button:before, .compsoul-gallery-prev button:before {
transform: rotate(-135deg);
}
.compsoul-gallery-next button:before {
transform: rotate(45deg);
}
.thumbnails-toggle {
right: 12em;
}
.thumbnails-toggle button {
cursor: pointer;
height: 100%;
position: relative;
width: 100%;
}
.thumbnails-toggle button:before {
background-color: transparent;
background-image: linear-gradient(90deg, #f2f2f2 0.5em, transparent 0.25em),
linear-gradient(90deg, #f2f2f2 0.5em, transparent 0.25em),
linear-gradient(90deg, #f2f2f2 0.5em, transparent 0.25em);
background-position: 0 0, 0 0.75em, 0 1.5em;
background-repeat: repeat-x;
background-size: 0.75em 0.5em, 0.75em 0.5em, 0.75em 0.5em;
content: "";
cursor: pointer;
height: 2em;
left: 50%;
opacity: 0.6;
position: absolute;
top: 50%;
transition: opacity 0.4s linear;
transform: translate(-50%, -50%);
width: 2em;
}
.thumbnails-toggle:active button:before, .thumbnails-toggle button:active:before {
background-image: linear-gradient(90deg, #f2f2f2 0.5em, transparent 0.125em),
linear-gradient(90deg, #f2f2f2 0.5em, transparent 0.125em),
linear-gradient(90deg, #f2f2f2 0.5em, transparent 0.125em);
background-position: 0 0, 0 0.625em, 0 1.25em;
background-size: 0.625em 0.5em, 0.625em 0.5em, 0.625em 0.5em;
height: 1.75em;
width: 1.75em;
}
.thumbnails-show .thumbnails-toggle button:before {
opacity: 1;
}
.thumbnails-container {
background: #111;
bottom: 0;
font-size: 0;
height: 72px;
left: 0;
letter-spacing: 0;
position: fixed;
right: 0;
transition: transform 0.2s linear;
transform: translateY(100%);
}
.thumbnails-show .thumbnails-container {
transform: translateY(0);
}
.thumbnails-content {
bottom: 0;
left: 0;
position: absolute;
top: 0;
white-space: nowrap;
}
.thumbnails-show .thumbnails-content {
transition: transform 0.2s linear;
}
.thumbnails-content.compsoul-drag {
transition: unset;
}
.thumbnails-content.compsoul-drag:before {
bottom: 0;
content: "";
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: 2;
}
.thumbnails-content .thumbnails-image {
background: none;
border: none;
cursor: pointer;
display: inline-block;
font-size: 0;
height: 100%;
position: relative;
user-select: none;
}
.thumbnails-content .thumbnails-image:before, .thumbnails-content .thumbnails-image:after {
bottom: 0;
content: "";
left: 0;
opacity: 0;
outline: 1px solid #f2f2f2;
outline-offset: -1px;
position: absolute;
right: 0;
top: 0;
transition: opacity 0.2s linear;
z-index: 1;
}
.thumbnails-content .thumbnails-image:after {
outline-color: #e7a14f;
}
.thumbnails-content .thumbnails-image button:focus {
outline: none;
}
.thumbnails-content .thumbnails-image:focus-within:before {
opacity: 1;
}
.thumbnails-content .thumbnails-image.compsoul-active:after {
opacity: 1;
}
.thumbnails-content .thumbnails-image img {
display: block;
max-height: 72px;
}
.gallery {
display: flex;
flex-flow: row wrap;
gap: 10px;
}
.gallery-row {
display: flex;
flex: 1 100%;
flex-flow: row nowrap;
gap: 10px;
}
.gallery-thumbnail * {
pointer-events: none;
}
.gallery-thumbnail img {
height: 100%;
object-fit: cover;
width: 100%;
}
@media (max-width: 1000px) {
.compsoul-gallery-container {
font-size: 5.4px;
}
.compsoul-gallery-content .compsoul-gallery-item {
height: 100vh;
height: calc(100vh - 16px);
width: 100vw;
width: calc(100vw - 16px);
}
.thumbnails-show .compsoul-gallery-image {
transform: scale(0.68) translate(-50%, -50%);
}
.compsoul-gallery-item .compsoul-gallery-image img {
max-height: 100vh;
max-height: calc(100vh - 16px);
max-width: 100vw;
max-width: calc(100vw - 16px);
}
}
@media (max-width: 380px) {
.compsoul-gallery-content .compsoul-gallery-item {
height: 100vh;
width: 100vw;
}
.thumbnails-show .compsoul-gallery-image {
transform: scale(0.75) translate(-50%, -50%);
}
.compsoul-gallery-item .compsoul-gallery-image img {
max-height: 100vh;
max-width: 100vw;
}
}
<script src="https://compsoul.dev/uploads/js/compsoul.js"></script><script src="https://compsoul.dev/uploads/js/gallery.js"></script><script>
new Gallery(".gallery-album").options({
album: true
}).init();
</script>
The album retrieves the list of photos based on one of the attributes of the activated element. In the above demo, the href="[LINK TO THE PAGE WITH THE LIST]" attribute was used to retrieve the list. Additionally, we can retrieve the list of photos using the data-url="[LINK TO THE PAGE WITH THE LIST]" attribute. The next step after indicating the address with the list of photos is to create this list on the page passed by the attribute. The list of photos is exactly the same as in the case of the regular gallery mode:
<a href="uploads/images/blog/galeria/galeria-01.jpg" class="gallery-album"><img src="uploads/images/blog/galeria/galeria-m-01.jpg" alt="Miniatura zdjęcia"></a>
<a href="uploads/images/blog/galeria/galeria-02.jpg" class="gallery-album"><img src="uploads/images/blog/galeria/galeria-m-02.jpg" alt="Miniatura zdjęcia"></a>
<a href="uploads/images/blog/galeria/galeria-03.jpg" class="gallery-album"><img src="uploads/images/blog/galeria/galeria-m-03.jpg" alt="Miniatura zdjęcia"></a>
<a href="uploads/images/blog/galeria/galeria-04.jpg" class="gallery-album"><img src="uploads/images/blog/galeria/galeria-m-04.jpg" alt="Miniatura zdjęcia"></a>
<a href="uploads/images/blog/galeria/galeria-05.jpg" class="gallery-album"><img src="uploads/images/blog/galeria/galeria-m-05.jpg" alt="Miniatura zdjęcia"></a>
<a href="uploads/images/blog/galeria/galeria-06.jpg" class="gallery-album"><img src="uploads/images/blog/galeria/galeria-m-06.jpg" alt="Miniatura zdjęcia"></a>
<a href="uploads/images/blog/galeria/galeria-07.jpg" class="gallery-album"><img src="uploads/images/blog/galeria/galeria-m-07.jpg" alt="Miniatura zdjęcia"></a>
<a href="uploads/images/blog/galeria/galeria-08.jpg" class="gallery-album"><img src="uploads/images/blog/galeria/galeria-m-08.jpg" alt="Miniatura zdjęcia"></a>
<a href="uploads/images/blog/galeria/galeria-09.jpg" class="gallery-album"><img src="uploads/images/blog/galeria/galeria-m-09.jpg" alt="Miniatura zdjęcia"></a>
<a href="uploads/images/blog/galeria/galeria-10.jpg" class="gallery-album"><img src="uploads/images/blog/galeria/galeria-m-10.jpg" alt="Miniatura zdjęcia"></a>
Remember that each photo on the list page must have a selector compatible with the one used on the target page. In the above examples, it will be the class .gallery-album
In summary, for the album to work correctly, we need:
- The URL address of the page where the list of photos of a particular album has been placed
- A list containing the photos of the album
- An instance along with a selector passed on referring to the albums and the list of photos of a particular album.
Below I will try to present the complete implementation of the module in relation to the assumptions mentioned:
//Kod znajdujący się, przykładowo, w pliku index.html
<nav class="gallery gallery-row">
<a href="blog-gallery-album-first.html" class="gallery-thumbnail gallery-album"><img src="uploads/images/blog/galeria/galeria-m-01.jpg" alt="Miniatura zdjęcia"></a>
<a href="blog-gallery-album-second.html" class="gallery-thumbnail gallery-album"><img src="uploads/images/blog/galeria/galeria-m-02.jpg" alt="Miniatura zdjęcia"></a>
<a href="blog-gallery-album-third.html" class="gallery-thumbnail gallery-album"><img src="uploads/images/blog/galeria/galeria-m-03.jpg" alt="Miniatura zdjęcia"></a>
<a href="blog-gallery-album-fourth.html" class="gallery-thumbnail gallery-album"><img src="uploads/images/blog/galeria/galeria-m-04.jpg" alt="Miniatura zdjęcia"></a>
<a href="blog-gallery-album-fifth.html" class="gallery-thumbnail gallery-album"><img src="uploads/images/blog/galeria/galeria-m-05.jpg" alt="Miniatura zdjęcia"></a>
</nav>
//Kod znajdujący się w pliku blog-gallery-album-first.html. Jest to lista wszystkich zdjęć pierwszego albumu.
//Należy zwrócić szczególną uwagę na klasy CSS, które w obu przypadkach powinny być takie same,jak klasa użyta do wywołania instancji modułu w zakładce js.
<a class="gallery-album" href="uploads/images/blog/galeria/galeria-01-01.jpg">galeria-01-01.jpg</a>
<a class="gallery-album" href="uploads/images/blog/galeria/galeria-01-02.jpg">galeria-01-02.jpg</a>
<a class="gallery-album" href="uploads/images/blog/galeria/galeria-01-03.jpg">galeria-01-03.jpg</a>
<a class="gallery-album" href="uploads/images/blog/galeria/galeria-01-04.jpg">galeria-01-04.jpg</a>
<a class="gallery-album" href="uploads/images/blog/galeria/galeria-01-05.jpg">galeria-01-05.jpg</a>
<a class="gallery-album" href="uploads/images/blog/galeria/galeria-01-06.jpg">galeria-01-06.jpg</a>
<a class="gallery-album" href="uploads/images/blog/galeria/galeria-01-07.jpg">galeria-01-07.jpg</a>
<a class="gallery-album" href="uploads/images/blog/galeria/galeria-01-08.jpg">galeria-01-08.jpg</a>
<a class="gallery-album" href="uploads/images/blog/galeria/galeria-01-09.jpg">galeria-01-09.jpg</a>
<a class="gallery-album" href="uploads/images/blog/galeria/galeria-01-10.jpg">galeria-01-10.jpg</a>
.compsoul-gallery-div, .compsoul-gallery-small, .compsoul-gallery-small,
.compsoul-gallery-big, .compsoul-gallery-hash, .compsoul-gallery-hash-test,
.compsoul-gallery-comment, .compsoul-gallery-comment-inside, .compsoul-gallery-comment-mix, .compsoul-gallery {
display: inline-block;
position: relative;
}
.compsoul-gallery-div:after, .compsoul-gallery-small:after, .compsoul-gallery-small:after,
.compsoul-gallery-big:after, .compsoul-gallery-hash:after, .compsoul-gallery-hash-test:after,
.compsoul-gallery-comment:after, .compsoul-gallery-comment-inside:after, .compsoul-gallery-comment-mix:after, .compsoul-gallery:after {
bottom: 0;
content: "";
left: 0;
position: absolute;
right: 0;
top: 0;
}
.compsoul-gallery {
display: inline-block;
max-width: 80%;
}
.compsoul-gallery-container {
background: rgba(25, 25, 25, 0.96);
bottom: 0;
font-size: 8px;
left: 0;
position: fixed;
right: 0;
top: 0;
will-change: auto;
z-index: 10;
}
.compsoul-gallery-container .compsoul-hidden {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
position: absolute;
padding: 0;
width: 1px;
}
.compsoul-gallery-container.compsoul-active {
animation: gallery-container 0.2s linear;
will-change: opacity;
}
.compsoul-gallery-container.compsoul-inactive {
animation: gallery-container-close 0.2s linear forwards;
will-change: opacity;
}
@keyframes gallery-container {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes gallery-container-close {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.compsoul-gallery-container button {
background: none;
border: none;
cursor: pointer;
font-size: inherit;
line-height: 0;
margin: 0;
padding: 0;
}
.compsoul-gallery-content {
bottom: 0;
position: absolute;
left: 0;
right: 0;
top: 0;
z-index: 0;
}
.thumbnails-active .compsoul-gallery-content {
bottom: 120px;
}
.thumbnails-inactive .compsoul-gallery-content {
bottom: 0;
}
.compsoul-gallery-content .compsoul-gallery-item {
height: 80vh;
height: calc(100vh - 172px);
left: 50%;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
user-select: none;
visibility: hidden;
width: 80vw;
width: calc(100vw - 204px);
will-change: auto;
z-index: 0;
}
.compsoul-gallery-item.compsoul-active, .compsoul-gallery-item.compsoul-prev, .compsoul-gallery-item.compsoul-next {
opacity: 1;
transform: translate(-150vw, -50%);
transition: opacity 0.3s ease-out, transform 0.3s ease-out;
visibility: visible;
will-change: opacity, transform;
z-index: 1;
}
.compsoul-gallery-item.compsoul-fade {
opacity: 0;
transition: opacity 0.2s ease-out;
visibility: visible;
will-change: opacity;
}
.compsoul-direction-prev .compsoul-gallery-item.compsoul-prev,
.compsoul-direction-next .compsoul-gallery-item.compsoul-next {
transition: unset;
will-change: auto;
}
.compsoul-resize .compsoul-gallery-item.compsoul-prev {
animation: compsoul-resize-prev 0.1s linear forwards;
}
@keyframes compsoul-resize-prev {
from {
transform: translate(-150vw, -50%);
}
to {
transform: translate(-150vw, -50%);
}
}
.compsoul-resize .compsoul-gallery-item.compsoul-next {
animation: compsoul-resize-next 0.1s linear forwards;
}
@keyframes compsoul-resize-next {
from {
transform: translate(50vw, -50%);
}
to {
transform: translate(50vw, -50%);
}
}
.compsoul-gallery-item.compsoul-next {
transform: translate(50vw, -50%);
}
.compsoul-gallery-item.compsoul-active {
transform: translate(-50%, -50%);
}
.compsoul-disorderly .compsoul-gallery-item,
.compsoul-disorderly .compsoul-gallery-item.compsoul-prev,
.compsoul-disorderly .compsoul-gallery-item.compsoul-next {
opacity: 0;
transition: unset;
visibility: hidden;
will-change: auto;
z-index: 2;
}
.compsoul-disorderly .compsoul-gallery-item.compsoul-past {
animation: disorderly-past 0.2s linear;
will-change: opacity, transform, visibility;
z-index: 3;
}
@keyframes disorderly-past {
0% {
opacity: 1;
transform: translate(-50%, -50%);
visibility: visible;
}
99% {
opacity: 0;
transform: translate(-50%, -50%);
visibility: visible;
}
100% {
opacity: 0;
transform: translate(-50%, -50%);
visibility: hidden;
}
}
.compsoul-disorderly .compsoul-gallery-item.compsoul-active {
animation: disorderly-active 0.2s linear;
opacity: 1;
visibility: visible;
will-change: opacity, transform, visibility;
z-index: 4;
}
@keyframes disorderly-active {
0% {
opacity: 0;
transform: translate(-50%, -50%);
visibility: hidden;
}
1% {
opacity: 0;
transform: translate(-50%, -50%);
visibility: visible;
}
100% {
opacity: 1;
transform: translate(-50%, -50%);
visibility: visible;
}
}
.compsoul-gallery-item .compsoul-gallery-image {
display: inline-block;
left: 50%;
opacity: 0.001;
overflow: hidden;
position: relative;
top: 50%;
transform: translate(-50%, -50%);
transform-origin: top left;
will-change: auto;
width: auto;
z-index: 1;
}
.compsoul-gallery-item.compsoul-active .compsoul-gallery-image {
transition: opacity 0.2s 0.2s linear, transform 0.2s linear;
will-change: opacity;
}
.compsoul-gallery-item .compsoul-gallery-image:before {
bottom: 0;
content: "";
left: 0;
position: absolute;
right: 0;
top: 0;
}
.thumbnails-show .compsoul-gallery-image {
transform: scale(0.8) translate(-50%, -50%);
}
.thumbnails-show .compsoul-gallery-item.compsoul-active .compsoul-gallery-image {
will-change: transform;
}
.compsoul-gallery-item.compsoul-loaded .compsoul-gallery-image {
opacity: 1;
}
.compsoul-gallery-item .compsoul-gallery-image img {
display: block;
max-height: 80vh;
max-height: calc(100vh - 172px);
max-width: 80vw;
max-width: calc(100vw - 204px);
}
.compsoul-gallery-item .compsoul-gallery-comment {
background: rgba(0, 0, 0, 0.6);
bottom: 0;
color: #f2f2f2;
font-family: Calibri, Candara, Segoe, Segoe UI, Optima, Arial, sans-serif;
font-size: 2em;
left: 0;
padding: 2em;
position: absolute;
right: 0;
transform: translate(0, 100%);
transition: transform 0.2s 0.4s linear;
z-index: 1;
}
.compsoul-disorderly .compsoul-gallery-item .compsoul-gallery-comment {
transform: translate(0, 0);
transition: unset;
}
.compsoul-gallery-item.compsoul-active.compsoul-loaded .compsoul-gallery-comment {
transform: translate(0, 0);
}
.compsoul-gallery-item .compsoul-gallery-comment.compsoul-inactive {
display: none;
}
.compsoul-loader {
left: 50%;
opacity: 0;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
z-index: 0;
}
.compsoul-loader:before, .compsoul-loader:after {
animation: compsoul-loading 1s linear infinite;
animation-play-state: paused;
border: 0.5em solid #f2f2f2;
border-radius: 100%;
content: "";
display: block;
filter: blur(1px);
height: 8em;
left: 50%;
opacity: 0;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
width: 8em;
}
.compsoul-gallery-item.compsoul-active .compsoul-loader,
.compsoul-gallery-item.compsoul-prev .compsoul-loader,
.compsoul-gallery-item.compsoul-next .compsoul-loader {
transition: opacity 0.2s linear;
}
.compsoul-gallery-item.compsoul-active .compsoul-loader {
opacity: 1;
}
.compsoul-gallery-item.compsoul-loaded .compsoul-loader {
opacity: 0;
}
.compsoul-gallery-item.compsoul-active.compsoul-loading .compsoul-loader:before,
.compsoul-gallery-item.compsoul-active.compsoul-loading .compsoul-loader:after {
animation-play-state: running;
}
.compsoul-loader:after {
animation-delay: 0.5s;
}
@keyframes compsoul-loading {
0% {
opacity: 0;
transform: translate(-50%, -50%) scale(0);
}
50% {
opacity: 1;
transform: translate(-50%, -50%) scale(0.5);
}
100% {
opacity: 0;
transform: translate(-50%, -50%) scale(1);
}
}
.compsoul-gallery-full-screen {
background: #000;
bottom: 0;
font-size: 0;
position: absolute;
left: 0;
opacity: 0;
overflow: auto;
right: 0;
top: 0;
transition: opacity 0.2s linear;
z-index: -1;
}
.compsoul-gallery-full-screen.compsoul-active {
z-index: 1;
}
.compsoul-zoom .compsoul-gallery-full-screen {
opacity: 1;
}
.compsoul-zoom-out .compsoul-gallery-full-screen {
opacity: 0;
transition-delay: 0.2s;
}
.compsoul-gallery-full-screen img {
display: block;
margin: 0 auto;
opacity: 0;
transition: opacity 0.2s 0.2s linear;
}
.compsoul-zoom .compsoul-gallery-full-screen img {
opacity: 1;
}
.compsoul-zoom-out .compsoul-gallery-full-screen img {
opacity: 0;
transition-delay: unset;
}
.compsoul-logo, .compsoul-gallery-close, .compsoul-gallery-next, .compsoul-gallery-prev, .thumbnails-toggle, .compsoul-gallery-progress, .compsoul-gallery-zoom {
cursor: pointer;
height: 7em;
outline: 1px solid rgba(242, 242, 242, 0);
overflow: hidden;
position: absolute;
right: 4em;
top: 2em;
transform: translate(0);
transition: outline 0.2s linear;
width: 7em;
}
.compsoul-logo {
box-sizing: border-box;
left: 4em;
right: auto;
transition: unset;
width: 8em;
}
.compsoul-logo svg {
fill: #f2f2f2;
top: 50%;
position: relative;
transform: translate(0, -50%);
transition: fill 0.2s linear;
}
.compsoul-logo:focus-within {
outline: none;
}
.compsoul-logo:hover svg, .compsoul-logo:focus-within svg {
fill: #e7a14f;
}
.compsoul-logo:focus-within, .compsoul-gallery-close:focus-within, .compsoul-gallery-next:focus-within, .compsoul-gallery-prev:focus-within, .thumbnails-toggle:focus-within, .compsoul-gallery-progress:focus-within, .compsoul-gallery-zoom:focus-within {
outline-color: rgba(242, 242, 242, 0.8);
}
.compsoul-gallery-close:before, .compsoul-gallery-next:before, .compsoul-gallery-prev:before, .thumbnails-toggle:before, .compsoul-gallery-progress:before, .compsoul-gallery-zoom:before, .compsoul-gallery-close:after, .compsoul-gallery-next:after, .compsoul-gallery-prev:after, .thumbnails-toggle:after, .compsoul-gallery-progress:after, .compsoul-gallery-zoom:after {
background: #111;
bottom: 0;
content: "";
position: absolute;
left: 0;
right: 0;
top: 0;
z-index: -2;
}
.compsoul-gallery-close:after, .compsoul-gallery-next:after, .compsoul-gallery-prev:after, .thumbnails-toggle:after, .compsoul-gallery-progress:after, .compsoul-gallery-zoom:after {
background: none;
z-index: 1;
}
.compsoul-gallery-close button, .compsoul-gallery-next button, .compsoul-gallery-prev button, .thumbnails-toggle button, .compsoul-gallery-progress button, .compsoul-gallery-zoom button {
outline: 0;
position: relative;
z-index: -1;
}
.compsoul-gallery-close button:before, .compsoul-gallery-close button:after, .compsoul-gallery-next button:before, .compsoul-gallery-prev button:before {
border-top: 0.25em solid #f2f2f2;
border-right: 0.25em solid #f2f2f2;
box-sizing: content-box;
content: "";
cursor: pointer;
display: inline-block;
height: 1em;
padding: 0 0 0.25em 0.25em;
width: 1em;
}
.compsoul-gallery-close {
z-index: 2;
}
.compsoul-gallery-close button {
cursor: pointer;
height: 6em;
left: 50%;
position: absolute;
top: 50%;
transform: translate(-50%, -50%) rotate(45deg);
width: 6em;
}
.compsoul-gallery-close button:before, .compsoul-gallery-close button:after {
bottom: 1.625em;
left: 1.625em;
position: absolute;
transform: rotate(0deg);
}
.compsoul-gallery-close button:before {
border: none;
border-bottom: 0.25em solid #f2f2f2;
border-left: 0.25em solid #f2f2f2;
left: auto;
padding: 0.25em 0.25em 0 0;
right: 1.625em;
top: 1.625em;
}
.compsoul-gallery-close button:after {
border-top: 0.25em solid #f2f2f2;
border-right: 0.25em solid #f2f2f2;
padding: 0 0 0.25em 0.25em;
}
.compsoul-gallery-zoom {
right: 28em;
}
.compsoul-gallery-zoom button {
cursor: pointer;
height: 100%;
position: relative;
width: 100%;
}
.compsoul-gallery-zoom button:before {
border: 0.25em solid #f2f2f2;
border-radius: 100%;
content: "";
height: 1.25em;
left: 50%;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
width: 1.25em;
}
.compsoul-gallery-zoom button:after {
background: #f2f2f2;
border-radius: 0 0 0.25em 0.25em;
content: "";
height: 1em;
left: 50%;
margin: 1em 0 0 -1.5em;
position: absolute;
top: 50%;
transform: rotate(45deg) translate(-50%, -50%);
width: 0.25em;
}
.compsoul-gallery-progress {
right: 20em;
}
.compsoul-gallery-progress button {
cursor: pointer;
height: 100%;
position: relative;
width: 100%;
}
.compsoul-gallery-progress button:before {
border-bottom: 1em solid transparent;
border-left: 1.2em solid #f2f2f2;
border-top: 1em solid transparent;
border-radius: 0.2em;
content: "";
height: 0;
left: 50%;
opacity: 1;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
transition: opacity 0.2s 0.2s linear;
width: 0;
}
.compsoul-gallery-progress.compsoul-active button:before {
opacity: 0;
transition-delay: unset;
}
.compsoul-gallery-progress button:after {
animation: gallery-progress 6s linear forwards;
animation-play-state: paused;
color: #f2f2f2;
content: "10";
font-size: 1.6em;
left: 50%;
opacity: 0;
position: absolute;
top: 50%;
transition: opacity 0.2s linear;
transform: translate(-50%, -50%);
}
.compsoul-gallery-progress.compsoul-active button:after {
opacity: 1;
transition-delay: 0.2s;
}
.compsoul-gallery-progress.compsoul-play button:after {
animation-delay: 0.4s;
animation-play-state: running;
}
.compsoul-gallery-progress.compsoul-unset button:after {
animation: unset;
}
@keyframes gallery-progress {
0% {
content: "10";
}
9% {
content: "9";
}
18% {
content: "8";
}
27% {
content: "7";
}
36% {
content: "6";
}
45% {
content: "5";
}
54% {
content: "4";
}
63% {
content: "3";
}
72% {
content: "2";
}
81% {
content: "1";
}
90% {
content: "0";
}
100% {
content: "0";
}
}
.compsoul-gallery-next, .compsoul-gallery-prev {
opacity: 0;
right: 4em;
top: 50%;
transform: translate(0, -50%);
transition: opacity 0.2s linear, outline 0.2s linear;
}
.compsoul-gallery-next.compsoul-active, .compsoul-gallery-prev.compsoul-active {
opacity: 1;
}
.compsoul-gallery-prev {
left: 4em;
}
.compsoul-gallery-next button, .compsoul-gallery-prev button {
left: 50%;
position: absolute;
top: 50%;
transform: translate(-1em, -50%);
}
.compsoul-gallery-prev button {
transform: translate(-0.5em, -50%);
}
.compsoul-gallery-next button:before, .compsoul-gallery-prev button:before {
transform: rotate(-135deg);
}
.compsoul-gallery-next button:before {
transform: rotate(45deg);
}
.thumbnails-toggle {
right: 12em;
}
.thumbnails-toggle button {
cursor: pointer;
height: 100%;
position: relative;
width: 100%;
}
.thumbnails-toggle button:before {
background-color: transparent;
background-image: linear-gradient(90deg, #f2f2f2 0.5em, transparent 0.25em),
linear-gradient(90deg, #f2f2f2 0.5em, transparent 0.25em),
linear-gradient(90deg, #f2f2f2 0.5em, transparent 0.25em);
background-position: 0 0, 0 0.75em, 0 1.5em;
background-repeat: repeat-x;
background-size: 0.75em 0.5em, 0.75em 0.5em, 0.75em 0.5em;
content: "";
cursor: pointer;
height: 2em;
left: 50%;
opacity: 0.6;
position: absolute;
top: 50%;
transition: opacity 0.4s linear;
transform: translate(-50%, -50%);
width: 2em;
}
.thumbnails-toggle:active button:before, .thumbnails-toggle button:active:before {
background-image: linear-gradient(90deg, #f2f2f2 0.5em, transparent 0.125em),
linear-gradient(90deg, #f2f2f2 0.5em, transparent 0.125em),
linear-gradient(90deg, #f2f2f2 0.5em, transparent 0.125em);
background-position: 0 0, 0 0.625em, 0 1.25em;
background-size: 0.625em 0.5em, 0.625em 0.5em, 0.625em 0.5em;
height: 1.75em;
width: 1.75em;
}
.thumbnails-show .thumbnails-toggle button:before {
opacity: 1;
}
.thumbnails-container {
background: #111;
bottom: 0;
font-size: 0;
height: 72px;
left: 0;
letter-spacing: 0;
position: fixed;
right: 0;
transition: transform 0.2s linear;
transform: translateY(100%);
}
.thumbnails-show .thumbnails-container {
transform: translateY(0);
}
.thumbnails-content {
bottom: 0;
left: 0;
position: absolute;
top: 0;
white-space: nowrap;
}
.thumbnails-show .thumbnails-content {
transition: transform 0.2s linear;
}
.thumbnails-content.compsoul-drag {
transition: unset;
}
.thumbnails-content.compsoul-drag:before {
bottom: 0;
content: "";
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: 2;
}
.thumbnails-content .thumbnails-image {
background: none;
border: none;
cursor: pointer;
display: inline-block;
font-size: 0;
height: 100%;
position: relative;
user-select: none;
}
.thumbnails-content .thumbnails-image:before, .thumbnails-content .thumbnails-image:after {
bottom: 0;
content: "";
left: 0;
opacity: 0;
outline: 1px solid #f2f2f2;
outline-offset: -1px;
position: absolute;
right: 0;
top: 0;
transition: opacity 0.2s linear;
z-index: 1;
}
.thumbnails-content .thumbnails-image:after {
outline-color: #e7a14f;
}
.thumbnails-content .thumbnails-image button:focus {
outline: none;
}
.thumbnails-content .thumbnails-image:focus-within:before {
opacity: 1;
}
.thumbnails-content .thumbnails-image.compsoul-active:after {
opacity: 1;
}
.thumbnails-content .thumbnails-image img {
display: block;
max-height: 72px;
}
.gallery {
display: flex;
flex-flow: row wrap;
gap: 10px;
}
.gallery-row {
display: flex;
flex: 1 100%;
flex-flow: row nowrap;
gap: 10px;
}
.gallery-thumbnail * {
pointer-events: none;
}
.gallery-thumbnail img {
height: 100%;
object-fit: cover;
width: 100%;
}
@media (max-width: 1000px) {
.compsoul-gallery-container {
font-size: 5.4px;
}
.compsoul-gallery-content .compsoul-gallery-item {
height: 100vh;
height: calc(100vh - 16px);
width: 100vw;
width: calc(100vw - 16px);
}
.thumbnails-show .compsoul-gallery-image {
transform: scale(0.68) translate(-50%, -50%);
}
.compsoul-gallery-item .compsoul-gallery-image img {
max-height: 100vh;
max-height: calc(100vh - 16px);
max-width: 100vw;
max-width: calc(100vw - 16px);
}
}
@media (max-width: 380px) {
.compsoul-gallery-content .compsoul-gallery-item {
height: 100vh;
width: 100vw;
}
.thumbnails-show .compsoul-gallery-image {
transform: scale(0.75) translate(-50%, -50%);
}
.compsoul-gallery-item .compsoul-gallery-image img {
max-height: 100vh;
max-width: 100vw;
}
}
<script src="https://compsoul.dev/uploads/js/compsoul.js"></script><script src="https://compsoul.dev/uploads/js/gallery.js"></script><script>
new Gallery(".gallery-album").options({
album: true
}).init();
</script>
Remember that for better optimization and smooth operation of the gallery, it is best to use thumbnails on the list of photos for each album.
Thank You for Reading
We hope you enjoyed this post! If you did, please consider following us on Facebook and leaving a like and a comment. If you have any questions or need assistance, feel free to use our contact form or email us at daniel@compsoul.dev. For urgent inquiries, you can reach us by phone at +48 732 846 416.