Controlling width of child of min-width parent - css

I have a simple, single page with a single, fixed-width content column (fixed width on body), that, among other things, contains figures as blocks.
Figures always contain exactly one image, an optional caption, and are styled with a border and a background. It is preferable that images retain their original size, but should be scaled down if the border-box width of the figure would not fit into the column. Captions, if present, should be contained within the figure (i.e. on its background and within its borders), and should be broken to multiple lines if it would cause the figure to grow in width.
I have come across basically two ways of achieving this, but I cannot really get either to work.
The first one is setting display: table on the figure and display: table-caption on the caption, but this seems to cause the browser to take it completely out of the figure, not leave it inside.
The second is setting width: min-content; max-width: 100% on the figure. This works properly if the figure is naturally smaller than the column width, but I could not manage to have it shrink the image. While the figure element itself is correctly width-limited, the image in it simply overflows. (width: fit-content also takes the caption's width into consideration.) object-fit: scale-down on the image gets completely ignored. If I set width: 100% and/or max-width: 100%, it gets arbitrarily scaled down to match the minimum width of the caption, if present, or 0 if there's no caption. Only thing that truly works is if I specify the image's exact width, but then it loses responsiveness.
I have looked all over the web for a solution, including SO, but not found a proper solution. Here's a simplified HTML/CSS to illustrate what I'm talking about.
<body>
<figure>
<img src="some-image.png" />
<figcaption>Lorem ipsum dolor sit amet, this might be narrower/wider than the image above or completely omitted.</figcaption>
</figure>
</body>
And the CSS:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
border: 1px solid red;
width: 300px;
}
figure {
background: gray;
display: block;
border: 1px solid blue;
width: min-content;
max-width: 100%;
}
figure img {
border: 1px solid green;
object-fit: scale-down; /* Doesn't seem to do anything */
width: 100%; /* This causes the image to shrink to the caption, or 0 if there is no caption */
max-width: 100%; /* Same as above */
}
I think I kind of understand why this is happening, I have no idea how to solve it. Any help would be appreciated. If JavaScript is absolutely necessary, please do not use any other frameworks than JQuery.
Here are two screenshots demonstrating both a correctly working and an overflowing case:

Your first approach might work. It puts the caption out of the figure box, but it does take on the figure width. So adding a background and border to your figcaption might do the trick. And leaving out the border bottom in the figure and the border top in the caption make it look like one box.
figure, figcaption
{
border: 1px solid blue;
background: gray;
}
figure
{
display: table;
border-bottom-width: 0;
}
figcaption
{
display: table-caption;
caption-side: bottom;
border-top-width: 0;
}
figure img
{
border: 1px solid green;
max-width: 100%;
}
See https://jsfiddle.net/xdv02n8e/11/

Related

Solution for variable height elements within relative width div

I have an image placed within a relative width div as part of a responsive page design. The div's width (and hence the image's size) is set to ensure that content beneath it appears above the fold on screens down to a certain resolution.
A minority of images that appear here have different dimensions (e.g. 4x5 format vs. 4x6). These taller images push the content beneath it below the fold.
I want to maintain the div's height for the 4x6 dimension, which represents the majority of images, such that when an alt format image appears here, the top and bottom of the image are evenly clipped.
I've tried a couple different approaches, none with the desired effect. Applying a max-height on the image element slightly distorts taller images. I tried max-height on the wrapper div with overflow:hidden, but that doesn't constrain the image element.
I applied max-height to that mainImage div, too, and this almost works. However, as you can see from the CSS, I'm using background-color and padding to create a border around the image. Setting max-height on the main div forces the bottom border of the image element outside of the main div. I also tried applying the border to mainImage, but the bottom border still does not appear. Lastly, with max-height applied to the div and not the image, the image is not centered vertically within the div.
I'm not sure how to accomplish what I'm after, or whether it's possible in a responsive design (i.e. without a fixed height). Any thoughts?
Here's the HTML:
<wrapper>
<header></header>
<content>
<!--the main image -->
<section>
<div id="mainImage" role="main">
<div class="in mainImageWrapper">
<img src="[IMAGEFILE]" />
</div><!--end mainImageWrapper -->
</div><!--end mainImage-->
</section>
<!-- more content -->
</content>
</wrapper>
And here's the CSS:
#wrapper {
width: 100%;
min-height:100%;
height: auto !important;
height:100%;
border: none;
}
#content {
margin: 0 auto;
width: 90%;
max-width: 980px;
}
#mainImage {
margin: 1% auto 3% auto;
width: 100%;
overflow: hidden;
}
.mainImageWrapper {
width: 100%;
max-height: 634px; /* The aforementioned fix that doesn't provide the desired effect */
overflow:hidden;
margin: 0 auto;
padding: 0;
display: table-cell;
text-align: center;
position: relative;
}
#mainImage img {
width: 97%;
padding: 1.5%;
background: #FFFFFF;
margin: auto;
vertical-align: middle;
-moz-box-shadow: 1px 2px 8px #1A1A1A;
-webkit-box-shadow: 1px 2px 8px #1A1A1A;
box-shadow: 1px 2px 8px #1A1A1A;
}
So, it appears that what I want to accomplish above isn't possible through css. I wound up implementing phpThumb and using the z-crop parameter to crop images that exceed a certain height from the center. Works well for most instances. Only issue I've encountered with this approach is that, since this is a photography website that includes watermarked images, occasionally the crop cuts off the watermark in an awkward way.

