In my application a user is able to input text and click a button to append a new 'span' to the DOM (within a container) containing their inputted text. I want these spans to have as much width as needed to fit the given user inputted text (you can assume the user wont input something longer than the container's width). I would also want the container to fit as many spans as possible within in a row; and if a span needs more room than is left in the current row -> go to the row below (see the last two lines of the picture).
What kind of CSS would I need to add to my container as well as the spans within it to achieve the organization below?
Please Note: the width of this container is fixed, but the height grows as needed to fit new text filled spans
As per you mockup, You can achieve your task by two way:
Use flex CSS3 property
Use CSS3 property width auto and float left in span class.
let span class="class-name"
.class-name {
display: inline-block;
width: auto;
float: left;
}
In this span class, you can add more property as per your need.
To do this with the CSS3 flex property:
.container {
display: flex;
border: 1px solid red;
width: 20rem;
flex-wrap: wrap; /* otherwise it will try to fit everything on one line */
justify-content: space-between; /* alternatives are space-evenly or space-around*/
}
see this pen, with flex you have the advantage that you have better control over how this width of the container is uses, with the float solution you cannot justify the content, it will all stick to the left and leave unused space on the right.
Related
I want the table height to fit the parent’s available height. Ideally, I want:
The footer to always be docked at the bottom of the parent container.
If the table contains a few rows, the footer should remain docked at the bottom.
If the table contains more rows than fit the parent’s height and needs to overflow then the overflow should be visible only for the table body, and the footer should remain docked at the bottom and not be pushed downwards.
A flexbox approach if possible (it seems to me that this is a flex scenario)
What I don’t want:
A height: 100vh approach
A calc (100vh - ***px) involved (because I want to use the methodology in arbitrary component hierarchies inside my solution)
Fixed heights in the table
To use absolute/fixed positioning
No 3rd party solutions (if possible)
To use .offsetHeight
Example: https://stackblitz.com/edit/react-8h5dpy
Visual Examples:
Growing an item to take all available space but not exceeding the height of the parent could work like follows:
.parent {
// use flexbox layout for children
display: flex;
flex-direction: column;
}
.childThatGrows: {
// take as much space as available
flex-grow: 1;
// don't take more space than available (elements are as high as their content by default)
min-height: 0;
overflow: scroll;
}
Why min-height: 0? See https://stackoverflow.com/a/36247448/3066632.
For your example this might look like this: https://stackblitz.com/edit/react-wgbzpb.
I have a fixed size container in which I wish to display variable-length multiline text with known font size, line height, etc.
If the text fits inside the container: it is centered vertically
If it does not fit inside the container:
Any overflow is hidden om a per-line basis (i.e. so that last line is either fully displayed or hidden but not half-hidden)
Text is displayed from the start (instead of only the middle portion showing up due to vertical centering)
An ellipsis is appended to the text (either real one or fake one via CSS hack)
As a bonus, if there are more dynamic solutions with scrolling text or "Read more..." auto-inserted via JavaScript, please mention these to or post a link.
The solution should work or at least have graceful fallbacks for older browsers starting from IE9 (don't care about older versions of IE).
Example usage: comment inside a fixed-size speech bubble:
EDIT:
I suppose I could use
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
line-height: #line-height; /* fallback */
max-height: #max-height; /* fallback */
-webkit-line-clamp: #line-number; /* number of lines to show */
-webkit-box-orient: vertical;
But, first of all, it's webkit-only. And secondly and more importantly, how do you then center text vertically when it does fit inside the container?
You should be able to use the text-overflow: ellipsis; property in your css for this. As far as vertically align, I always recommend flexbox and using display: flex; with align-items: center.
EDIT: Flexbox does not work in IE9. In that case, I would recommend wrapping the text in another div and giving it margin: auto; That will put it in the middle of the div.
I have the following CSS code written;
#container {
width: 1300px;
background-color:green;
margin:0 auto;
overflow:hidden;
}
#menu {
float:left;
width:20%;
background-color: yellow;
}
After searching google for a long time I couldn't find an explaination why the container background color is disappearing when the container overflow attribute is visible.
Can someone help me understand why ?
Update:
Thanks alot for your answers.... :)
I don't mind using overflow:hidden, ijust want to understand its purpose and how to use it.
As i unserstand, the overflow property specifies what happens if content overflows an element's box, so i dont understand why would its visibilty make the container background color disappear or why would it change the container height.
Since the elements within the container are have float:left - the container had a height of 0 - which is also what is causing you not to see any background.
In order to fix this there are a few solutions out there:
One of them is called clearfix
<div id="container" class="clearfix">
<!-- floated elements here -->
</div>
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
Another is by setting overflow:hidden on the container element - this establishes a new block formatting context - which in effect clears the floats. (See this post)
From the spec:
Floats, absolutely positioned elements, block containers (such as
inline-blocks, table-cells, and table-captions) that are not block
boxes, and block boxes with 'overflow' other than 'visible' (except
when that value has been propagated to the viewport) establish new
block formatting contexts for their contents.
In a block formatting context, boxes are laid out one after the other,
vertically, beginning at the top of a containing block. The vertical
distance between two sibling boxes is determined by the 'margin'
properties. Vertical margins between adjacent block-level boxes in a
block formatting context collapse.
In a block formatting context, each box's left outer edge touches the
left edge of the containing block (for right-to-left formatting, right
edges touch). This is true even in the presence of floats (although a
box's line boxes may shrink due to the floats), unless the box
establishes a new block formatting context (in which case the box
itself may become narrower due to the floats).
This is because of the floating child element. If your container only contains floated elements, its height will be equal to zero.
You need to include a clear element, different possibilities exists:
The Empty Div Method: By adding a <div style="clear: both;"></div> as latest child element.
The Overflow Method: By setting an overflow: hidden on the container element
The Easy Clearing Method: By adding extra CSS and a class on the parent element (clearfix')
.clearfix:after {
content: ".";
visibility: hidden;
display: block;
height: 0;
clear: both;
}
It is happening because you have not given any height to #menu.
As, #container has height of #menu, background is not visible.
Give some height to it.
#menu {
float:left;
width:20%;
background-color: yellow;
height:50px;
}
DEMO here.
You can set the height of the container div to be equal with the height of the menu. This way you don't need the overflow: hidden setting.
$("#container").height($("#menu").height());
Demo here: http://jsfiddle.net/er144/ZV6pb/
I have a table where users input data into columns. Each time the user enters data a new column is created. After a while they have a TON of columns and I need them to wrap.
I know how to wrap the text inside the columns, but I need the entire column to wrap below the first column and so on.
You shouldn't use tables for this.
You should use divs with "float: left" CSS style.
Here is a working example: http://jsfiddle.net/3MEJ5/
Instead of using table columns, try having each input data be a table on its own, wrapped inside a <div class="datainput">, using the following CSS:
.datainput {display: inline-block; vertical-align: top;}
Now, instead of adding a new column, duplicate the container. This will place it next to the existing ones, and wrap if/when needed.
Should it fail to wrap, apply this CSS to the element containing all these containers:
word-break: break-all;
it is actually not simple. The table/row/column structure is quite rigid. To achieve what you describe, you have to create each cell as a single-celled table in a giant outer cell. Then they will wrap. But then, they may not align well.
A good solution for this now is to use CSS3 Columns.
You can set the CSS properties on the container and the children will flow down and across.
You have the options:
div {
/* Make columns with a min width of 100px, create multiple columns as space permits */
column-width: 100px;
column-count: 3; /* Divide the text in a <div> element into three columns */
column-gap: 40px; /* Specify a 40 pixels gap between the columns */
/* Specify the width, style, and color of the rule between columns */
column-rule: 4px double #ff00ff;
}
For more details see: https://www.w3schools.com/cssref/css3_pr_columns.asp
For browser support see: https://caniuse.com/#search=css3%20columns
I am making a horizontal content slider, and need to put an arbitrary number of equally-sized elements in a row inside the slider div, so i can shift the slider div back and forth and display one element at a time on the page. These elements could be anything: divs, imgs, whatever.
Currently I am floating all the elements, and in order to prevent them from dropping onto the next row, using javascript to sum up the widths of all the elements on page load and manually fix the width of the slider in order to fit all of them.
Naturally I do not want to do this. I have looked at the CSS Flexible Box Model and it seems it would do what i need, but it does not appear very often outside of the W3C specification and i'm not sure how well supported it is. Does anyone have any experience using it? Apart from that, is there any other non-javascript way of lining up a bunch of divs side by side and having the parent expand laterally to fit?
Flexbox isn't really standardised or widely-supported enough to use yet. It's supported in newer browsers including IE10, but it's likely to be a long time before that's your baseline.
There are some ways to work around it. For example you can use white-space: nowrap to make inline children not fall down to the next line, in combination with float: left to make the parent shrink-wrap its width around the children. Then if you want the children to be stackable blocks you could use tables or inline blocks:
#slider { white-space: nowrap; float: left; border: dotted blue 1px;}
#slider .box { display: inline-block; width: 100px; border: dotted red 1px; }
<div id="slider">
<span class="box">foo</span
><span class="box">bar</span
><span class="box">bof</span
><span class="box">zot</span
>...
</div>
(Using <span> is needed for inline-block in IE7, and the odd > placement is to prevent unwanted whitespace between the boxes.)
As you may have seen, every browser may render things differently, but if you apply the style display:inline; to the elements in the slider, and width:auto; to the container element, they should not wrap.