I have very simple example of an un-ordered list with a black border, and one of its child elements hidden: http://jsfiddle.net/spryno724/Sm9Lx/1/. Notice how the hidden child element is considerably wider than the visible element, but the container only scales to the width of the visible child.
Is there a way within CSS to automatically scale the width of this container to the width of its widest child element, even if that element is hidden?
I know that this is possible with JavaScript, but I would like to avoid a scripting hack and go straight CSS, if possible.
Also, I'd like to avoid setting a specific width because in my actual application, my container will contain visual objects of unknown widths.
Thank you for your time.
use visibility: hidden; rather than display: none; on the hidden li
visibility: hidden; retains the elements space
display: none; acts as if the element doesnt exist in the markup
How about:
<li style="visibility: hidden; height: 0;">This is not the first list element, ok?</li>
Instead of display: none you can use opacity: 0
Related
Assuming I have 2 elements on a responsive design like this:
<div id="container">
<div class="first"></div>
<div class="second"></div>
</div>
both of them with style contains:
width: auto;
display: inline-block;
float: left;
And because I'm expecting different screen sizes to view page, so, according to screen size, sometimes they will be rendered/displayed on the same row, and sometimes they will not!, the second DIV will be moved to a separate row.
So, I'm wondering, how can I check if they are on the same line with JavaScript?
Thank you
"on the same line" would require inline elements or floating block elements of the exact same height. DIVs are block elements by default. So either use <span> tags instead of <div>, or add display: inline-block;to the CSS rule of those DIVs
ADDITION after EDIT OF QUESTION:
width: auto for a <div> means 100% of the parent element (in this case full width). As I wrote: If you have blocks, use display: inline-block; in their CSS. If you want them to have the same height, put them into a common container DIV (which you already have) and apply the following CSS:
#container {
display: table;
}
.first, .second {
display: table-cell;
width: 50%;
}
Aha (edited question), Javascript: Well, read out the DIV widths, add them and compare the result to the (read-out) container width.
You can use the element bounding boxes and check for overlap:
var rect1 = $('.first')[0].getBoundingClientRect();
var rect2 = $('.second')[0].getBoundingClientRect();
var overlaps = rect1.top <= rect2.bottom && rect2.top <= rect1.bottom;
This checks for any overlap which will probably be sufficient for your use. I used jQuery to get the elements but you can use pure js in the same way, it would just be a bit more verbose.
There is no concept of line on a page. You can check the x and y position of any element in the window and then decide if that meets whatever criteria you have for "on the same line".
By default, a div is the full width of a window so the two divs inside your container in this HTML:
<div id="container">
<div class="first"></div>
<div class="second"></div>
</div>
will be one above the other unless there is some other CSS you have not disclosed that controls the layout to allow them to be in the same row. If they are indeed width: auto and don't have any other layout rules affecting this, then they will each be full width and thus first will be above second in the layout stream. They would never be "on the same line" by any typical definition of that phrase.
Feel free to try it out here: https://jsfiddle.net/jfriend00/y0k7hLr8/ by resizing the right pane to any width you want. In all cases, the first will stay on top of the second.
If, on the other hand, you allow the div elements to have a different type of layout such as let them be display: inline-block and define a width for them, then the layout engine will fit as many on a given row as possible like here: https://jsfiddle.net/jfriend00/229rs97p/
Something tells me display: flex might help you in this. Read https://css-tricks.com/snippets/css/a-guide-to-flexbox/ for more info.
I want to embed a dropdown div in a wrapper div that has 0 height, so that it takes no space whether or not it is shown, and when it is shown, it overlays the contents placed below. Suppose that dropdown element is a div with content Foo. I did something like:
HTML
<div class="dropdown_wrapper">
<div id="dropdown_content">Foo</div>
</div>
CSS
.dropdown_wrapper{
height: 0;
overflow: visible;
}
And through Javascript, I switched the #dropdown_content's style between display: block and display: none. When it is the former, I expect the content to be shown, but it is actually not shown, hidden within the wrapper div that has 0 height.
How can this be fixed?
you probably do not want the wrapper to use any space in the document. to use it as an anchor point use
position: absolute;
overflow: visible;
on the wrapper. this way the content will set it's own bounding box.
the rest seems to work as you intended. check this FIDDLE
I have a couple of d3.js animations on-screen at the same time, each governed by CSS display: flex; and flex: nowrap; directives, the only telling difference between the problematic one (which wraps) and other, correctly-displayed (ie non-wrapping) animations being that:
because it has non-svg header and text input elements, it comprises anchoring div or section elements. (As I understand, these, being block-level, theoretically occupy the entire available display width, and so have, in the css file, been 'overridden' with the setting display: inline;.
overflowing svg path elements, whose length has now been physically curtailed so as to match the limits of the containing svg:svg element.
Frustratingly, the animation steadfastly refuses to be governed by the flex: nowrap; directive.
The question:
Is there a general approach to ensuring that flex row nowrap behaviour is determined by what is actually visible on-screen, and not by containing (or sibling) block-level elements such as section or div, or wider but overflow: hidden; child svg lines or path content?
Note: other questions/answers on this topic relate to text, not section, div or svg.
All animations are theoretically governed by the parent flex-flow: row nowrap; setting.
The associated widths are such as to allow plenty of free space around each.
It would be nice to think the parent flex-flow: row nowrap;, taken together with the svg:svg element's overflow: hidden; and the block-level display: inline; CSS settings would be enough to ensure that no wrapping occurs. I have checked in the inspector, and all dimensions displayed lie within limits required for flex-flow: row nowrap;.
The only elements in play are section (or div), text, svg, g, input, ul and li. In practice, something is leading to unwanted wrapping. My feeling is that the block-level elements are the source of the problem. Can you suggest a strategy to avoid this?
Failing this, are there alternatives I can use as containers for text input elements which are less likely to cause problems?
Once again, the answer arrived during sleep.. :-)
Firstly, use of display: inline; on block-level elements seems not, at least in this situation, have the effect on width claimed by some bloggers (in fact tends to pollute the parent flex context).
This in turn led to a search for alternative inline elements to replace div or section. On substituting the inline element span in place of the block-level elements div or section, the desired nowrap behaviour immediately took effect, but in turn knocked out my (now local) vertical block layout. This was restored using display:inline-block; on the containing span, so:
originally (somewhat simplified):
---------- header
/
div--- svg:g -- svg:svg (with overflow:hidden;)
\
---------- user text input area
..which, despite a parent nowrap directive, was caused to wrap by the div (or other block-level) element.
now:
---------- header
/
span-- svg:g -- svg:svg (with path extents matching those of svg:svg container)
\
---------- user text input area
..whereby span has the css display:inline-block; directive set on it and a width specified. Here, the parent flex nowrap directive was adhered to, but locally (ie inside the span) the block layout is applied.
I would like to be able to insert an element that a user can navigate (left) to without disturbing what the user currently sees. that is, the new element will be inserted offscreen, to the left, but the currently "focused" element (and the other visible ones) shouldn't be seen to move.
Currently I am doing this using insertbefore, measuring the clientWidth of the new element and subtracting that from the margin of the container element. However, clientWidth is expensive to get, and this method is proving problematic when I add transitions. Is there a cleverer way to do this? I would have thought it's a fairly common problem - insert an element before another without shifting everything else.
You could use some CSS to achieve this. Insert a wrapping div with no height, but overflow: visible, insert the elements you want inside this div:
.wrapper {
height: 0;
overflow: visible;
}
.wrapper div {
margin-left: 100%;
}
It is quite easy to make two div overlap when the size of the container div is known but what if the div heigh cannot ?
I tried to do it without manipulating container height:
http://jsfiddle.net/AJfAV/
But #text2 go over #text3 and do not "push" it.
How can the #container be resized automatically ?
I manage to achieve my goal using jquery ui but I feel this is not an elegant solution:
http://jsfiddle.net/AJfAV/6/
Is this what you need?
Updated fiddle:
I'm setting height to the default, auto, using jQuery, like this:
$("#container").css("height", "auto");
You can also set: height: auto; in CSS.
Do you need position:absolute? You can use absolute positioning if you don't want to do any arrangement, but a placement. The absolute positioning takes an element completely out of the flow of elements. They know nothing of its existent.
You may use floats and a technique to enclose floats. I'm using clear:
.cl-left {
clear: left;
height: .1px;
font-size: 0;
line-height: 0;
}
Don't forget to add <div class="cl-left"> </div>.
In addition, a negative margin is used. Therefore, #text2 is nailed to the right.
http://jsfiddle.net/AJfAV/7/
this can be solved if you removed absolute positioning of #text1 and #text2.
and make #text2 overlap #text1 by making both float:left and set margin-left:-30px for #text2.
now let's test it: http://jsfiddle.net/RPe4H/
the problem now is that when #text1 is toggled, #text2 will float to top left of #container, this happening because JQuery set display:none on the element when toggling is done.
now to solve this, put #text1 and #text2 inside containers with same width, so #text doesn't affect the flow when it is set to display:none, also you must set min-height:1px on the container of #text1.
now it is working as expected http://jsfiddle.net/MyyF6/1/