CSS: Strange behavior for inline-grid + svg in Firefox - css

Consider this example:
.grid {
display: inline-grid;
grid-template-rows: 25px 100px 25px;
width: auto;
}
svg {
height: 100%;
}
.item {
grid-row: 2;
}
<div class="grid">
<div class="item">
abc
</div>
<div class="item">
<svg viewbox="0 0 20 40">
<rect width="20" height="40" style="fill:deeppink;" />
</svg>
</div>
</div>
In an inline-grid container I'm positioning two items next to each other in the same grid-row. Now, my problem is that in Firefox the second item (containing the svg) gets a width of 0px as opposed to the expected width of 50px that I also get in Chrome. (Visually the result is the same, but this breaks the layout and makes it very problematic if other stuff happens around it)
What I want to do here, is to set the svg to height 100% and let the width of the svg AND the parent container be determined by the svg's internal ratio.
Can you help me how I can fix this in Firefox?
This is how I see the example in Firefox:
Notes:
I'm not looking for a way to achieve a certain layout here. I'm struggling to understand why the svg doesn't stretch the parent div in Firefox.
Things change of course, if I give the svg a width value. But in this approach I want the svg to have a height equal to the grid-row and let its internal ratio define the width.
Of course there are millions of ways to achieve layouts like this with flexbox etc. But I'm really interested in the inline-grid scenario.
I really want the svg to be placed directly within the html. No <img>, background-image etc.

Related

Image alignment with responsive sizes and fixed px margins

I'm working on a site where I have been given very strict spacing requirements. One of these is that there should be 30px margin between all images. The images themselves can be responsive but the margin must remain the same.
The problem I have run into is depicted below. Essentially I have two columns side by side. In one there are two square images with a 30px gap in the middle. In the other is a single tall image with a height equivalent to 2X the height of a square image + 30px (to account for the margin between the two squares).
On a large screen when the images are their full size this displays correctly, however on smaller screens the images shrink. As a result of this the + 30px included in the tall image size to match the margin between the squares is reduced. However the margin between images remains at 30px, this results in a gap at the bottom putting the images out of alignment.
What elegant solutions have people used for this issue before? I am sure it is a straight forward issue yet the only solutions I have found are convoluted and messy.
Tech-wise I'm working with the grid from bootstrap 3, and Styled Components.
So I've found a reasonably satisfactory solution, that keeps the images perfectly aligned and preserves the margin regardless of screen size. However, a drawback of this method is that the image is not centrally aligned within the containing <TallImage> div, meaning the true centre of the image is shifted to the right.
I'm going to leave the question open as I'd welcome seeing whatever other solutions anyone can come up with. But for someone that is looking, my solution is below.
import styled from 'styled-components';
const TallImage = styled.div`
height: 0;
margin: 0 0 30px;
overflow: hidden;
padding-top: calc(200% + 30px);
position: relative;
width: 100%;
img {
height: 100%;
position: absolute;
top: 0;
width: auto;
}
`;
<div className="row">
<div className="col-sm-6">
<SquareImage>
<img src="..." alt="..." />
</SquareImage>
<SquareImage>
<img src="..." alt="..." />
</SquareImage>
</div>
<div className="col-sm-6">
<TallImage>
<img src="..." alt="..." />
</TallImage>
</div>
</div>

Centre Image in DIV (Original can be bigger than DIV)

Struggling with the dreaded centring of different sized images in a DIV.
Got a solution from StackOverflow ( How to vertically align an image inside div ), using a <SPAN> as a dummy element (with vertical-align: middle) and it works well except for the images which are bigger than the DIV and these are correctly resized, but shown below the DIV.
If I remove the <SPAN>, then the centring works in the horizontal, but not in the vertical.
If there is a simple change, I can make as I like the simplicity of the solution.
The tests are at
http://mclportal.net/ModalTests.html
This will work for you:
<div id="divModal" style="display:table">
<div id="divImage" style="display:table-cell; vertical-align:middle">
<img id="img" src=".........">
</div>
</div>
You should put max width and max heights on your images. Then just use relative positioning of the images inside a div with a relative position. for instance...
<div style="height: 300px; width: 300px; position: relative; text-align: center;>
<img src="#" style="max-width: 200px; max-height: 200px; position: relative; top: 50px; />
</div>
Using an approach like this all images will be vertically aligned with each other and centered within their div container. Plus having max height and width set will allow the image to keep its aspect ratio.
#mcl not sure if you've managed to resolve your problem yet.
If not checkout out my blog post centering large images in smaller containers their is also a codepen demo on there.
I had the same issue and managed to get it working without any need of javascript or inline styles.
Hope it helps