css min-width issue

.mainCoverWrapper {
position: relative;
min-width:312px;
background:red
}
I'm trying to center a div with min-width of 312px and make it expand according to its dynamic content while keeping it centered.
Right now the min-with doesn't work at all because it needs a float. I can't use a float because I need the div centered on the page.
In other words, div starts out with margin auto with a width of 312px and expands with its added content while being centered. Is this possible?
Any help would be greatly appreciated.
http://jsfiddle.net/FVmvA/
Here's a working example of the parent to follow the width of the child, and the child will expand according to the text given in it.
.myCoverWrapper {
border: 1px solid Peru;
margin:auto;
min-width: 200px;
max-width: 100%;
display: inline-block;
background: red;
}
.test {
height: 100px;
margin: 10px;
background: cyan;
}
This makes the parent div follow the width of the kid.
This however, will disallow you to "center" it. There's no way you can have both. This is because you cant center an image without knowing the width of the element.
The solution is to use jQuery, to add CSS in when necessary.
Here's an example. There's some bugs, but well, you have the general idea.
If you want the width to be fluid, your best bet is to set display: inline-block; on the to-be-centered element, and text-align: center; to the parent element.
See: CSS center display inline block?

height percentage problem for body tag - unresolved through searches

I have read a vast amount of posts on the subject of css heights filling the viewport and have failed to find a working answer. So I'm reluctantly starting yet another thread about this in the hope of finding the missing part of the jigsaw I have probably been staring at without seeing it.
My DOCTYPE is xhtml transitional and I'm currently testing on IE6, FF6 and Safari 5 with the same problem.
I have a container div that also displays an image driven border within a table and I want this to fill the browser window, no bigger, no smaller but adaptable to each browser (minimum heights will be set to ensure all content is contained to account for older resolutions).
I have set the html and body styles as follows:-
html {
height:auto !important;
height: 100%;
min-height: 100%;
border: solid;
border-color: black;
overflow: hidden;
}
body {
height: 100%;
height:auto !important;
min-height: 100%;
border: solid;
border-color: black;
}
As you can see I have added a border to each of the elements so that I can actually see the size of each when I view the page. The html element fills the window fine, but the body element doesn't. It just shows a short box along the top of the window.
Can anyone offer a suggestion as to what may be causing the problem?
This is all you need for the css:
html,body {
padding: 0;
margin: 0;
height: 100%;
}
Live example: http://jsfiddle.net/tw16/gyAKJ/

How can I make the width of my <figcaption> match the width of the <img> inside its <figure> tag?

