css - shrink a parent div to fit one child's width and constrain the width of the other child [duplicate] - css

This question already has answers here:
How to match width of text to width of dynamically sized image/title?
(2 answers)
Closed 2 years ago.
Say, a parent div has two child divs, one containing text, the other containing an image of known (but variable) width & height.
I would like
the width of the first child (image-containing) div to shrink to fit the width of the image (this i can do)
the parent div (of unspecified width) to shrink to fit the width of the image-containing div (this is ok too)
the text-containing second child div (also of unspecified width) to match the parent div's width irrespective of the quantity of text it contains (this is where it gets tricky).
I have a working version that does what I want until the quantity of text in the second child pushes the parent div's width wider than that of the image.
Here's my code:
css:
#container{border:1px solid #f00;display:inline-block;}
#child1{border:1px solid #0f0;}
#child2{border:1px solid #00f;}
img {border:1px solid #000;}
html:
<div id="container">
<div id="child1"><img src="//www.google.com/logos/2012/Teachers_Day_Alt-2012-hp.jpg" width="300" height="116"></div>
<div id="child2">Lorem ipsum dolor sit amet.</div>
</div>
and here's a jsfiddle:
http://jsfiddle.net/BmbAS/1/
you can see where it's going wrong by clicking the 'lengthen/shorten text' link to increase the quantity of text
tldr - i want all the divs to be the same width which is equal to the width of the image
ps. modern browser solution only necessary

See this edited version of your jsFiddle.
Here's what's added to the CSS:
#container {
display: table-cell;
}
#child1 {
display: table-row;
width: 1px;
}
#child2 {
display: table-cell;
width: 1px;
}

The answer provided by #Chris leads me to the following, great solution of my case, where I need to fit the container div only to the first child element (and leave the rest child elements to auto fit to the container's width):
div.container {
width: fit-content;
max-width: 100%;
margin: 16px auto;
display: table;
}
div.inner-primary {
display: block;
}
div.inner-rest {
margin-top: 8px;
display: table-caption;
caption-side: bottom;
}
<div class="container">
<div class="inner-primary"><div style="width:200px; border:1px dotted #ccc; border-radius:4px; padding: 4px;">This is the main element that drives the width of the container.</div></div>
<div class="inner-rest">This is the first of the rest divs that fit automatically to the container...</div>
<div class="inner-rest">This is the second element...</div>
</div>

If you're willing to use a little javascript (jQuery in this example), you could set the width of the text div with the width of the image div.
Try adding $("#child2").css({'width': $('#child1').width()}); to the end of the JS in your fiddle, or check out the fork here: http://jsfiddle.net/VXEMu/

Related

How do I prevent multiline text from filling the entire width of the parent element

Suppose I have a container element that has a set width. I have a content element with a display inline-block that can contain some text. This text could be so big that it has to be filled over several lines. The problem with this is that default behaviour for multiline text is that it grows the element to the complete width of the parent element.
Imagine the following example:
HTML:
<div class="container">
<div class="content">
Firstreallongword11 Secondalsolongword22 Thirdwordthatisconsiderablylonger
</div>
</div>
CSS:
.container {
width: 260px;
border: solid blue 1px;
}
.content {
display: inline-block;
background: red;
}
Because these are long words, they will be positioned over multiple lines. What I would expect for the .content element, is that it would grow to the maximum width of the largest word on one single row.
But as you can see, because it consists of multiple lines, the element grows to the max width of .container .
FIDDLE
What I want to achieve is, .content gaining the width of the largest item on a single row, as it would with one single lin:
FIDDLE
Is there any way to achieve this with pure css/html?
The simple answer is: No, you can't do that with pure CSS.
But here is a solution anyway, which is a bit of a hack: It uses display: table-cell; for the .content element, and a rather small width value (which will adjust to the actual value of the longest word and acts like a min-width setting in this case):
.container {
width: 260px;
border: solid blue 1px;
}
.content {
display: table-cell;
width: 100px;
background: red;
}
<div class="container">
<div class="content">
Firstreallongword11 Secondalsolongword22 Thirdwordthatisconsiderablylonger
</div>
</div>

How to align two divs next to each other, first is fixed width, second is dynamic height

I am trying to produce responsive css for the following scenario. We have a div container (henceforth called 'the parent div/container'). Inside that div is an icon (represented by the 'X's below) and a set of text inside a div next to it (represented by the 'Y's below). Both 'X' and 'Y' containers have borders. The icon is 44px wide and we want the 'Y' container to be 100% of the remaining width. If the screen is resized, the 'Y' container flexes, taking up (or removing) additional lines as necessary. If the text is too long to fit on one line it will wrap within its own container. Roughly like this:
_____ ____________________
|XXXX| |YYYYYYYYYYYYYYYYYYY| <-Edge of screen
|XXXX| |YYYYYYYYYYYYYYYYYYY|
------ |YYYYYYYY |
--------------------
We've tried this a number of ways, but I've not been happy with any. My current attempt (somewhat simplified):
#parent { position:relative; }
#X { width: 44px; border: 1px solid red;}
#Y { position: absolute: left: 44px; top: 0px; border: 1px solid red }
This work for a number of my requirements, except that if the text overflows onto multiple lines the height of the 'Y' container is greater than the parent container and overlaps further content below the parent container. It also does not fill the remaining width.
I'd like to find a more elegant css-only solution to this. Any help appreciated!
EDIT: HTML looks like this:
<div id='parent'>
<div id='X'><i class="fa fa-exclamation-triangle"></i></div>
<div id='Y'>text goes here</div>
</div>
The simplest solution would be to use display: flex as shown below. It allows you to have exactly what you needed without taking too much care about the child elements.
#parent {
/* Set parent to flex, starting at
the very left corner. */
display: flex;
justify-content: flex-start;
/* If you want the icon to be on top,
use flex-start instead of center */
align-items: center;
}
#X {
/* Set fixed width. This part is important,
otherwise it would stretch the icon */
width: 44px;
}
#Y {
/* Set the #Y container to 100% width.
It will be stretched since it is a
relative width but its content stays within its borders */
border: 1px solid #000;
width: 100%;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<div id="parent">
<div id="X"><i class="fa fa-exclamation-triangle"></i></div>
<div id="Y">text goes here<br>
with some more<br>lines</div>
</div>

