CSS and JavaScript Integration


CSS and JavaScript Integration Interview with follow-up questions

1. Can you explain how JavaScript can be used to manipulate CSS styles?

JavaScript manipulates CSS styles through several mechanisms, each with different appropriate use cases.

1. Inline styles via element.style

The style property exposes the element's inline style as a CSSStyleDeclaration object. Property names are camelCase equivalents of CSS property names:

const box = document.querySelector('.box');
box.style.backgroundColor = '#3b82f6';
box.style.transform = 'translateX(100px)';
box.style.setProperty('--custom-color', 'red'); // for custom properties

Inline styles have the highest specificity and override stylesheet rules. They are best for values computed at runtime (a drag position, a percentage from user input).

2. Toggling classes (preferred approach)

Define styles in CSS and use JavaScript to add, remove, or toggle class names. This keeps style logic in CSS where it belongs:

el.classList.add('is-active');
el.classList.toggle('is-open');
el.classList.replace('loading', 'loaded');

This approach is more maintainable, performs better (no inline specificity conflicts), and allows CSS transitions and animations to trigger naturally.

3. CSS custom properties

JavaScript can read and write CSS custom properties on any element, enabling dynamic theming without inline style specificity issues:

// Write
document.documentElement.style.setProperty('--theme-hue', '220');

// Read
getComputedStyle(document.documentElement).getPropertyValue('--theme-hue');

This is particularly powerful because the custom property change cascades through the entire component tree.

4. Reading computed styles

getComputedStyle(element) returns the final resolved values after all stylesheets and inheritance are applied — not just inline styles:

const styles = getComputedStyle(el);
styles.getPropertyValue('font-size'); // "16px"

5. CSSStyleSheet API (constructable stylesheets)

Modern JavaScript can create and adopt stylesheets programmatically, useful in Web Components:

const sheet = new CSSStyleSheet();
sheet.replaceSync('.widget { color: red; }');
document.adoptedStyleSheets = [sheet];

Best practice: use class toggling as the default pattern, reserve element.style for dynamic computed values, and use CSS custom properties for runtime theming.

↑ Back to top

Follow-up 1

Can you provide an example of this?

Sure! Here's an example of how JavaScript can be used to manipulate CSS styles:

// HTML
Click me

// JavaScript
var button = document.getElementById('myButton');
button.style.backgroundColor = 'blue';
button.style.color = 'white';
button.style.fontSize = '20px';

Follow-up 2

What are some use cases for dynamically changing CSS with JavaScript?

There are several use cases for dynamically changing CSS with JavaScript. Some common examples include:

  1. Creating interactive web pages: JavaScript can be used to change CSS styles based on user interactions, such as hovering over an element or clicking a button.

  2. Implementing themes: JavaScript can be used to switch between different CSS stylesheets or modify the styles of elements to create different themes for a website.

  3. Animations and transitions: JavaScript can be used to dynamically change CSS properties over time, allowing for the creation of animations and transitions on web pages.

  4. Responsive design: JavaScript can be used to modify CSS styles based on the screen size or device orientation, allowing for a more responsive and adaptive layout.

These are just a few examples, and the possibilities are endless when it comes to dynamically changing CSS styles with JavaScript.

Follow-up 3

What are the potential drawbacks of this approach?

While JavaScript can be a powerful tool for manipulating CSS styles, there are some potential drawbacks to consider:

  1. Performance impact: Frequent changes to CSS styles using JavaScript can impact the performance of a web page, especially on older devices or slower connections. It's important to optimize the code and minimize unnecessary style changes.

  2. Accessibility concerns: Dynamically changing CSS styles can sometimes affect the accessibility of a web page. For example, changing the font size or color without providing alternative options may make the content difficult to read for users with visual impairments. It's important to ensure that any style changes made with JavaScript do not negatively impact accessibility.

  3. Maintenance and debugging: Dynamically changing CSS styles with JavaScript can make the codebase more complex and harder to maintain. It can also introduce potential bugs and compatibility issues across different browsers and devices.

It's important to weigh the benefits and drawbacks before deciding to use JavaScript for manipulating CSS styles.

Follow-up 4

How can you ensure accessibility when changing styles with JavaScript?

To ensure accessibility when changing styles with JavaScript, consider the following:

  1. Provide alternative options: When changing styles that affect the readability or usability of the content, make sure to provide alternative options. For example, if you change the font size, allow users to adjust it back to the default size.

  2. Test with assistive technologies: Use screen readers and other assistive technologies to test the accessibility of the page after making style changes. Ensure that the content remains accessible and usable for all users.

  3. Follow accessibility guidelines: Follow WCAG (Web Content Accessibility Guidelines) to ensure that your web page meets the accessibility standards. Pay attention to contrast ratios, keyboard accessibility, and other accessibility requirements.

