How to force child element adherence to `flex: nowrap;` CSS directives - javascript

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.

Related

How to check if 2 elements displayed on the same row?

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.

"Priority Nav" breaks when div is floated

I'm using the "Priority Navigation" design pattern. For those who aren't quite sure what this is, basically when the viewport width is reduced and there isn't enough space for all the list-items to fix horizontally, they're moved into another nested list so they can still be accessed. This is within a "more" link at the end of the list.
At a basic level, this works fine in my example (below):
http://codepen.io/moy/pen/RrRJBe
The problems I'm having are:
1) Because I have another item alongside the navigation, which is floated (and of unknown width), I needed to set overflow:hidden; on the nav. This means when the width of the container changes, the nav stays alongside the other content rather than dropping onto the next line. It's fixes that ...the problem is it also means the dropdown on the end isn't visible as it's displayed below the navigation and overflow: hidden; is set.
Any alternative (CSS) fixes for this?
2) Another issue is the nav links need to be positioned to the right. No problem, just float the div right, yeah? Unfortunately it doesn't like this and the page almost crashes - must be something to do with the script trying to calculate the widths? As soon as the nav or it's parent is floated, it breaks!
The list-items are floated left so they display horizontally. Instead I tried using display: inline-block and text-align: right;. This positions the text correctly but when there's not enough horizontal space the items either wrap or all collapse into the "more" link rather than one-by-one.
-
Browser requirements: It's worth noting that my browser support is IE8+, so flexbox is unfortunately out the window. Even if it worked, it would mean that I'd have to find a fix for IE8/9.
Is anyone able to help with this, or maybe there's a plug-in I should take a look at. This script works great when the nav is isolated but as soon as another item is in it's path it becomes a bit tricky. On a previous attempt I got the width of the item which was in the way and subtracted it for the available space. But that isn't that flexible/scalable - but that again, maybe there isn't another way?
Thanks, hope someone can help!
Part 1
You can use clearfix instead of overflow: hidden.
Add the following to the parent element containing nav:
.wrap:before, .wrap:after {
content: '';
display: table;
clear: both;
}
But if you need to support IE8, you can just add element like below to the bottom of the parent element containing nav
html
<div class="clear"></div>
.clear {
clear: both;
}

What is the difference between visibility:collapse and display:none? Which one is the preferred? [duplicate]