Floated DIV width = 100% - widths of two other floated divs

OK, so here is my problem,
I need to have four DIVs in one line. The First three are float:left and the fourth one is float:right. The container has a specified width.
I need the third div to fill all the space from the second div that is floated to the left, to the fourth div that is floated right.
EDIT: DIVs #1, #2 and #4 have dynamic width as well... They have a certain padding and the content defines the width.
Why not turn the question on its head, and establish how to create the layout you want- in which case, likely the simplest approach would be:
Demo Fiddle
HTML
<div class='table'>
<div class='cell'>fit</div>
<div class='cell'>fit</div>
<div class='cell'>expand</div>
<div class='cell'>fit</div>
</div>
CSS
.table {
display:table;
width:100%; /* <-- will make the divs align across the full browser width */
height:50px;
}
.cell {
display:table-cell;
border:1px solid red;
width:1%; /* <-- will make 1, 2, 4 only fit their content */
}
.cell:nth-child(3) {
width:100%; /* <-- will make 3 expand to the remaining space */
}
Solution Using Floated Elements
Here is one way of doing this using floats.
Arrange your HTML as follows:
<div class="panel-container">
<div class="panel p1">Panel 1 - and a word</div>
<div class="panel p2">Panel 2 - Done. </div>
<div class="panel p4">Panel 4 - End!</div>
<div class="panel p3">Panel 3</div>
</div>
and apply the following CSS:
.panel-container {
width: 600px;
border: 1px dotted blue;
overflow: auto;
}
.panel {
background-color: lightgray;
padding: 5px;
}
.p1 {
float: left;
}
.p2 {
float: left;
}
.p3 {
background-color: tan;
overflow: auto;
}
.p4 {
float: right;
}
The trick is to place the floated elements (.p1, .p2. .p4) ahead of the in-flow content (.p3).
Use overflow: auto on the parent container to keep the floated child elements from affecting the layout outside of the parent element.
I added overflow: auto on .p3 so that the padding gets included within the containing block.
See fiddle at: http://jsfiddle.net/audetwebdesign/9G8rT/
Comments
The one disadvantage of this approach is that the order of the content is altered, that is, .p3 appears after .p4 in the code order.
Another side effect, which may be desirable in a responsive design, is that the child elements will wrap onto 2 or more lines as the parent container width gets smaller.
If you need to retain the content order in the HTML code, the CSS table-cell solution is a good alterantive.
The table-cell solution will keep the child elements on a single line regardless of the width of the parent container.
One final advangtage of the floated element solution is that it is more backward compatible than a CSS table-cell solution, but as we move forward, this is becoming less
of a compelling argument.

Set child to content width, ignore parent width, and make parent scroll

With CSS alone, is it possible to obtain the following example, http://jsfiddle.net/LdJ7t/, without explicity knowing the child element's width before hand?
The final result desired:
parent element scrollable to child element
child element's width set to content
#Parent {
width: 100px;
height:200px;
background: #ccc;
overflow:auto;
padding: .5em;
margin: .5em;
}
#Child {
width:300px;
height:100px;
background:yellow;
}​
<div id="Parent">
<div id="Child">
This is a test. This is a test.
</div>
</div>​
It looks like display:inline-block; almost works: http://jsfiddle.net/LdJ7t/1/
I think this is possible. I just can't find a solution.
Your inline-block solution is correct - if you put longer words in or an image, the scrollbar will appear. Text is broken on white space by default.
If you don't want text breaking on white space, you can add white-space: nowrap; to the child div like here: http://jsfiddle.net/LdJ7t/2/

Dynamic height increase of one div with respect another div

I have two divs. These two divs are orientated as two vertical columns next to each other. Instead of pre-determining the height of the divs via css I want to have it grow dynamically with the content I put into it. Which is simple enough for one div but my problem is that I want the div on the left with background color green to grow to the same height of the div on the right . There is always going to be more content in the right than in left.
Assuming the elements are after body. Give 100% to the body, and all the div
body, #div1, #div2 { height: 100%; }
If they are not, then you have to either fix the height of the parent or chain 100% height all the way to the body again.
#parent { height: 800px; }
#div1,#div2 { height: 100%; }
Enclose those divs in a parent div, and set their height to 100%.
You simply need a three-column (X)HTML + CSS Layout.
It's here
Let insert a parent div (container of those two adjacent divs)
add a property 'display: flex;' to the parent div
.parent{
display: flex;
}
.child1, .child2{
padding: 10px;
border: 1px solid gray;
}
<body>
<div class="parent">
<div class="child1">
CHILD 1 AREA<br />
CHILD 1 AREA
</div>
<div class="child2">
CHILD 2 AREA
</div>
</div>
</body>

Resources