I’m a bit shocked to find out that Webflow’s Conditional Visibility feature actually only hides content. It doesn’t remove it. Is there a reason why they decided to still load all the hidden content?
I’m using this feature to show three very different layouts of a page depending on the content and this means the page ends up loading all three of them, but hides two.
This is also really bad in terms of accessibility. Screen readers will still ‘see’ the hidden content. The least Webflow could do is set tags appropriately for screen readers so that they ignore content that’s hidden.
Webflow renders the content statically to the hosting platform. A reason WF sites are so fast. So no dynamic code runs on the hosting platform to render pages real-time like you would have via a server-side language like PHP. So the only way you can have conditionals right now is to load it all and hide it via CSS. Loading lots of content using conditionals also loads the page with all that extra content and media (if present) which is bad for page performance.
I have used Ajax to control the loading of content on pages (from other pages or collection items), driven by custom code to work around it. If real dynamic content is a requirement I use other CMS platforms or reactive code like Vue instead.
You could use custom code to address the needs of screen readers as a workaround. Good luck with your project.
Webflow should make conditional visibility remove the item from the DOM. That’s the expected behavior for all users, including those using assistive technology. Webflow doesn’t even place aria-hidden: true; around the content to notify these technologies to ignore the content. display: none !important; is not the right thing to do under any circumstances, let alone when accessibility suffers.
I understand that this is something that the user can add via custom code, however, this should not be an option given to the Webflow user. The web is accessible by default and Webflow should follow that standard.
I’d love to see conditional visibility remove the item from the DOM completely. This would definitely make Webflow the perfect platform to build websites on.
@DylanIslington - Webflow renders the code on the page. If it is hidden by using conditional visibility it’s still loaded by the browser. Using custom code to remove the element(s) would not change the fact that the browser loaded the content already.
Because we cant have individual collection pages linked to a individual cms item, for example a unique product page for each brand of product.
Ive had to build everything on one page, hiding and showing with conditional visibility, but now my page is bloated as hell, slow, and I just learned its because conditional visibility only hides in theory and is still loaded. Wow.
You could potentially use a library like HTMX or JavaScript to pull content in from related items on some trigger. I have built SPA functionality this way.
Could you let me know briefly if something like this would actually work?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dynamic Element Visibility</title>
</head>
<body>
<!-- Your HTML content -->
<div class="product">
<!-- Product elements -->
<h2 class="product-title brand1">Product Title (Brand1)</h2>
<p class="product-description brand1">Description of product for Brand1</p>
<h2 class="product-title Brand2">Product Title (Brand2)</h2>
<p class="product-description brand2">Description of product for Brand2</p>
</div>
<!-- Your other HTML content -->
<script>
// Function to hide products based on brand
function hideProducts(brand) {
// Hide elements for other brands
document.querySelectorAll('.product-title:not(.' + brand + ')').forEach(function(el) {
el.style.display = 'none';
});
document.querySelectorAll('.product-description:not(.' + brand + ')').forEach(function(el) {
el.style.display = 'none';
});
}
// Retrieve the brand from the CMS or wherever it's stored
// For example, you might get it from a URL parameter or a cookie
const currentBrand = "brand1"; // You need to replace this with the actual brand value
// Call the function with the current brand to hide other products
hideProducts(currentBrand);
</script>
</body>
</html>
Another option here is a reverse proxy. I regularly remove conditionally-hidden content for performance, content security, a11y. It has a unique class so it’s easy to identify.
Hey Memetican, thanks for this advice! I have no idea what a reverse proxy is, but im always looking to learn. Im watching a Finsweet video now that I found on them to see how I could use this in my case.
Just out of curiosity, with reverse proxies, would this simply allow me to hide show an element depending upon a specific collection item being viewed, or would this also allow me to have multiple collection pages for each collection item?
Just for some context, I have one products collection, with a single reference inside of “brand”, but I need different collection pages based upon the brand of product being viewed. For now, I have all the product pages being built on one page, and as mentioned above hiding and showing using conditional visibility, with the permater of “brand” = “brand1” ect.
Would reverse proxy allow me to show a completely different page when a collection item with say “brand1” has been clicked, or would it allow me to only have the one collection page, but completely hide the elements that are not needed, so that the page speed is much better?
hi @DylanIslington another approach can be done with documentFragment in very simple explanation this element works like temporary Array you make request based on condition and push data to this element rest is removed from DOM.
Hey Stan, thanks a bunch, just so I understand, is it as simple as this, naming the relevant divs that I want to hide and show. Then placing the following or similar code into my webflow site, with the relevant div names within the code as well of course:
<!-- HTML Structure -->
<div class="brand-elements-container"></div>
<!-- JavaScript Code -->
<script>
// Create a DocumentFragment
var fragment = document.createDocumentFragment();
// Function to create and append elements based on brand
function appendElementsByBrand(brandName) {
// Create elements based on brand
var elementToShow = document.createElement('div');
elementToShow.textContent = 'Elements for ' + brandName;
// Append elements to the fragment
fragment.appendChild(elementToShow);
}
// Example: Iterate through collection items
var collectionItems = [
{ name: 'Item 1', brand: 'Brand A' },
{ name: 'Item 2', brand: 'Brand B' },
// Add more items as needed
];
collectionItems.forEach(function(item) {
// Check brand and append elements accordingly
if (item.brand === 'Brand A') {
appendElementsByBrand('Brand A');
} else if (item.brand === 'Brand B') {
appendElementsByBrand('Brand B');
}
// Add more conditions for other brands
});
// Insert the fragment into the document
document.querySelector('.brand-elements-container').appendChild(fragment);
</script>
Or would I have to have anything hosted outside of webflow?
hi @DylanIslington I have used this approach in few projects several ways but I can now find only one but it is I think some way close what you are after.
here is request.
there is a one collection called “artists”. Create dynamically alphabet and to each letter add artist whose name start with letter from alphabet.
Means I had to select Artis based on condition and add these into fragment that as added to DOM behind letter.
This was request from client but she never come back so here is this RO - example to see how documentFragment works.
Thanks a lot for this Stan! the live example really helps me as I dont know how to code, but can scrape by with editing :D so seeing it implemented really helps me visually, allowing me to see how I would use it in my own project.
I will go through it tonight and see how I get on!
hi @DylanIslington I have now checked code and this example actually doesn’t use fragment. I will paste code with figment later but I thing I have posted here on forum already.
here we go:
const frag = document.createDocumentFragment();
const list = document.querySelector(".w-dyn-items").firstChild.innerText;
let cards = Array.from(document.querySelectorAll(".cus-card__w"));
const filterBtns = Array.from(document.querySelectorAll(".btn-filter"));
filterBtns.forEach((btn) => {
btn.addEventListener("click", (evt) => {
//convert all values to lowercase to prevent errors
const filterText = evt.target.innerText.toLowerCase();
// FILTER
const filteredList = cards.filter((item) => {
// display all CMS items
if (filterText === "all") {
item.setAttribute("data-visible", true);
item.style.display = "block";
return item;
}
// if text of btn match data attribute display matched CMS Items
if (item.dataset.category === filterText) {
item.setAttribute("data-visible", true);
item.style.display = "block";
return item;
} else {
// else hide NOT mathsed items
item.setAttribute("data-visible", false);
item.style.display = "none";
}
});
// add filtered items to fragment
for (let item of filteredList) {
frag.appendChild(item);
}
// replace list
list.appendChild(frag);
removeElementsByClass("w-dyn-item");
});
});
function removeElementsByClass(className) {
var elements = document.getElementsByClassName(className);
while (elements.length > 0) {
elements[0].parentNode.removeChild(elements[0]);
}
}
Thats great stan thanks a bunch for sending this. One question, does this fragment hide/show only work for text elements, or would it work for a for example radio button with an image inside?
Like I have mentioned the documentFragment is like an “Array” so you can push anything (appending child) to it based on your condition rest is removed.
Where you can read more what it is and how it can be used but I believe there are videos on YT about this.
A reverse proxy is a server that sits between your visitors and your Webflow hosted site, so it can modify the requests and responses any way you like.
It most definitely requires coding skill however.
I’ve built Sygnal’s Hyperflow framework primarily on Cloudflare, and we use it for exactly these types of builds…
modify pages to add or remove elements, before they’re delivered to the viewer. Performance benefits. content security, dynamic content…
create new pages dynamically
merge pages
split pages
build pages live from 3rd party sources like google docs
You’d have some learning to do but you’d be able to delivery complex pages very efficiently. Client side JS will be fairly limited there.
@memetican Thats awesome that you built sygnals hyeperflow framework.
Yep so far I have opened a cloudflare account to host there, and now im about to get into the weeds using the finsweet tutorials, once I have everything in place I can always ask chatgpt for some help if I get stuck.
It will probably take me a while to get my head around it! but it will be really useful with building larger projects in the future.
For now i’m just going to try hide and show the elements without diving into creating pages dynamically or merge/split, Ill update here if I manage to do it :D I have high hopes.
Thanks again for mentioning this, very handy, I thought I had no options and was just doomed.
Im actually building a product customiser using a form, I need around 6 individual customisers for different products as different brands all have different options, with around 50 radios with images per customiser.
So you can imagine how bad the page load speed is getting bogged down. Even the webflow builder is like ground hog.