0

The following javascript returns the viewport of a browser:

<script>
  $(document).ready(function(e) {
    showViewportSize();    
  });
  $(window).resize(function(e) {
     showViewportSize();
  });
  function showViewportSize() {
     var the_width = $(window).width();
     var the_inner_width = window.innerWidth;                   
     $('#width').text(the_width);
     $('#inner_width').text(the_inner_width)
  }
</script>

The browser can display the value via

<span id="inner_width"> Resize me </span>

How can width or innerWidth be invoked in a rails condition within a view file, assuming one wants to generate an image_tag based on the initial viewport width:

<% if width > 1440 %>
  <%= image_tag(...
<% elsif width <= 1440 && width > 1200 %>
  <%= image_tag(...
<% else %>
  <%= image_tag(...
<% end %>
3
  • Correct me if I'm wrong, but Rails is like PHP, it's a server-side templating engine, right? In this case, well, you can't, by design. When JS is executed, the template has already been rendered and all templating code has already disappeared. Use CSS media queries for what you want to achieve. Commented Feb 4, 2020 at 15:57
  • Agree with @JeremyThille. There are other things you could do - an ajax call back to the server with viewport width as a param, render all images and set display: none in your css based on viewport width, etc. - but you can't do what you're specifically asking. Commented Feb 4, 2020 at 16:29
  • @JeremyThille technically its wrong to call Rails a templating engine. Its a whole framework like Symfony or Laravel in the PHP world. The actual templating engine (ERB) is actually part of Rubys standard library. But your basic point that it runs on the server still stands. Commented Feb 4, 2020 at 19:22

1 Answer 1

1

You would need a time travel device for this to even be remotely possible. The view is rendered on your server long before the page is even sent to the client. The only way the server would know the viewport size is if you sent it in the request. And thats not exactly ideal as the viewport size may change after the fact. The javascript is executed much later on the client when it gets the response from the server.

The solution is really simple - just provide all the available paths to the client and let it choose what image size to use.

Nowadays <img> tags can be made responsive with the srcset and sizes attributes. This is an example from MDNs excellent tutorial on responsive images:

<img srcset="elva-fairy-480w.jpg 480w,
             elva-fairy-800w.jpg 800w"
     sizes="(max-width: 600px) 480px,
            800px"
     src="elva-fairy-800w.jpg" alt="Elva dressed as a fairy">

srcset defines a comma separated list of sources and sizes defines the media rules that choose what size is used.

A quick and dirty rails conversion would be:

<%= img_tag('elva-fairy-800w',
  srcset: ["480w", "800w"].map {|s| image_path('elva-fairy-' + s) " #{s}" }.join(', ')
  sizes: "(max-width: 600px) 480px, 800px",
  alt: "Elva dressed as a fairy"
)%>
Sign up to request clarification or add additional context in comments.

2 Comments

Back in the early days of responsive design we would just use javascript and change the src attribute of the image which will cause it to reload. On the other end you had a php script running image_magic which would resize a full size image according to the ?size= parameter. Then came CSS media queries and "faux" images.
Whomever stumbles upon this, I second the observation of MDN's tutorial. Truly excellent. One thing to fiddle with is the max-width attribute. If the viewport is your tripwire for switching to the next size, as the first true condition is met, one needs to set it for each size except, obviously, for the last step.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.