Shopify themes, liquid, logos, and UX
Hey shopify designers I'm working with a client and they've asked me to do something that I think every web designer struggles with. Their ask is to make the collection sort by dropdown look uniform and on brand. The dropdown looks fine on windows but when looking at it on MacOS webkit takes over and the options look like default select options. I've of course tried "-webkit-appearance:none;" but unfortunately that means absolutely nothing when webkit has limited design capabilities of select elements to begin with.
Just when I thought to give up I found what looked like a solution: using div and span elements as well as some javascript. People have tried to do this already and I've successfully implemented it into my theme, but I've run into a problem. I have no idea how shopify changes urls with the default sort by so I'm struggling with making the dropdown actually functional. If anyone has any pointers on how to handle this please let me know.
For reference my 'collection-sorting.liquid' looks like this:
<style>
*,
*:after,
*:before {
box-sizing: border-box;
}
.container {
margin: 20px;
max-width: 300px;
}
.custom-select-wrapper {
position: relative;
user-select: none;
width: 100%;
}
.custom-select {
display: flex;
flex-direction: column;
border-width: 0 2px 0 2px;
border-style: solid;
border-color: #394a6d;
}
.custom-select__trigger {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 22px;
font-size: 20px;
font-weight: 300;
color: #3b3b3b;
height: 60px;
line-height: 60px;
background: #ffffff;
cursor: pointer;
border-width: 2px 0 2px 0;
border-style: solid;
border-color: #394a6d;
}
.custom-options {
position: absolute;
display: block;
top: 100%;
left: 0;
right: 0;
border: 2px solid #394a6d;
border-top: 0;
background: #fff;
transition: all 0.5s;
opacity: 0;
visibility: hidden;
pointer-events: none;
z-index: 2;
}
.custom-select.open .custom-options {
opacity: 1;
visibility: visible;
pointer-events: all;
}
.custom-option {
position: relative;
display: block;
padding: 0 22px 0 22px;
font-size: 22px;
font-weight: 300;
color: #3b3b3b;
line-height: 60px;
cursor: pointer;
transition: all 0.5s;
}
.custom-option:hover {
cursor: pointer;
background-color: #b2b2b2;
}
.custom-option.selected {
color: #ffffff;
background-color: #305c91;
}
.arrow {
position: relative;
height: 15px;
width: 15px;
}
.arrow::before,
.arrow::after {
content: "";
position: absolute;
bottom: 0px;
width: 0.15rem;
height: 100%;
transition: all 0.5s;
}
.arrow::before {
left: -5px;
transform: rotate(45deg);
background-color: #394a6d;
}
.arrow::after {
left: 5px;
transform: rotate(-45deg);
background-color: #394a6d;
}
.open .arrow::before {
left: -5px;
transform: rotate(-45deg);
}
.open .arrow::after {
left: 5px;
transform: rotate(45deg);
}
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block;
}
body {
line-height: 1;
}
ol,
ul {
list-style: none;
}
blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: "";
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
</style>
<div class="filter-dropdown__wrapper text-center collection-filters">
<div class="filter-dropdown" style="float:right;">
<label class="filter-dropdown__label" for="sortBy">
<span class="filter-dropdown__label--title" style="font-size: 1em; color:#999999;">Sort by</span>
<span class="filter-dropdown__label--active"></span>
</label>
{% assign sort_by = collection.sort_by | default: collection.default_sort_by %}
<div class="container">
<div class="custom-select-wrapper">
<div class="custom-select">
<div class="custom-select__trigger"><span>Featured</span>
<div class="arrow"></div>
</div>
<div class="custom-options">
<span class="custom-option selected" data-value="manual">Featured</span>
<span class="custom-option" data-value="created-ascending">Date, old to new</span>
<span class="custom-option" data-value="created-descending">Date, new to old</span>
<span class="custom-option" data-value="price-ascending">Price, low to high</span>
<span class="custom-option" data-value="price-descending">Price, high to low</span>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
// document.querySelector('.custom-select-wrapper').addEventListener('click', function () {
// this.querySelector('.custom-select').classList.toggle('open');
// })
for (const dropdown of document.querySelectorAll(".custom-select-wrapper")) {
dropdown.addEventListener('click', function () {
this.querySelector('.custom-select').classList.toggle('open');
})
}
for (const option of document.querySelectorAll(".custom-option")) {
option.addEventListener('click', function () {
if (!this.classList.contains('selected')) {
this.parentNode.querySelector('.custom-option.selected').classList.remove('selected');
this.classList.add('selected');
this.closest('.custom-select').querySelector('.custom-select__trigger span').textContent = this.textContent;
}
})
}
// window.addEventListener('click', function (e) {
// const select = document.querySelector('.custom-select')
// if (!select.contains(e.target)) {
// select.classList.remove('open');
// }
// });
window.addEventListener('click', function (e) {
for (const select of document.querySelectorAll('.custom-select')) {
if (!select.contains(e.target)) {
select.classList.remove('open');
}
}
});
</script>
Solved! Go to the solution
This is an accepted solution.
Hi mate! I had to do the same with a client recently and this post was great help! All of this because MAC OSX and webkit browsers like Chrome doesn't let you customize select - option tags. It was a hell, but this post saved my life, just a few more lines of javascript and its working perfectly.
To customize the dropdown select you have to create a custom div like you did, and then you can controll the variant selected with Javascript.
This is an accepted solution.
Hi mate! I had to do the same with a client recently and this post was great help! All of this because MAC OSX and webkit browsers like Chrome doesn't let you customize select - option tags. It was a hell, but this post saved my life, just a few more lines of javascript and its working perfectly.
To customize the dropdown select you have to create a custom div like you did, and then you can controll the variant selected with Javascript.
This is coming almost half a year late, but thank you! This is more or less what I ended up doing as well.
Are you ready to take your business to the next level? Look no further than the latest ...
By SarahF_Shopify Apr 15, 2024We’re keeping the ball rolling to make sure you’re always ahead of the game. So buckle ...
By JasonH Apr 8, 2024Portrait of Stephen positioned next to an image of planet Earth, with the Stephen's World ...
By JasonH Mar 18, 2024