how to make the height of all three sections same?

I've attached a screenshot with this question. There are three columns and I want to keep the height of all the three columns exactly same. I managed to keep the width same with width css property now i wanted to adjust to height. Can anyone help me out in this regard. Thanks in advance.
I would use the following CSS to achieve this:
.wrapper {
display: table;
table-layout: fixed;
width: 100%;
}
.column {
display: table-cell;
}
With table-layout: fixed you're telling every child elements with display: table-cell to have same width, equally distributed based on wrapper's width, as well equal height.
Demo
In pure CSS you can use CSS3 columns: for a 3-column layout just try with
<div style="columns:3">...</div>
(with both -moz- and -webkit- prefixes)
See https://developer.mozilla.org/en-US/docs/CSS/Using_CSS_multi-column_layouts for the reference, in particular about the height balancing:
Height Balancing
The CSS3 Column specification requires that the column heights must be balanced: that is, the browser automatically sets the maximum column height so that the heights of the content in each column are approximately equal.
There is actually no right, cross browser way to do this, but rather you have to resort to some hacks.
A method I have used previously is to wrap the three columns inside a container and set a custom background to the hole container. Basically you create an image, having the same width of the website, having the two vertical lines, and you set it as the background of the container.
<div class="wrapper">
<div class="column">....</div>
<div class="column">....</div>
<div class="column">....</div>
</div>
<style> .wrapper { background-image: url(wrapper-bg.png); } </style>
You could use a javascript library like http://www.cssnewbie.com/equalheights-jquery-plugin/#.UVwCaZAW200 to achive this. This method however does not work if, the hight of the columns is dinamically changing in height (e.g. you have a collapsable item in it). Of course you can handle this cases by handling those events and recalculating the hight.
Finally you could use height: 100%. It's not as simple as it seems however! This solution does only work for block elements and the size of the parent has to be known. So, if you know the size of the website in advance you can do something like the following:
<div class="wrapper">
<div class="column">....</div>
<div class="column">....</div>
<div class="column">....</div>
</div>
<style>
.wrapper { height: 1000px; width:900px; }
.column { width:300px; float:left; height: 100%; }
</style>
Hopefully this will become simpler in future....

Force Parent Div To Inherit Child Image Height (For Responsive Scaling Images)

I'm trying to make the parent div inherit the height that the responsive child image sets... but it's not working.
This is for a responsive website, so when resizing the browser, the image resizes. The problem is that if I set a height on the parent .mosaic-block-three element, then the image appears to stay fixed at that height.
If I set the .mosaic-block-three element to height: auto, then it fails completely and goes down to 0 height.
What am I missing to make this scale smoothly? I can rearrange and add css, html or javascript, whatever I have to do to get it done. I've tried for hours so any help is GREATLY appreciated :-)
The example page is here: http://bit.ly/KzfN2g
My goal is to replicate how the images are perfectly responsive on this page, but with the addition of the rollover mosaic text: http://bit.ly/LIrJv7
<div class="mosaic-block-three magnifier2">
<div class="details">
<a class="pf_title_link" href="/portfolio/vignette-tiered-architella-shades/">Vignette® Tiered™ Architella® Shades </a> </div>
<div class="mosaic-backdrop" style="display: block; ">
<img src="/wp-content/uploads/2012/05/home-office-vignette-tiered-architella-shades-01-1024x564.png" class="attachment-large wp-post-image" alt="home-office-vignette-tiered-architella-shades-01" title="home-office-vignette-tiered-architella-shades-01">
</div>
<!-- end mosaic-backdrop -->
</div>
This is working with these few CSS changes (tested in Chrome only):
mosaic.css line 46
.mosaic-block-three {height: 250px}
mosaic.css line 74
.mosaic-backdrop {position: absolute}
promotion.css line 92
.details {margin: 15px 20px; margin: 0 20px;}
responsepress.css line 155
.mosaic-backdrop img {float:left}
You might want to move the border-radius:5px to the img now also.
You should probably use an img tag instead of a background. Then set a max-width of that image. don't set a width/height on the parent element.
That should work!