By considering these factors and testing for accessibility, you can ensure that changing styles with JavaScript does not negatively impact the accessibility of your web page.

2. What is the role of JavaScript in responsive design?

In 2026, CSS handles the bulk of responsive design through media queries, container queries, and flexible layout systems. JavaScript's role is complementary — it handles the things CSS cannot do.

What CSS handles natively

  • @media queries for viewport-based breakpoints
  • @container queries for component-level responsiveness based on parent size
  • Fluid typography with clamp()
  • Intrinsically responsive layouts with CSS Grid auto-fill + minmax() and Flexbox wrapping
  • aspect-ratio, min(), max(), clamp() for fluid sizing

Where JavaScript is still needed

  • Dynamic breakpoint logic: window.matchMedia() lets JavaScript react to breakpoint changes programmatically — for example, switching a carousel to a static grid above a certain width, or loading different data based on screen size.
const mq = window.matchMedia('(min-width: 768px)');
mq.addEventListener('change', e => {
  if (e.matches) initDesktopFeature();
  else initMobileFeature();
});
  • ResizeObserver: Watches an individual element's size and fires a callback when it changes, enabling JavaScript-driven responses to component resizing — predating or supplementing container queries.
const ro = new ResizeObserver(entries => {
  for (const entry of entries) {
    entry.target.classList.toggle('compact', entry.contentRect.width < 400);
  }
});
ro.observe(document.querySelector('.widget'));
  • IntersectionObserver: Detects when elements enter or leave the viewport for lazy loading images, infinite scroll, and triggering animations.

  • Touch and pointer event handling: Detecting swipe gestures, pinch-zoom, or hover-vs-tap differences requires JavaScript.

  • Conditional resource loading: Loading smaller images or reduced data payloads based on navigator.connection or screen resolution.

  • Viewport unit bugs: On mobile, 100vh historically included the browser chrome. JavaScript can measure window.innerHeight and write it as a CSS custom property to work around this (the dvh unit now handles this natively in modern browsers).

Interviewer follow-up: "Has container queries reduced JavaScript's role in responsive design?" Yes, significantly. Logic that previously required ResizeObserver and class toggling can now be expressed in pure CSS with @container queries, leading to simpler, more maintainable responsive components.

↑ Back to top

Follow-up 1

How does JavaScript interact with media queries?

JavaScript can interact with media queries by using the window.matchMedia() method. This method allows you to check if a specific media query matches the current viewport size. You can then use JavaScript to perform actions or apply styles based on the result of the media query check. Here's an example:

const mediaQuery = window.matchMedia('(max-width: 768px)');

if (mediaQuery.matches) {
  // Code to execute when the viewport width is less than or equal to 768px
} else {
  // Code to execute when the viewport width is greater than 768px
}

Follow-up 2

Can you provide an example of JavaScript being used in responsive design?

Certainly! Here's an example of JavaScript being used to toggle a navigation menu in a responsive design:





    .nav {
      display: none;
    }

    @media (max-width: 768px) {
      .nav {
        display: block;
      }
    }



  Toggle Navigation

    <ul>
      <li>Home</li>
      <li>About</li>
      <li>Contact</li>
    </ul>



    const toggleButton = document.getElementById('toggleButton');
    const nav = document.querySelector('.nav');

    toggleButton.addEventListener('click', () =&gt; {
      nav.classList.toggle('active');
    });



Follow-up 3

What are some alternatives to using JavaScript for responsive design?

While JavaScript is commonly used for responsive design, there are alternative approaches that can be used:

  1. CSS Media Queries: CSS media queries allow you to apply different styles based on the viewport size or device characteristics. This can be a purely CSS-based solution without the need for JavaScript.

  2. Server-Side Detection: Server-side technologies like PHP, Ruby, or Python can detect the user's device or viewport size and serve different HTML or CSS files accordingly.

  3. CSS Frameworks: CSS frameworks like Bootstrap or Foundation provide responsive design components and utilities that can be used without relying heavily on JavaScript.

It's important to consider the specific requirements and constraints of your project when choosing the approach for responsive design.

3. How can JavaScript be used to handle browser inconsistencies with CSS?

Browser inconsistencies in CSS have narrowed dramatically with evergreen browsers, but they have not disappeared entirely. JavaScript helps in a few specific ways.

