I'm having a little CSS trouble.
I have some div elements structured like the following example. There are a dynamic number of class="block" divs, each with a fixed width:
<div class="outer-container">
<div class="inner-container">
<div class="block">text</div>
<div class="block">text</div>
<div class="block">text</div>
<!-- More "block" divs here -->
</div>
</div>
My goal is to find a CSS-based solution that will.
Display the class="block" divs inline, without them wrapping to new lines.
Support a variable number of class="inner-container" divs like the one above, each displayed as its own line.
Have the outer container fluidly "shrink-wrap" to match the width of its contents.
Any suggestions?
Not 100% sure if this is what you're looking for, but it might be a start:
http://jsfiddle.net/r4dEX/3/
By setting each block element to display: inline-block and white-space: nowrap, it should allow the elements to sit alongside each other, but not wrap to a new line if the content is longer than the available space (instead the block will move to a new line).
Each inner-container will display on its own line (display: block is default behaviour for a div).
Setting the outer container to display: inline-block will cause it to 'shrink wrap' to fit its content.
Here is an example where the blocks are inline, the inner-containers have a fixed width, and the outer-container is shrinking to fit.
Related
I need to constrain content in a div that has zero or more of height, width, max-height, or max-width set. If the content is smaller than the container in either dimension, it must be centered in that dimension; if it's larger, it must be scrollable in that dimension and start scrolled to the top/left.
This renders as I expected, with the image and text scrolling around, and the top-left corner of the image showing initially:
<div style="background-color:red;max-width:10rem;max-height:10rem;overflow:auto">
<div>
<img src="https://picsum.photos/id/123/400/300.webp">
</div>
<div>test</div>
</div>
It looks like this:
This is the full image:
This doesn't render as I expected (note the addition of display:flex;flex-direction:column;justify-content:center):
<div style="background-color:red;max-width:10rem;max-height:10rem;overflow:auto;display:flex;flex-direction:column;justify-content:center">
<div>
<img src="https://picsum.photos/id/123/400/300.webp">
</div>
<div>test</div>
</div>
It looks like this:
If I remove justify-content, then initially the top-left of the image is displayed, as expected. However, the content is no longer centered vertically if it is smaller than the container.
My questions are:
Why is justify-content affecting the scrollability and placement of the content? Shouldn't it only affect the immediate children of the div it's set on?
How do I achieve the effect I need?
JSFiddle: https://jsfiddle.net/5m4hec27/
<div style="background-color:red;max-width:50rem;height:10rem;overflow:auto;display:flex;justify-content:center; align-items:center;">
<div>
<img src="https://picsum.photos/id/123/400/300.webp">
</div>
<div>test</div>
</div>
Please check the code snippet and try to run it. Try to play with the value of height and width.
If container width is more than the child elements, Child elements will be horizontally centered automatically because of the justify-content property.
If container width is less than the child width, then it will show a horizontal scrollbar because of the overflow property.
If container Height is more than the child element, Child elements will be vertically centered automatically because of the align-items property.
If container height is less than the child width, It will show a vertical scrollbar because of the overflow property.
Note : 1. justify-content is not affecting the scroll ability
2. How to achieve the effect - Please see the Fiddle attached.
I'm trying to make some html form with help of bootstrap. Some of my inputs must have no gap from left or right side. But bootstrap .col-XX-Y blocks have gutter via paddings from left and right. So my idea was to use negative margin for my input elements, and display: block. And here I'm stuck.
Please refer to this codepen example. I was faced with several strange things for me:
Why input with display: block doesn't fill all it's parent
container, like div does? It fills the container only with: width:100%; (comment width for red-bordered input in codepen example)
Why if I'm apply negative margin-left to compensate parent container's
left padding, my input shifts to the left, but keeps it's original width (like if left css property was used). Doesn't it have to behave
like a block element (e.g. div): shifts to the left and keep
filling of all width of it's parent, excluding right padding?
When I'm apply negative right margin for my input to compensate parent's right padding, then nothing happens (look my example, compare orange div
with red input). Why? What about of a behavior like block element?
If this is normal behavior, can you give me some link to html standard docs with explanations of that.
If you don't want the padding on a grid parent element to effect its children, surround all its children elements in a block element with a class of row.
Bootstrap input elements are meant to span the whole width of there parent elements even without display block style attribute.
<div class="col-md-12">
<div class="row"> <!--this is what you need -->
</div>
</div>
full example code
<div class="col-md-12">
<div class="row">
<input type="text" placeholder='I\'m some damned input' />
</div>
<div class="row">
<div>I am some div</div>
</div>
</div>
Form elements do not behave the same way as regular block level elements. When you display an <input> field as block it will not fill the full width.
For this reason you need to make give the element width: 100%. This is how Bootstrap styles form elements.
Like any other block element, giving it a width of 100% will allow it to fill the width of its container. When you apply a negative margin-left, the width will still be the same (100% = containers width) which will cause the gap to appear.
I would suggest wrapping the <input> field in a <div> and apply the negative margin to that instead:
.wrap {
margin: 0 -20px;
}
.wrap input {
width: 100%;
display: block;
}
I have a page where I want an element to align right at the same time I have elements which may be wide and cause a horisontal scrollbar. For instance:
<body>
<div style="float:right">Stay right</div>
<div style="white-space:nowrap; clear:both; font-size:2em">
Wide child element which determines the width of the page.
</div>
</body>
This works fine if the wide element fits within the browser window. But if the browser window is too small so that a horisontal scrollbar appears the "stay right" element will align with the window and not the page:
If I move the scrollbar the "stay right" element moves and doesn't really align to anything.
If a add a table around the whole page it does what I wan't:
<body>
<table width="100%"><tr><td>
<div style="float:right">Stay right</div>
<div style="white-space:nowrap; clear:both; font-size:2em">
Wide child element which determines the width of the page.
</div>
</td></tr></table>
</body>
The "stay right" element will align with the right side of the wide child element regardless of browser window size.
Edit: The table based solution above will align right to largest of the width of the wide child element or the window width. Effectively this gives the page a "minimum width" which is determined by the contents of the page (ie. the wide child element). This is what I want - which isn't clear from the original text, sorry.
I am wondering if there is a better way than wrapping the entire page in a table.
That is a very interesting problem. It actually happens because the computed width on div matches the window size (and body size) instead of the width of the text. The floating text looks to it's container for a width/height when rendering (and because that computed value is actually size of the window, the float stops at the edge of the window).
This does not really occur often because most sites use something like grid960/foundation/etc and a min/max width are provided (you probably figured out that setting a width will fix your problem).
I don't know of a really good solution for dynamically sized text (with only css)... The only thing I can think of without using a table would be to use a clearfix. It is really used/created for element with floating children (in order to give them a correct width/height.. floating elements do not normally effect the containers dimensions) but it also will work in this case.
<body>
<div class="clearfix">
<div style="float:right">Stay right</div>
<div style="white-space:nowrap; clear:both; font-size:2em">
Wide child element which determines the width of the page.
</div>
</div>
</body>
EDIT: I lied, I came up with a second (better) way but it does require a more modern browser. It is to use a wrapper with a display: inline-block OR display: table. It really is just a sub-set of the clearfix but will work if you can get away with being IE8+ based.
<body>
<div style="display:inline-block">
<div style="float:right">Stay right</div>
<div style="white-space:nowrap; clear:both; font-size:2em">
Wide child element which determines the width of the page.
</div>
</div>
</body>
NEVER wrap an entire page in a table. It messes up your HTML since about the year 2000.
I think you want a fixed position for your div, it lines up the element with the window instead of the page:
.myDivThatFloatsRight {
position: fixed;
top: 10px;
right: 10px;
}
I have a div containing elements with display set to inline-block. These contained elements have various heights. The resulting lines in the div have various heights, according to the heights of the elements in them. This is as I want it. But I want to add some space between the lines in the div. For example, elements in adjacent lines with background color set should have a visible gap between them. The common advice for a paragrpah is to set line-height, but this sets the same height for all lines in the div, which I don't want. Is there a way to set a space between the lines without making all the lines the same height and without modifying the contained elements?
In a simplified form the HTML content looks like this:
<div>
<div style="display: inline-block;...">variable stuff</div>
<div style="display: inline-block;...">variable stuff</div>
<div style="display: inline-block;...">variable stuff</div>
<div style="display: inline-block;...">variable stuff</div>
...
</div>
Each inner div has different content: different height and width.
I can style all the inner divs. Pragmatically, I have already done that and have a result I could live with. But I was surprised to see that CSS doesn't have an obvious way to set line spacing (i.e. the space between lines, as opposed to the height of lines: I know about line-height but it is not, directly, line spacing and has the (undesired in this instance) effect of making all the lines the same height - even the lines where all the elements in the line have a low height). I am curious to know if there is a way to set line spacing as a parameter of the outer div, without setting the line height.
I think of it as line spacing, but another way to think of it is top and bottom margin on each line in the outer div, rather than on the outer div as a whole, and without overriding the top and bottom margins of all the inner divs (which is what I have done for now) or making all the lines the same height (as line-height does).
The only way I can think of to do it without overriding the margins of the inner divs, is by wrapping each in another div, simply to set a common margin. If I do it this way, the margins of the two divs don't collapse, which I can live with. This works well enough in this case, where all the content is divs, but it wouldn't work if I had mixed text and divs (i.e. text interspersed with divs), in which case I would be back to wishing I could find a way to specify line spacing.
What about using the css padding property? For Example:
padding:25px;
You can also specify: padding-right, padding-bottom, etc.
Why not try CSS margin or border settings on your P elements?
That can only be done using margin style. You don't need to wrap each contained DIVs with another DIV. Just use the STYLE tag.
Here's an example. Border and colorings are added for demo purpose.
<style>
#container {width:30ex; outline:1px solid black; padding:0 .2em; background:white;}
#container>div {display:inline-block; margin:.2em 0; background:#fca;}
</style>
<div id="container">
<div style="height:1em">variable</div>
<div style="height:5em">variable stuff variable</div>
<div style="height:2em">variable stuff</div>
<div style="height:1em">variable</div>
<div style="height:3em">variable stuff variable stuff</div>
<div style="height:1em">variable</div>
<div style="height:1em">variable</div>
<div style="height:1em">variable</div>
<div style="height:1em">variable</div>
</div>
Whats about to use columns with inline-block and in each column are more divs.
<div>
<div style="display: inline-block;">
<div>variable stuff</div>
<div>variable stuff</div>
</div>
<div style="display: inline-block;">
<div>variable stuff</div>
<div>variable stuff</div>
</div>
</div>
I have a div with overflow: auto. Suppose I want to put an arbitrary number of div elements inside it such that there is no line wrapping (the additional elements spill into the hidden area and can be scrolled to).
If I knew how wide all those elements would add up to be, I could do this:
<div class="scrollable">
<div class="fixed-width-container">
<!-- elements float left or display inline-block -->
</div>
</div>
Can I get this effect without knowing the total width of the contained elements?
UPDATE #2
Check updated fiddle: http://jsfiddle.net/cyCY3/2/
UPDATE
Check fiddle: http://jsfiddle.net/cyCY3/
Specifying a fixed width and white-space: nowrap for the child elements should solve the issue.