Shopify themes, liquid, logos, and UX
I am in the process of adding text to my collection pages within the Description area.
The text, however, is quite long - and as a user, it might be a bit annoying to read or scroll through this text if you just want to see the products.
Initially, I thought I'd move the Collection Banner area below the product grid, but this also moves the collection name below as well.
I hoped I could just add the title again, but I don't know how to do this with Shopify.
The next thing I thought was to add a read more/less link to the description so a user could decide to read it or not - so it wouldn't be a distraction either way.
I viewed several tutorials and posts on this topic; however, all of them only half-worked, so I don't want to leave either of these solutions in my store.
To see what I mean, you can view a page with a lengthy description here: https://veganjoyjar.com/collections/vegan-t-shirts.
If anyone has an effective way to handle this, I am all ears!
Thanks!
Solved! Go to the solution
This is an accepted solution.
If anyone stumbles across this post and wants to find the solution, here it is.
With great help from Terence, whose details are in his previous post, we managed to get this working exactly as I'd hoped.
Firstly, Terence added JavaScript code, which was not part of the original solution, into a file with the extension *.js. (make sure the .js filename and reference name in the below code match)
document.addEventListener("DOMContentLoaded", function() {
const description = document.querySelector('.collection-description');
const readMoreBtn = document.createElement('button');
readMoreBtn.textContent = 'Read more';
readMoreBtn.classList.add('read-more-btn');
description.appendChild(readMoreBtn);
const hideBtn = document.createElement('button');
hideBtn.textContent = 'Read less';
hideBtn.classList.add('hide-btn');
description.appendChild(hideBtn);
readMoreBtn.addEventListener('click', function() {
description.style.maxHeight = 'none';
readMoreBtn.style.display = 'none';
hideBtn.style.display = 'inline-block';
});
hideBtn.addEventListener('click', function() {
description.style.maxHeight = '4.5em';
readMoreBtn.style.display = 'inline-block';
hideBtn.style.display = 'none';
});
});
The theme.liquid also needed the update for the js file:
{{ 'novajet-js.js' | asset_url | script_tag }}
<style>
body:has(.product) {
max-width: unset;
}
.page-width:has(.product) {
max-width: 100%;
}
</style>
</head>
<body class="gradient{% if settings.animations_hover_elements != 'none' %} animate--hover-{{ settings.animations_hover_elements }}{% endif %}">
<a class="skip-to-content-link button visually-hidden" href="#MainContent">
{{ 'accessibility.skip_to_text' | t }}
</a>
{%- if settings.cart_type == 'drawer' -%}
{%- render 'cart-drawer' -%}
{%- endif -%}
{% sections 'header-group' %}
<main id="MainContent" class="content-for-layout focus-none" role="main" tabindex="-1">
{{ content_for_layout }}
</main>
{% sections 'footer-group' %}
<ul hidden>
<li id="a11y-refresh-page-message">{{ 'accessibility.refresh_page' | t }}</li>
<li id="a11y-new-window-message">{{ 'accessibility.link_messages.new_window' | t }}</li>
</ul>
Hi!
The most sensible approach seems to be toggling visibility. For this, we need to use both CSS and JavaScript.
Terence.
The following code will do what you want. You can change the values as you like. If you encounter any issues again, feel free to write, I'll help.
Navigate to the 'Edit Code' option in your theme settings, then search for “base.css” in the search bar and add below codes.
.collection-description p {
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 5;
}
1) Navigate to the 'Edit Code' option in your theme settings, then search for 'theme.liquid' in the search bar.
2) Paste the following code below the '<head>' tag. Please refer to the attached screenshot for guidance.
<style>
document.addEventListener("DOMContentLoaded", function() {
const description = document.querySelector('.collection-description');
const paragraph = description.querySelector('p');
const readMoreBtn = document.createElement('button');
readMoreBtn.textContent = 'Read more';
readMoreBtn.classList.add('read-more-btn');
description.appendChild(readMoreBtn);
const hideBtn = document.createElement('button');
hideBtn.textContent = 'Hide';
hideBtn.classList.add('hide-btn');
description.appendChild(hideBtn);
paragraph.style.webkitLineClamp = '2';
hideBtn.style.display = 'none';
readMoreBtn.addEventListener('click', function() {
paragraph.style.webkitLineClamp = 'unset';
readMoreBtn.style.display = 'none';
hideBtn.style.display = 'inline-block';
});
hideBtn.addEventListener('click', function() {
paragraph.style.webkitLineClamp = '2';
readMoreBtn.style.display = 'inline-block';
hideBtn.style.display = 'none';
});
});
</style>
Thanks for the suggestion - your example is just what I was looking for.
However, when implementing your code, I am left with paragraphs truncated with the '...' as per the attached.
I've subsequently changed the paragraph to a smaller version.
Can you ascertain if I have done something wrong or if there is something else affecting this that I am unaware of?
Thanks again!
Just as an FYI, I have removed all the code so the text does not truncate.
Since there was only one 'p' tag in the relevant place, it was working without issues. However, the software you're using adds a new tag for each new paragraph, so this method won't work. Instead, you can use the method below. I'm not having any issues right now. Also, you need to put the code exactly where I specified.
If you still encounter problems, let me know!
base.css
.collection-description {
max-height: 4.5em;
overflow: hidden;
transition: max-height 0.3s ease;
}
.read-more-btn,
.hide-btn {
display: inline-block;
margin-top: 10px;
cursor: pointer;
background-color: #007bff;
color: white;
border: none;
padding: 5px 10px;
border-radius: 5px;
font-size: 14px;
}
.read-more-btn
{
position: absolute;
bottom: -10px;
}
.hide-btn {
display: none;
}
.collection-hero__text-wrapper {
position: relative;
}
theme.liquid <head>
<script>
document.addEventListener("DOMContentLoaded", function() {
const description = document.querySelector('.collection-description');
const paragraph = description.querySelector('p');
const readMoreBtn = document.createElement('button');
readMoreBtn.textContent = 'Read more';
readMoreBtn.classList.add('read-more-btn');
description.appendChild(readMoreBtn);
const hideBtn = document.createElement('button');
hideBtn.textContent = 'Hide';
hideBtn.classList.add('hide-btn');
description.appendChild(hideBtn);
paragraph.style.webkitLineClamp = '2';
hideBtn.style.display = 'none';
readMoreBtn.addEventListener('click', function() {
paragraph.style.webkitLineClamp = 'unset';
readMoreBtn.style.display = 'none';
hideBtn.style.display = 'inline-block';
});
hideBtn.addEventListener('click', function() {
paragraph.style.webkitLineClamp = '2';
readMoreBtn.style.display = 'inline-block';
hideBtn.style.display = 'none';
});
});
</script>
Thank you for the update, but this doesn't appear to work either.
I've attached what happens at my end and the code blocks I've added to ensure they are correct.
Can I fix an issue at my end to get this working?
Thanks again for all the help.
I think there might be a cache issue or some other problem with your software. I also can't see the CSS code you uploaded in the 'base.css' section.
Additionally, I made a small mistake. Could you replace the code I sent with the one below, except for the CSS? You need to paste the code right above the </head> tag. If it still doesn't work, I can do it for you if you give me permission.
<script>
document.addEventListener("DOMContentLoaded", function() {
const description = document.querySelector('.collection-description');
const paragraph = description.querySelector('p');
const readMoreBtn = document.createElement('button');
readMoreBtn.textContent = 'Read more';
readMoreBtn.classList.add('read-more-btn');
description.appendChild(readMoreBtn);
const hideBtn = document.createElement('button');
hideBtn.textContent = 'Hide';
hideBtn.classList.add('hide-btn');
description.appendChild(hideBtn);
paragraph.style.webkitLineClamp = '2';
hideBtn.style.display = 'none';
readMoreBtn.addEventListener('click', function() {
paragraph.style.webkitLineClamp = 'unset';
readMoreBtn.style.display = 'none';
hideBtn.style.display = 'inline-block';
});
hideBtn.addEventListener('click', function() {
paragraph.style.webkitLineClamp = '2';
readMoreBtn.style.display = 'inline-block';
hideBtn.style.display = 'none';
});
});
</script>
Thanks again. I get the 'read more' button, but it doesn't appear to do anything.
Sure, I can give you access to have a look if you like. I wonder if it's also possible to have the text the same width as the products listed? That would also make it a lot better.
How do I give you access?
I think there's a minor issue with the system. It's best if you grant me access with Collaborator permissions. You can send me the code via private message. We can also make the text full width.
https://help.shopify.com/en/manual/your-account/staff-accounts/collaborator-accounts
This is an accepted solution.
If anyone stumbles across this post and wants to find the solution, here it is.
With great help from Terence, whose details are in his previous post, we managed to get this working exactly as I'd hoped.
Firstly, Terence added JavaScript code, which was not part of the original solution, into a file with the extension *.js. (make sure the .js filename and reference name in the below code match)
document.addEventListener("DOMContentLoaded", function() {
const description = document.querySelector('.collection-description');
const readMoreBtn = document.createElement('button');
readMoreBtn.textContent = 'Read more';
readMoreBtn.classList.add('read-more-btn');
description.appendChild(readMoreBtn);
const hideBtn = document.createElement('button');
hideBtn.textContent = 'Read less';
hideBtn.classList.add('hide-btn');
description.appendChild(hideBtn);
readMoreBtn.addEventListener('click', function() {
description.style.maxHeight = 'none';
readMoreBtn.style.display = 'none';
hideBtn.style.display = 'inline-block';
});
hideBtn.addEventListener('click', function() {
description.style.maxHeight = '4.5em';
readMoreBtn.style.display = 'inline-block';
hideBtn.style.display = 'none';
});
});
The theme.liquid also needed the update for the js file:
{{ 'novajet-js.js' | asset_url | script_tag }}
<style>
body:has(.product) {
max-width: unset;
}
.page-width:has(.product) {
max-width: 100%;
}
</style>
</head>
<body class="gradient{% if settings.animations_hover_elements != 'none' %} animate--hover-{{ settings.animations_hover_elements }}{% endif %}">
<a class="skip-to-content-link button visually-hidden" href="#MainContent">
{{ 'accessibility.skip_to_text' | t }}
</a>
{%- if settings.cart_type == 'drawer' -%}
{%- render 'cart-drawer' -%}
{%- endif -%}
{% sections 'header-group' %}
<main id="MainContent" class="content-for-layout focus-none" role="main" tabindex="-1">
{{ content_for_layout }}
</main>
{% sections 'footer-group' %}
<ul hidden>
<li id="a11y-refresh-page-message">{{ 'accessibility.refresh_page' | t }}</li>
<li id="a11y-new-window-message">{{ 'accessibility.link_messages.new_window' | t }}</li>
</ul>
HI All,
Would these pieces of code work on the Refresh Theme and is so, where exactly in base.css and theme.liquid do i past them.
Sorry, i am a nubie.
Gavin
By investing 30 minutes of your time, you can unlock the potential for increased sales,...
By Jacqui Sep 11, 2024We appreciate the diverse ways you participate in and engage with the Shopify Communi...
By JasonH Sep 9, 2024Thanks to everyone who participated in our AMA with 2H Media: Marketing Your Shopify St...
By Jacqui Sep 6, 2024