Feature detection with JavaScript

Rather than browser sniffing (checking navigator.userAgent, which is unreliable and fragile), the modern approach is feature detection — checking whether a specific API or CSS feature exists:

if (!CSS.supports('container-type', 'inline-size')) {
  // load a polyfill or apply a fallback
}

CSS.supports() mirrors the CSS @supports at-rule and is the correct way to test CSS feature availability at runtime.

Polyfills and ponyfills

When a CSS feature is unavailable, JavaScript polyfills can replicate the behaviour:

  • Container queries had a JavaScript polyfill (@oddbird/container-query-polyfill) before native support landed.
  • ResizeObserver, IntersectionObserver, and MutationObserver all had polyfills for older browser support.

Modern projects targeting evergreen browsers rarely need these, but projects that must support older environments still load them conditionally.

Applying browser-specific classes

JavaScript can detect a browser quirk and add a scoping class to or, enabling targeted CSS overrides:

// Detect a specific rendering issue and apply a workaround class
if (someDetectedQuirkCondition) {
  document.documentElement.classList.add('needs-scroll-fix');
}

CSS custom properties as a bridge

JavaScript can detect a runtime value (like the actual available viewport height, accounting for mobile browser chrome) and write it as a CSS custom property:

const setVhUnit = () =&gt;
  document.documentElement.style.setProperty('--vh', `${window.innerHeight * 0.01}px`);
window.addEventListener('resize', setVhUnit);
setVhUnit();

This pattern was widely needed before dvh (dynamic viewport height) units shipped. Knowing the pattern and its modern native replacement demonstrates real-world experience.

What to avoid

User agent string sniffing: browsers lie in their UA strings, user agents change, and the strings are not reliable indicators of capability. Always test for the feature, not the browser.

↑ Back to top

Follow-up 1

Can you provide an example of a CSS feature that is not consistently supported across browsers and how JavaScript can be used to handle this?

One example of a CSS feature that is not consistently supported across browsers is the flexbox layout. Older versions of Internet Explorer (IE) have limited or different support for flexbox compared to modern browsers. To handle this inconsistency, JavaScript can be used to detect if the browser is IE and apply a different CSS layout technique, such as using CSS grid or manually calculating and setting the dimensions of the elements using JavaScript.

Follow-up 2

What are some other ways to handle browser inconsistencies with CSS?

Apart from using JavaScript, there are other ways to handle browser inconsistencies with CSS:

  1. CSS Feature Detection: Libraries like Modernizr can be used to detect the availability of specific CSS features in the browser and apply fallback styles or JavaScript-based solutions if the feature is not supported.

  2. CSS Prefixes: Some CSS properties require vendor prefixes to work correctly in certain browsers. By using tools like Autoprefixer, CSS code can be automatically generated with the necessary prefixes for different browsers.

  3. Polyfills: Polyfills are JavaScript libraries that provide fallback functionality for CSS features that are not supported in older browsers. They can be used to add support for CSS features like CSS variables, CSS animations, etc. in browsers that do not natively support them.

Follow-up 3

What are the potential drawbacks of using JavaScript to handle browser inconsistencies?

While using JavaScript to handle browser inconsistencies with CSS can be effective, there are some potential drawbacks to consider:

  1. Increased Complexity: Adding JavaScript code to handle browser inconsistencies can make the codebase more complex and harder to maintain.

  2. Performance Impact: Dynamically modifying CSS properties or adding/removing CSS classes using JavaScript can have a performance impact, especially on older devices or slower browsers.

  3. Dependency on JavaScript: If JavaScript is disabled or not supported in the browser, the fallback styles or workarounds may not be applied, leading to inconsistent rendering.

  4. Compatibility Issues: JavaScript-based solutions may themselves have compatibility issues across different browsers or versions, requiring additional testing and maintenance efforts.

4. Can you explain how JavaScript can be used to create CSS animations?

JavaScript creates CSS animations through two main APIs, plus the ability to drive CSS transitions by changing state.

1. CSS Transitions triggered by JavaScript

Define the transition in CSS, then use JavaScript to change a class or property. The browser handles the animation:

.box {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.3s ease, transform 0.3s ease;
}
.box.visible {
  opacity: 1;
  transform: translateY(0);
}
document.querySelector('.box').classList.add('visible');

This is the preferred pattern — styles live in CSS, JavaScript only manages state. It is performant because opacity and transform are compositor-layer properties that do not trigger layout or paint.

2. Web Animations API (WAAPI)

The Web Animations API lets JavaScript describe and control animations programmatically without writing any CSS keyframes:

