nathancahill / split

Unopinionated utilities for resizeable split views
https://split.js.org/
MIT License
6.08k stars 451 forks source link

Support CSS media queries #545

Open learnwithsumit opened 3 years ago

learnwithsumit commented 3 years ago

It seems that, splitting not working in case of CSS media queries. Please check the below example:

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
.grid > div {
  border: 1px solid #f5f5f5;
  display: flex;
  align-items: center;
  justify-content: center;
}
.grid {
  height: 100vh;
  display: grid;
}

@media (min-width: 1024px) {
  .grid {
      grid-template-columns: 150px 1fr 5px 1fr;
      grid-template-rows: 32px 1fr;
  }
  .topbar {
      grid-column: 1/-1;
  }
  .column-gutter {
      cursor: col-resize;
      grid-column: 3;
  }
}
<div class="grid">
      <div class="topbar"></div>
      <div class="explorer"></div>
      <div class="editor"></div>
      <div class="column-gutter"></div>
      <div class="chapters"></div>
</div>
Split({
  minSize: 400,
  columnGutters: [
    {
      track: 2,
      element: document.querySelector(".column-gutter"),
    },
  ],
});

in this case, I am getting this error : split-grid.js:217 Uncaught Error: Unable to determine grid template tracks from styles

nathancahill commented 3 years ago

Thanks for the bug report. Meanwhile, you can supply the CSS value with the gridTemplateColumns option:

Split({
  gridTemplateColumns: "150px 1fr 5px 1fr",
  minSize: 400,
  columnGutters: [
    {
      track: 2,
      element: document.querySelector(".column-gutter"),
    },
  ],
});
learnwithsumit commented 3 years ago

Oh wow! I did't know that. May be I missed that in documentation. Thanks a ton @nathancahill

jeremylowery commented 1 year ago

So the issue here is that getMatchedCSSRules doesn't honor media queries. I asked ChatGPT to rewrite it to support media queries and it gave this:

  function getMatchedCSSRules(el) {
  const matchedRules = [];

  function getRulesFromStyleSheet(sheet) {
    try {
      const rules = sheet.cssRules || sheet.rules;

      // Iterate through each rule in the sheet
      for (let i = 0; i < rules.length; i++) {
        const rule = rules[i];
        if (rule.type === CSSRule.MEDIA_RULE) {
          // Recursively check media rules for matching rules
          getRulesFromStyleSheet(rule);
        } else if (rule.type === CSSRule.STYLE_RULE && el.matches(rule.selectorText)) {
          // Add matching style rule to matchedRules
          matchedRules.push(rule);
        }
      }
    } catch (e) {
      // Ignore results on security error
    }
  }

  // Iterate through each style sheet in the document
  Array.from(el.ownerDocument.styleSheets).forEach(getRulesFromStyleSheet);
  return matchedRules;
}

The last piece was to modify getRawTracks to return tracks[tracks.length - 1] instead of tracks[0] as in CSS AFAIK the last definition wins.

I'm not really setup for JS development, so I'm not able to offer a pull request but if you want to take these code snippets this might do the trick.

tonywok commented 4 months ago

Ran into a similar problem with container queries.

wykopx commented 2 months ago

@nathancahill Without media-queries support this split grid is practiacaly useless in 2024 with projects that handle responsive web design. Currently it's almost impossible to create grid-based SPA or PWA without media queries. This issue was reported 3 years ago. Can you tell us if there is any chance you will fix this or should we try to find some other JS library to handle draggable grid splitters?