Scale image with css to both width and height to scale

The bounding box is approx 1000x600, and some images are 500x100,
while some others are 400x100 (extreme examples). Now I'd like to
scale both up to the maximum size the bounding box is capable to
handle, but keep them to scale.
img {
width: 100%;
height: 100%;
}
Won't keep the image to scale.
You can set only width or only height to 100%. E.g.
img {
width: 100%;
}
or
img {
height: 100%;
}
That will preserve the image scale, but the image might overflow the container.
This might not work in all browsers, but it does in the latest versions of Firefox, Chrome and Opera. I've had weird experiences with this in the past and my solution was to calculate the new image size on the server.
I was having difficulty with this until I read this thread (resize view width, preserve image aspect ratio with CSS), and the List Apart article (http://alistapart.com/article/fluid-images) and put it all together.
If your markup is like this...
<img src="myImg.jpg" />
...then simply stating
img {
width:100%
}
should be enough because most modern browsers realise that most people, given a choice, don't want to change the aspect of their images. However, if your markup contains dimension attributes like...
<img src="myImg.jpg" width="400" height="400" />
...which, is meant to be better technique, then the markup will shine through the CSS keeping the image at fixed height but flexible width (urgh!) unless you tell it otherwise with something like...
img {
width:100%;
height:inherit;
}
...or...
img {
width:100%;
height:auto;
}
Both seem to work and force the image back into correct aspect.
I've just stumbled upon this problem myself (my WYSIWIG editor adds dims to images by default - I needed a simple solution or I needed to spend hours hacking JCE to stop this behaviour) and haven't yet tested it exhaustively but it should give you a good starting point if you're having the same issue as me.
I don't know if there is a way to do this with just CSS. If you want to achieve something like this then you can use supersized
Alternatively, if you don't care about older browsers, you can look into the CSS3 background-size property. Specifically, I think that setting background-size: cover will do the trick.
Edit - I misunderstood. What you might actually want is background-size: contain, but the downside is that you probably will have to change your html markup, not just your css.
I think this A List Apart article may help you greatly, it discusses responsive images that adapt to their container, maintaining aspect ratio.
Essentially you just need to contain the <img> and specify dimensions for that container than apply max-width:100% to the <img> and it will adapt. Read the rest of the article for obligitary IE considerations (thankfully IE7+ supports it).
Setting only width or height doesn't always work, so alternatively you can set:
img {
max-width: 100%;
max-height: 100%;
}
BUT
it will not extend images over their original size
You can't do it like that. You can edit the image element's width and height attributes...
<!-- keeps width-height ratio -->
<img src="smiley.gif" alt="Smiley face" height="50" />
<!-- keeps width-height ratio -->
<img src="smiley.gif" alt="Smiley face" width="50" />
<!-- does not keep width-height ratio, unless your image is square -->
<img src="smiley.gif" alt="Smiley face" height="50" width="50" />
You can set the width and height to either pixels or percent. Note that you don't have to write px when using pixels, but you do have to write % when doing percentage. So you can do something like...
<img src="smiley.gif" alt="Smiley face" height="100%" width="100%" />
... but that will take 100% of the width and height of the parent element. So be sure you know what the parent element is and its dimensions.
An update to this in 2020. The css property object-fit can be used to display an image at 100% width and height without distorting it.
.wrapper {
height: 100px;
width: 100px;
border: 1px solid;
}
img {
width: 100%;
height: 100%;
}
.contain {
object-fit: contain;
}
.cover {
object-fit: cover;
}
<div class="wrapper">
<img src="https://i.stack.imgur.com/6c39r.jpg" />
</div>
↑ default, bad aspect ratio
<div class="wrapper">
<img src="https://i.stack.imgur.com/6c39r.jpg" class="contain" />
</div>
↑ <code>object-fit: contain;</code>
<div class="wrapper">
<img src="https://i.stack.imgur.com/6c39r.jpg" class="cover" />
</div>
↑ <code>object-fit: cover;</code>

Resources