const el = document.querySelector('.box');
const animation = el.animate(
  [
    { opacity: 0, transform: 'translateY(20px)' },
    { opacity: 1, transform: 'translateY(0)' }
  ],
  { duration: 300, easing: 'ease', fill: 'forwards' }
);

// Full playback control
animation.pause();
animation.currentTime = 150; // scrub to midpoint
animation.playbackRate = 2;  // speed up
animation.finished.then(() =&gt; console.log('done'));

WAAPI is now fully supported across modern browsers and is the modern programmatic animation API — it replaces the need for requestAnimationFrame loops in most cases and offers better performance than setInterval-based animation.

3. requestAnimationFrame for custom animation loops

For canvas animations, game loops, or physics-based animations that CSS cannot express, requestAnimationFrame schedules callbacks in sync with the browser's render cycle:

let start;
function step(timestamp) {
  if (!start) start = timestamp;
  const progress = (timestamp - start) / 1000;
  el.style.transform = `translateX(${Math.min(progress * 100, 200)}px)`;
  if (progress &lt; 2) requestAnimationFrame(step);
}
requestAnimationFrame(step);

4. Driving CSS custom properties

JavaScript can animate a CSS custom property value; CSS @property (Houdini) allows the browser to interpolate typed custom properties natively:

@property --gradient-angle {
  syntax: '';
  initial-value: 0deg;
  inherits: false;
}

Then animate --gradient-angle with WAAPI or a requestAnimationFrame loop.

Performance rules: always animate transform and opacity. Animating width, height, top, or left triggers layout recalculations on every frame — visible as jank. Use will-change: transform on elements you know will animate, but remove it after the animation ends to free compositor memory.

↑ Back to top

Follow-up 1

Can you provide an example of a CSS animation created with JavaScript?

Sure! Here's an example of how you can create a CSS animation using JavaScript:

const element = document.getElementById('myElement');

function animateElement() {
  element.style.transform = 'translateX(100px)';
  element.style.transition = 'transform 1s';
}

animateElement();

In this example, we select an element with the id myElement and then use JavaScript to change its transform property to translateX(100px). We also set the transition property to transform 1s, which specifies that the transition should take 1 second. This creates a smooth animation where the element moves 100 pixels to the right over the course of 1 second.

Follow-up 2

What are the benefits of using JavaScript for CSS animations?

There are several benefits of using JavaScript for CSS animations:

  1. Interactivity: JavaScript allows you to create animations that respond to user interactions or other events. This can make your animations more engaging and interactive.
  2. Dynamic animations: With JavaScript, you can dynamically change the CSS properties of an element based on conditions or calculations. This allows for more complex and dynamic animations that are not possible with CSS alone.
  3. Control: JavaScript gives you more control over the timing and behavior of animations. You can use JavaScript to start, stop, or pause animations, as well as control their speed and direction.
  4. Compatibility: JavaScript animations are supported by all modern browsers, so you don't have to worry about compatibility issues.

Follow-up 3

What are the potential drawbacks of this approach?

While using JavaScript for CSS animations has its benefits, there are also some potential drawbacks:

  1. Performance: JavaScript animations can be more resource-intensive compared to CSS animations, especially if you are animating a large number of elements or complex animations. This can lead to decreased performance and slower animations.
  2. Complexity: JavaScript animations can be more complex to implement compared to CSS animations. You need to write JavaScript code to handle the animation logic, which can be more time-consuming and error-prone.
  3. Browser compatibility: While JavaScript animations are supported by all modern browsers, there may still be some older browsers or devices that do not support JavaScript or have limited JavaScript capabilities. This can result in animations not working as expected on those devices.

Follow-up 4

How does performance compare between CSS animations and JavaScript animations?

In general, CSS animations tend to perform better than JavaScript animations. CSS animations are typically hardware-accelerated by the browser, which means they can be rendered more efficiently and with better performance. On the other hand, JavaScript animations are executed by the browser's JavaScript engine, which can be slower and less optimized for animations.

However, the performance difference between CSS and JavaScript animations can vary depending on the complexity of the animation and the number of elements being animated. Simple animations with a small number of elements may not have a noticeable performance difference between CSS and JavaScript. It's always a good idea to test and optimize your animations to ensure smooth performance.

5. How can JavaScript and CSS be used together to improve website performance?

JavaScript and CSS have distinct but complementary performance responsibilities. Using them well together reduces load time, avoids jank, and improves perceived responsiveness.

Defer non-critical CSS and JavaScript

