<andres-carmona />

TIL #9: ownerDocument.defaultView
First published on
on html, javascript, typescript

Despite considering my self a seasoned programmer and being developing for over 15 years, I’m surprised I didn’t know about the ownerDocument.defaultView property.

I basically returns the window object (or null) associated with a specific DOM node. It could be used to safely attach an event listener to a window object from a component that is rendered outside the main window where the application was initially rendered (think portals).

function ThemeProvider({ children }) {
  const [theme, setTheme] = useState("light");
  const ref = useRef(null);

  useEffect(() => {
    const win = ref.current?.ownerDocument.defaultView || window;

    const toggle = (e) => {
      if (e.metaKey && e.key === "d") {
        e.preventDefault();
        setTheme((t) => (t === "dark" ? "light" : "dark"));
      }
    };

    win.addEventListener("keydown", toggle);

    return () => win.removeEventListener("keydown", toggle);
  }, []);

  return (
    <div ref={ref} className={theme}>
      {children}
    </div>
  );
}

From the same article, also learned about useId and cache 😛

Reference: https://shud.in/thoughts/build-bulletproof-react-components, great article btw! 💯


Blender shortcuts
First published on
on css, html

I was reviewing a page that I have in Notion about Three.js, with bookmarks, links to articles, utilities, tools, repositories, etc, and found a good one about Blender shortcuts, some of them I didn’t know about (I mean, I’m just getting started in Blender anyways) like the Snap shortcuts or the Clear transform, and I wanted to share it here:

http://hollisbrown.github.io/blendershortcuts

TIL #7: SVG Filters
First published on
on css, html, svg, effects, filters

SVG filters allow you to create complex visual effects directly within your SVG graphics using a variety of filter primitives. You can apply effects like blurring, color manipulation, and even custom distortions to your SVG elements.

SVG Filters

<p class="ripple-text">SVG Filters</p>

<svg style="position: absolute; width: 0px; height: 0px; pointer-events: none;">
  <filter id="water-ripple">
    <feTurbulence
      type="fractalNoise"
      baseFrequency="0.05"
      numOctaves="2"
      result="ripple"
    >
      <animate
        attributeName="baseFrequency"
        dur="10s"
        values="0.02;0.05;0.02"
        repeatCount="indefinite"
      ></animate>
    </feTurbulence>
    <feDisplacementMap
      in="SourceGraphic"
      in2="ripple"
      scale="5"
    ></feDisplacementMap>
  </filter>
</svg>
.ripple-text {
  font-size: clamp(2rem, 4vw, 3rem);
  font-weight: bold;
  text-align: center;
  filter: url(#water-ripple);
}

Using 100vw is now scrollbar-aware (in Chrome 145+, under the right conditions)
First published on
on css, html

From Chrome 145 onwards, 100vw will automatically subtract the size of the (vertical) scrollbar from it if you have forced the html element to always show a vertical scrollbar (using overflow[-y]: scroll) or if you reserve space for it (using scrollbar-gutter: stable).

Via https://www.bram.us/2026/01/15/100vw-horizontal-overflow-no-more/


TIL #6: SVG Favicons
First published on
on css, html, svg, icons
<svg xmlns="http://w3.org/2000/svg" viewBox="0 0 100 100">
  <text y=".9em" font-size="90">👾</text>
</svg>

Reference:

More description SVG favicons and favicons maintain general:


TIL #4: CSS content-visibility to improve performance
First published on
on css, html, performance

content-visiblity Without Jittery Scrollbars

/* Defer rendering for the 2nd+ article */
body > main > *+* {
  content-visibility: auto;
}
<script type="module">
  let observer = new IntersectionObserver(
    (entries, o) => {
      entries.forEach((entry) => {
        let el = entry.target;
        // Not currently in intersection area.
        if (entry.intersectionRatio == 0) {
          return;
        }
        // Trigger rendering for elements within
        // scroll area that haven't already been
        // marked.
        if (!el.markedVisible) {
          el.attributeStyleMap.set(
            "content-visibility",
            "visible"
          );
          el.markedVisible = true;
        }
      });
    },
    // Set a rendering "skirt" 50px above
    // and 100px below the main scroll area.
    { rootMargin: "50px 0px 100px 0px" }
  );

  let els =
    document.querySelectorAll("body > main > *+*");
  els.forEach((el) => { observer.observe(el); });
</script>

TIL #3: View transitions minimum setup
First published on
on html, css, view transitions

The bare minimum setup for enabling your site to use native view transitions in HTML and CSS:

<meta name="view-transition" content="same-origin" />
@view-transition {
  navigation: auto;
}

Ref URL: https://www.amitmerchant.com/bare-minimum-view-transitions/


TIL #2: Animate details element
First published on
on css, html, css-animations

https://developer.chrome.com/docs/css-ui/animate-to-height-auto#animate_the_details_element

@supports (interpolate-size: allow-keywords) {
    :root {
        interpolate-size: allow-keywords;
    }
    
    details {
        transition: height 0.5s ease;
        height: 2.5rem;
        
        &[open] {
            height: auto;
            overflow: clip; /* Clip off contents while animating */
        }
    }
}

TIL #1: valueAsNumber and valueAsDate on inputs
First published on
on html, inputs, forms

You can automatically transform input values to number and date with the valueAsNumber and valueAsDate function on inputs objects.

// This will always return NaN since valueAsNumber is not available on text inputs
<input type="text" onChange={e => console.log(e.target.valueAsNumber)} />

// Return the value as an integer or a float
// depending on the input's step attribute
<input type="number" onChange={e => console.log(e.target.valueAsNumber)} />

// Return the date as a UNIX timestamp, i.e. new Date().getTime()
<input type="date" onChange={e => console.log(e.target.valueAsNumber)} />

// Return the date as a JS Date object
<input type="date" onChange={e => console.log(e.target.valueAsDate)} />

Ref URL: https://devlog.willcodefor.beer/pages/use-valueasnumber-and-valueasdate-on-inputs/