Detecting Flex-Wrap Support in Browsers

What is a proper way to detect the support of css flex-box and flex-wrap?

how we can detect the support of css flex-box and flex-wrap by
JavaScript.

Create an element and check the style property. If it is supported, it will return nothing i.e. '' else it will return undefined.

For example, if you run the below snippet in Chrome you will get undefined for columns and '' for flex-wrap.

Snippet:

console.log('flex = ' + document.createElement("p").style.flex);console.log('columns = ' + document.createElement("p").style.columns);console.log('flex-wrap = ' + document.createElement("p").style.flexWrap);

@supports (-webkit-flex-wrap: wrap) doesn't return true when Safari does support it

Sorry to disappoint, but Safari does not presently support the CSS @supports rule. According to caniuse.com and MDN, it is only supported in Firefox 22+, Chrome 28+, and Opera 12.1+. You still have to use JavaScript-based feature detection for Internet Explorer and Safari.

Here is an example feature-detection script that adds a supports-webkit-flex-wrap to the root element in the DOM.

if ('webkitFlexWrap' in document.documentElement.style) {
document.documentElement.classList.add('supports-webkit-flex-wrap');
}

Then you can apply styles using that class name.

.supports-webkit-flex-wrap {
}

How to detect if CSS code is activated or not

As far as I remember css flex or order property is animatable, so you can trigger a class on an element with visibility hidden to turn on flex property. Then attach an eventListener for the transitionend event, and check if the property is from flex by checking event.propertyName, if this event is fired, it means it is supported. Here is a fiddle to illustrate, a class called active is turned on a div with #mock id and listened for transition:

https://jsfiddle.net/ibowankenobi/yLv39dsm/1/

document.getElementById("mock")
.addEventListener("transitionend",function(e){if(e.propertyName.match(/flex/gi)){alert("flex is supported")}});
setTimeout(function(){document.getElementById("mock").classList.add("active");},1000);

Apart from above, this question can help:

Detecting flex-wrap support in browsers

Also there seems to be an approach that seems to work:

https://gist.github.com/davidhund/b995353fdf9ce387b8a2

And of course, Modernizr probably has this already.

detecting flex wrap/content overflow in react

For anyone wondering I was able to isolate the code to be reused in any given container:


import useResizeObserver from '@react-hook/resize-observer'
//we need ResizerObserver
const useSize = (target) => {
const [size, setSize] = React.useState()

React.useLayoutEffect(() => {

setSize(target.current && target.current.getBoundingClientRect())
}, [target])

// Where the magic happens
useResizeObserver(target, (entry) => setSize((entry as any).contentRect))
return size
}
//this part goes in the component
//we need one ref to the container and some states to track the size of the individual items
const menuRef = React.useRef(null)
const menuRefSizes = useSize(menuRef)
const [navLinkIsHidden, setNavLinkIsHidden] = React.useState(false)
const [neededContainerWidth, setNeededContainerWidth] = React.useState(null)
const [navMenuIsHidden, setNavMenuIsHidden] = React.useState(false)
const [neededNavMenuContainerWidth, setNeededNavMenuContainerWidth] = React.useState(null)
React.useLayoutEffect(()=>{
CheckResponsive(
setNeededContainerWidth,setNavLinkIsHidden,neededContainerWidth, 'nav-links')
CheckResponsive(
setNeededNavMenuContainerWidth,setNavMenuIsHidden,neededNavMenuContainerWidth,'nav-menu-buttons')
return () => {
// no cleanup
};
}, [menuRefSizes])

//and the function we use applies to all items we are tracking.
//I am using direct dom references here, I am sure this can be simplified further but this is the more general I could done.

const CheckResponsive = (setContainer, setHide, neededContainerWidth, contId) => {
const navLinkNode = window.document.getElementById(contId)
const menuContainer = window.document.getElementById('menu')
const scrollWidth = navLinkNode ? navLinkNode.scrollWidth : 0
const offsetWidth = navLinkNode ? navLinkNode.offsetWidth : 0
const NavLinkIsOverflown = navLinkNode ? scrollWidth !== offsetWidth : false
const DoesNavLinkFitInContainer = menuContainer.scrollWidth >= neededContainerWidth
const navLinkWillBeHidden = NavLinkIsOverflown || !DoesNavLinkFitInContainer

navLinkWillBeHidden?setHide(true):setHide(false)
if (navLinkNode && navLinkWillBeHidden) {
setContainer(menuContainer.scrollWidth
+ window.document.getElementById(contId).scrollWidth
- window.document.getElementById(contId).offsetWidth)
}
return () => {
// no cleanup
};
}

the result is that all items that I am tracking wont be rendered when they overflow, when the container then have enough space again the items will be rendered.



Related Topics



Leave a reply



Submit