Say, I got this code:
<figure>
<img src="bunnyrabbit.jpg" width="200" height="150" alt="An image of a bunny rabbit." />
<figcaption>Bunny rabits are cuddly and fluffy creatures with big ears. They eat carrots.</figcaption>
</figure>
If I don't use any CSS the figcaption will expand the width of the figure element beyond 200px. How can I prevent this?
I know I can force the text inside the figcaption to wrap by specifying the width of the figure element (<figure style="width:200px;">) but I don't really want to use this for each and every image.
Adding this Code to <figure> and <figcaption> CSS-Attributes helped me with the same problem. Also, it preserves the responsivenes of your images and captions.
figure { display: table; }
figcaption { display: table-caption; caption-side: bottom ; }
Adding display: table; sets the stage.
Adding display: table-caption; alone placed the caption on top of
the image, The caption-side property specifies the placement of
the table caption at the bottom, top is default.
This will place the figcaption side by side with the img:
figure {
display: table;
}
img, figcaption {
display: table-cell;
vertical-align: bottom;
}
figcaption {
padding-left: 4px;
}
Here's an example. However I'm not entirely clear what you're trying to achieve - you say in the question that you want the figure to stay at 200px width, but then you comment that you want the figcaption to appear to the right, which would make the figure wider. If all you want is for the figcaption to be restricted to the width of the image, this should work:
figure {
display: table;
width: 1px; /* This can be any width, so long as it's narrower than any image */
}
img, figcaption {
display: table-row;
}
Another solution: Use Intrinsic width
Just set width: min-content; on the figure element
DEMO (Except for IE)
figure {
width: -webkit-min-content;
width: -moz-min-content;
width: min-content;
}
<figure>
<img src=" http://placehold.it/200x150" width="200" height="150" alt="An image of a bunny rabbit." />
<figcaption>Bunny rabits are cuddly and fluffy creatures with big ears. They eat carrots.</figcaption>
</figure>
NB: Browser Support is OK, except for IE, however they are considering implementing this
Unfortunately, setting the width of the figure instead of using max-width: 100% means that it won't shrink on narrow (mobile) devices. That is, the images will not be responsive. I resorted to inserting <br /> to break up long captions, but I didn't like it. But this obscure CSS feature seems to work for me:
figcaption {
display: run-in;
width: 150px
}
This keeps the image responsive, even though the caption isn't. You can pick your own caption width. I also added margin: auto;
text-align: center; to center the caption on a mobile device.
This was really bothering me, because I wanted to find an answer to accommodate an upgrade to HTML5 that would successfully replace my original setup of displaying images and captions- a table with two rows (or one if no caption was available).
My solution might not work for everyone, but so far, it seems to do just fine in the major browsers (O, FF, IE, S, C), as well as being responsive on mobile devices:
figure {
border: 0px solid #000;
display: table;
width: 0;
}
The idea here is that figure is pushed into existence by the width of the img and so doesn't need any kind of direction.
figure img {
display: block;
}
This is used to rid ourselves of the useless, unsightly gap between the bottom of img and the bottom of figure.
figcaption {
text-align: left;
}
Now that figure has been pushed open just wide enough to let img in, figcaption text has only that limited amount of space in which to exist. text-align is not required for this solution to function.
This solution works as well as display: table-caption, but keeps figcaption contained in any border or background value that might need to be set.

Pixel and percentage width divs side-by-side

I've found a lot of similar questions, and tried out several solutions (including some of the so-called "holy grail" CSS layouts), but they don't quite do what I need.
I have a containing div (a CSS containing block) with id right. Inside it on the left side, I want a fixed-width div (a splitter bar, but it doesn't matter what it's being used for; id splitpane); on the right, filling the rest of the space, another div (id right-box below).
I've tried making the two inner divs display: inline-block (with vertical-align: top), setting the left one to width: 3px, but then there's no way to set the right to have width 100% - 3px. I've also tried using the float: left/margin-left: -100%/margin-left: 3px trick, but it has the same problem: the 100% plus the 3px overflows the parent containing block and causes a scroll bar to pop up. (Of course, it's not the scroll bar per se that's the problem; I could use overflow: hidden to remove it, but then content on the right would be truncated.)
Currently I'm using width: 99.5% for the right div, but that's a terrible hack (and is subject to overflow depending on screen width). It looks a bit like this:
<div id="right"><div id="splitpane"></div><div id="right-box">
...
</div></div>
With CSS as follows (float version, but the inline-block version is similar):
#right {
display: inline-block;
vertical-align: top;
height: 100%;
width: 85%; /* this is part of a larger div */
}
#right-box {
width: 99.5%; /* stupid hack; actually want 100% - 3px for splitter */
height: 100%;
}
#splitpane {
float: left;
width: 3px;
height: 100%;
background: white;
border-left: solid gray 1px;
border-right: solid gray 1px;
cursor: e-resize;
}
Is it even possible to do this? This is for an internal app., so solutions only need to work in Firefox 3 (if they are specific to FF3, though, preferably it's because the solution is standards-compliant but other browsers aren't, not because it's using Firefox-only code).
DIVs are the wrong element type for this since they don't "talk" to each other. You can achieve this easily with a table:
<table style="width:200px">
<tr>
<td id="splitpane" style="width: 3px">...</td>
<td id="rightBox" style="width: 100%">...</td>
<tr>
</table>
The 100% will make the rightBox as wide as possible but within the limits of the table.
This is possible. Because block level elements automatically expand to take up any remaining horizontal space, you can utilise a block level element next to an uncleared floated element with your desired width.
<style type="text/css">
div {
height: 100px;
}
#container {
width: 100%;
}
#left {
background: #FF0;
}
#splitpane {
position: relative;
float: right;
background: #000;
width: 3px;
}
</style>
<div id="container">
<div id="splitpane"></div>
<div id="left"></div>
</div>
See http://jsfiddle.net/georeith/W4YMD/1/
why you didn't use margin-left (since it was float layout) on right box?
so no need to create a splitter div...
#right{
width:200px; /*specify some width*/
}
#rightbox{
float:left;
margin-left: 3px; /*replace the splitter*/
/*margin: 0 3px; /*use this to give left & right splitter*/ */
}
yeah something like that, i hate empty div, it's not semantic and it's like putting a splitter on the "old" table way
If the div #right-box is only going to contain non-floated content it might be an idea to just put the content inside #right instead and let it wrap around the floated #splitpane.

Resources