What is the difference between visibility:collapse and display:none?
Short version:
The former is used to completely hide table elements. The latter is used to completely hide everything else.
Long version:
visibility: collapse hides an element entirely (so that it doesn't occupy any space in the layout), but only when the element is a table element.
If used on elements other than table elements, visibility: collapse will act like visibility: hidden. This makes an element invisible, but it will still occupy space in the layout.
display: none hides an element entirely, so it doesn't occupy any space in the layout, but it shouldn't be used on table elements.
W3C Reference
visibility: collapse behaves exactly like visibility: hidden in most formatting contexts: the space required by the element is 'reserved' in the layout, but the element itself is not rendered, leaving a blank space where it would have been.
There are three exceptions that I know of: table-rows, table-columns and flex items, in which visibility: collapse behaves like display: none, but with one major difference: the 'strut'. You can think of the strut as a zero-sized placeholder, that doesn't claim any space of its own in the layout process, but is nevertheless still part of the formatting structure and participates in some size computations.
A collapsed table-row, for example, will not occupy any vertical space in the table, but the table columns will still be dimensioned 'as-if' the collapsed row and its contents were actually visible. This is to prevent columns from 'wobbling' as rows are toggled in and out. Likewise, a collapsed flex item doesn't occupy any space along the main axis, but still contributes to the flex line cross-size.
'Do not use display: none with tables' is a valuable rule of thumb, but it doesn't tell the whole story.
Use display: none if you don't want your hidden elements to participate in any way in the table (or flex line) layout process.
Use visibility: collapse if you want to dynamically show and hide elements without destabilizing the table (or flex line) layout.
Here is a code snippet demonstrating the difference between display: none and visibility: collapse for a table row:
.show-right-border {
border-right: 1px black solid;
}
<h3>visibility: collapse</h3>
<table class="show-right-border">
<tr>
<td>Short text.</td>
<td style="visibility: collapse;">Loooooooooong text.</td>
</tr>
</table>
<h3>display: none</h3>
<table class="show-right-border">
<tr>
<td>Short text.</td>
<td style="display: none;">Loooooooooong text.</td>
</tr>
</table>
visibility:collapse should only be used on tables. On other elements it will act as a visibility:hidden.
visibility:hidden hide the element but still take the space of the element whereas display:none won't even keep the space.
Resources :
w3schools.com - visibility
w3schools.com - display
On the same topic :
What is the difference between visibility:hidden and display:none
CSS Properties: Display vs. Visibility
CSS display:none and visibility:hidden
Does opacity:0 have exactly the same effect as visibility:hidden
visibility:collapse has a display:none behavior only for table elements. On other elements, it should render as hidden.
You can also apply visibility: collapse on an element under a flexbox container (a flex item). It will act as you're applying it on an element with display: table-row or display: table-column

CSS positioning full width and height of multiple elements

Good evening gentlemen (and of course ladies),
I'm currently experiencing some problems with CSS and the dynamic positioning of some elements in one big container. And I hoped that anyone of you could probably know the solution for my problem.
Maybe I just start with the explanation, which I will split in three parts to make it easier to understand. In the end of this post, there are two links, one for the steps to visualize them and one for the example jsfiddle for step two.
Step one:
There is one div.container which has the height 255px and a dynamic width of 33.3%. This container contains two divs: div.left and div.right. The div.left has exactly 150px width, which should bring the div.right to fill up the whole remaining space.
I already tried to solve it this way, which works, but not for the next steps.
.left {
float: left;
width: 150px;
}
.right {
overflow: hidden;
}
Step two: Now, there should be three different elements in the div.right, a h3, span and p element. The h3 and span should just behave like a regular element, and use the space they want to use (like for displaying text). But the p element should take the whole remaining height of the div.right. I achieved this single step by using the code in the jsfiddle link in the end of this post. And it looks really cool, but it's not compatible with the next step. As you maybe already guessed it.
Step three:
As the p.description element contains a description, I want to put as much information into this small element as possible. Therefor, I hoped to use overflow:hidden in combination with text-overflow:ellipsis, but this didn't work. Due to some strange reason, the p.description element was placed right of the h3 and span elements after I added the overflow:hidden style.
And additionally, there is an extra div in the footer of the div.right, which is div.btns. This div contains about 3 plain links and is placed absolutely in the right bottom of div.right, and I only want to have the p.description element to wrap the text around it.
Right now, I doubt, that all of these steps are solvable by only using css. At least, I wanted to have the positioning of the elements with css and the truncating of the text could be done in Javascript.
Is there anybody out there, who has an idea, how I could solve my problem?
Many thanks in advance!
Attachments:
All three steps in one picture: http://cl.ly/image/2t2a3o3o2l0s/steps.png
JsFiddle for step two: http://jsfiddle.net/S8g4E/1188/
Check this Jsfiddle: http://jsfiddle.net/Mohamed_nabil/7btp2/
In css: the max-height of the ellipsis in lines(52 & 61) are now 200px,
this can be changed with jQuery if you want to, on window resize or load.
max-height: 200px; /*This value could be changed with jquery*/

How can I dynamically resize a DIV element's width to fit its text content?

Let say I have this HTML code snippet:
<div id="container">
<div id="textContent">Text Content Te</div>
<div id="anotherText">Another Text Content</div>
</div>
Original HTML output http://img26.imageshack.us/img26/1571/beforeeffect.gif
I wonder how I could dynamically resize the div's textContent width so that it fits its text content nicely (neither the text will be wrapping nor scrolling nor truncated).
Desired HTML output http://img26.imageshack.us/img26/5851/desiredeffect.gif
I am open to any solution using CSS and/or JavaScript.
I wonder how could I dynamically
resized the div's width to fit the
text content (without wrapping)?
Assuming the content would fit without overflowing, you could use a float without a width set (width isn't required in CSS 2.1 or greater). Without more detail, I can't suggest where to put it or what other properties to set to get the desired effect (eg, floats float down around following content, so put it at the beginning of a paragraph).
If you're not concerned with the effect looking perfect on old browsers like Internet Explorer, you could use display: table or display: table-cell, with the caveat that tables don't overflow: they stretch. That stretching may be desirable if you want to avoid overflow of your div, but allow it to overlow the viewport -- eg, a film strip that scrolls horizontally. In that case, altCognito's suggestion of white-space: nowrap would be very useful.
<style>
div {
white-space: nowrap;
}
</style>
This will do the trick (though you probably should be more specific about the divs that you want to change. This means the divs that you do use this on won't have any line feeds unless you specify them yourself. But I'm guessing you're using this for labels, so you should be all set.
See an example.

Categories