Load only what is needed for the initial render. Mark scripts as defer or async to avoid blocking HTML parsing. Use dynamic import() to code-split JavaScript and load features on demand. Lazy-load non-critical CSS with `and anonload` swap.

Use CSS for animation, JavaScript for logic

CSS animations and transitions run on the compositor thread and do not block JavaScript. JavaScript should control state (adding/removing classes, updating custom properties) while CSS handles the visual output:

el.classList.add('is-animating'); // JavaScript changes state
// CSS defines what .is-animating looks like and how it transitions

Batch DOM reads and writes

Interleaving DOM reads (which force layout) with DOM writes (which invalidate layout) causes forced synchronous layouts, also called layout thrashing. Batch all reads first, then all writes:

// BAD: read → write → read → write causes multiple forced reflows
const h1 = el.offsetHeight; el.style.height = h1 + 'px';
const h2 = el.offsetHeight; el.style.height = h2 + 'px';

// GOOD: all reads, then all writes
const h1 = el.offsetHeight;
const h2 = other.offsetHeight;
el.style.height = h1 + 'px';
other.style.height = h2 + 'px';

The requestAnimationFrame callback and libraries like FastDOM formalise this separation.

CSS custom properties for dynamic theming

Instead of applying inline styles element by element, write a single custom property on :root and let CSS cascade do the work. One JavaScript write propagates to every consumer:

document.documentElement.style.setProperty('--theme-hue', userSelectedHue);

content-visibility: auto

This CSS property skips rendering off-screen content entirely. JavaScript does not need to do anything — the browser defers paint and layout for invisible sections automatically, dramatically reducing initial render time on long pages.

IntersectionObserver for lazy loading

JavaScript's IntersectionObserver API defers loading images, videos, and heavy components until they are about to enter the viewport, reducing initial payload:

const io = new IntersectionObserver(entries =&gt; {
  entries.forEach(entry =&gt; {
    if (entry.isIntersecting) {
      entry.target.src = entry.target.dataset.src;
      io.unobserve(entry.target);
    }
  });
});
document.querySelectorAll('img[data-src]').forEach(img =&gt; io.observe(img));

Avoid layout-triggering CSS properties in JavaScript-driven animations

Changing width, height, top, or left from JavaScript triggers a full layout recalculation. Use transform and opacity instead — they are GPU-composited and do not cause reflow or repaint.

will-change as a hint

will-change: transform on an element that is about to animate promotes it to its own compositor layer ahead of time, preventing frame drops at animation start. Remove it once the animation completes to free GPU memory.

↑ Back to top

Follow-up 1

Can you provide an example of a performance improvement made possible by using JavaScript and CSS together?

Sure! One example of a performance improvement made possible by using JavaScript and CSS together is lazy loading images. By using JavaScript to detect when an image is in the viewport, and then applying a CSS class to that image to load it, we can delay the loading of images that are not immediately visible to the user. This can significantly improve the initial load time of a webpage, especially if it contains a large number of images.

Follow-up 2

What are some other ways to improve website performance with JavaScript and CSS?

There are several other ways to improve website performance with JavaScript and CSS. Some examples include:

  1. Minifying and compressing JavaScript and CSS files to reduce their file size.
  2. Using CSS sprites to combine multiple images into a single image, reducing the number of HTTP requests.
  3. Using CSS animations instead of JavaScript animations, as CSS animations are often more performant.
  4. Using JavaScript to asynchronously load external resources, such as fonts or third-party scripts, to prevent them from blocking the rendering of the page.

These are just a few examples, and there are many other techniques and best practices available to improve website performance with JavaScript and CSS.

Follow-up 3

What are the potential drawbacks of using JavaScript and CSS for performance improvements?

While JavaScript and CSS can be powerful tools for improving website performance, there are also potential drawbacks to consider. Some potential drawbacks include:

  1. Increased complexity: Using JavaScript and CSS together to optimize performance can add complexity to the codebase, making it harder to maintain and debug.
  2. Compatibility issues: Not all browsers may support the JavaScript or CSS features used for performance improvements, which can lead to inconsistent behavior across different browsers.
  3. Increased load time: If JavaScript or CSS files are not optimized or loaded efficiently, they can actually increase the load time of a webpage instead of improving it.

It's important to carefully consider these potential drawbacks and weigh them against the potential performance benefits when using JavaScript and CSS for performance improvements.

Live mock interview

Mock interview: CSS and JavaScript Integration

Intermediate ~5 min Your own free AI key

Your voice and your AI key never touch our servers; the key stays in this browser and is sent only to Google. Only your round scores are saved to track progress.