Chrome 100% width and 100 vw overflow [duplicate] - css

This question already has answers here:
How to remove the space between inline/inline-block elements?
(41 answers)
Closed 5 years ago.
Here's a repro.
Padding off, margins off, I don't see what's causing the space circled below. I'm using normalize, it doesn't matter. I get that the vertical scroll bar changes things, but shouldn't 100% width fix this?
The screenshot is using canvas width, max-width 80% and the right hand is allowed to size by the browser. If I set to 20% it wraps below.
Update: For those too lazy to click the repro link, here's a similar snippet:
.model-div {
background: black;
display: inline-block;
height: 100vh;
max-width: 80%;
width: 80%;
}
.ui-console {
display: inline-block;
height: 100vh;
max-width: 20%;
width: 20%;
}
<body>
<div class="model-div"></div>
<div class="ui-console">
<button class="reset" onclick="model.fReset()">Reset</button>
<button class="blind-mode" onclick="model.fToggleBlind()">Toggle Blind Mode</button>
<div class="log-text-div"></div>
</div>
</body>

Browsers detect ANY amount of whitespace as 1 space, therefore it prints a space between the two items, thus causing the second item to fall. (Unless you use a workaround.)
Possible solutions:
1.Eliminate your whitespace inside your HTML. The easiest way to do this is to use something to minify your HTML, which honestly is a good practice anyway.
2.Set the font-size of your parent to zero
Parent (body, in your example.)
.parent{
font-size:0;
}
Children
.parent>*{
font-size:16px;
}
3.Float the children (Bootstrap does this in v3, before it switched to flexbox.)
.model-div,.ui-console{
float:left;
}

Related

Grow to fit available space, then eagerly wrap text instead of expanding parent [duplicate]

This question already has answers here:
How to match width of text to width of dynamically sized image/title?
(2 answers)
Closed 6 months ago.
Consider the example below, a tooltip or modal or something outside the normal layout flow where the container is able to grow, but should shrink to fit its contents. Here I would like the header (blue) to fit on a single line, (greedily) expanding the parent. That is, to behave like it normally would. But the "body text" (red) should only grow to fill the available space and then (eagerly) wrap the text.
Unfortunately there seems to be no obvious CSS property to express eagerly wrapping text layout.
article {
position: absolute;
background: whitesmoke;
padding: 1em 2em;
}
header {
color: blue;
}
main {
color: red;
}
<article>
<header>This should expand parent to fit.</header>
<main>This should use available space, but wrap instead of expanding parent.</main>
</article>
PS: This might just be my search or problem description skills being terrible, but I've not found anything even describing this problem, let alone the solution. Please link anything you can find that is related to this.
One trick I stumbled upon is to set min-width: 100% and then set max-width to the actual minimum value.
min-width: 100%;
max-width: min-content; /* or even 0 */
You might think that setting max-width: 100% as well would work. Nope! I'm guessing because 100% then would refer to the width after its "preferred" width has been applied.
I would love a proper explanation of why this works, but my understanding of it is simply that max-width overrides the internal "preferred" width, and then min-width overrides max-width. Seeing as this is CSS, I'm sure it's much more complicated though :)
article {
position: absolute;
background: whitesmoke;
padding: 1em 2em;
}
header {
color: blue;
}
main {
color: red;
min-width: 100%;
max-width: min-content;
}
<article>
<header>This should expand parent to fit.</header>
<main>This should use available space, but wrap instead of expanding parent.</main>
</article>

For a CSS flexbox, allow an element to shrink to minimum(its intrinsic width, an absolute length) [duplicate]

This question already has answers here:
Flexbox children shrink up to a certain point (but don't expand if they don't need to)
(3 answers)
Closed 2 years ago.
I have a box that displays a number of text elements, one after the other along a row. I do not want the text within each element to wrap. Instead if there is insufficient room then it should truncate the text and show an ellipse.
This is easy to obtain using display: flex, and allowing each element to shrink to zero.
But the smaller elements are shrunk so much that the text almost completely disappears. In that case I would rather shrink the smaller elements a little less, and shrink the bigger elements more. This can also be obtained by giving each element a bigger min-width (say 100px) so that it cannot shrink beyond a certain point.
My problem occurs when one of the text element's intrinsic width is already smaller than 100px. Since I just specified that the element had a longer min width, the browser leaves extra space after the element. I don't want that extra space.
I would prefer not to use java-script. I'm seeking a solution using CSS. It's so close that I feel that it should be possible, but none of my attempts have come out correctly.
If I knew in advance which text elements were tiny, then I can specify that the tiny elements should not flex at all, and get the desired outcome. But without using javascript I do not know which elements are tiny.
If I could set the min-width of an element to the minimum of its intrinsic width and 100px then I would get the desired outcome. Although CSS does have a min() function which may be used for min-width, unfortunately it appears that I am not allowed to use max-content as an argument to that function.
The description of min-width on MDN (https://developer.mozilla.org/en-US/docs/Web/CSS/min-width) states that fit-content(100px) is a syntactically valid way of specifying the min-width. I hoped to craft an element whose minimal content size is zero, and max size is the text element's intrinsic length. Then fit-content(100px) would either be 100px, or if that's larger than the intrinsic length, the intrinsic length. But whenever I use fit-content() with an argument the browser says that the expression is invalid.
Finally I tried to use a grid display. But then fit-content() either uses the intrinsic width or 100px, but does not expand further. I tried experimenting with minmax with no luck (it seems I cannot put fit-content() as an argument to minmax()). Besides I do not know the number of text elements, but a grid display wants me to specify that number so I don't think a grid can be made to work.
So is there any way to obtain the desired outcome using just CSS. Since this text is for an Electron program, I only care about Chrome as a browser. I have an example below showing each of my attempts.
main {
display: flex;
flex-direction: column;
width: 600px;
border-style: solid;
border-color: black;
border-width: 1px;
}
span {
background-color: skyblue;
padding: 10px;
margin: 0 10px 10px 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex: 0 1 auto;
}
section {
width: 100%;
display: flex;
}
.set-min-width span {
min-width: 100px;
}
.set-min-width .no-shrink {
flex: none;
min-width: initial;
}
.use-max-expression span {
min-width: min(100px, max-content);
}
.use-fit-content div {
flex: 0 1 auto;
min-width: fit-content(100px);
display: flex;
}
.use-fit-content div span {
min-width: 0;
}
.use-grid {
display: grid;
grid-template-columns: fit-content(100px) fit-content(100px) fit-content(100px);
}
.use-grid span {
min-width: 0;
}
<main>
<h4>The hidden overflow allows each text item to shrink to nothing<br> Both small and medium elements are heavily truncated<br></h4>
<section>
<span>Medium length</span>
<span>Tiny</span>
<span>Longer text that has to be truncated to fit within the section. It is far far far far too big to fit.</span>
</section>
<h4>By setting a min-width to 100px I can control truncation of medium element. But the tiny element now has extra space after it that I do not want.</h4>
<section class="set-min-width">
<span>Medium length</span>
<span>Tiny</span>
<span>Longer text that has to be truncated to fit within the section. It is far far far far too big to fit.</span>
</section>
<h4>1: This is what I want.<br> But to obtain it I had to specify a different style for the tiny element so that it would not flex. But I don't know in advance which elements are tiny.</h4>
<section class="set-min-width">
<span>Medium length</span>
<span class="no-shrink">Tiny</span>
<span>Longer text that has to be truncated to fit within the section. It is far far far far too big to fit.</span>
</section>
<h4>2: I want the min-width to be the element's max-content if this is smaller than the truncation limit<br> `min(100px, max-content)` would return the correct result, but it is not valid CSS and so is ignored</h4>
<section class="use-max-expression">
<span>Medium length</span>
<span>Tiny</span>
<span>Longer text that has to be truncated to fit within the section. It is far far far far too big to fit.</span>
</section>
<h4>3: I tried to use fit-content(arg)<br> The inner element has min-width 0, so its min-content size should be 0<br> Its max-content size is the intrinsic width of the text<br> So the fit-content(100px) size should be 100px if that's smaller than intrinsic
width, or the intrinsic width otherwise.<br> Despite MDN stating that fit-content with argument is valid CSS for min-width, the browser rejects `fit-content(100px)`</h4>
<section class="use-fit-content">
<div><span>Medium length</span></div>
<div><span>Tiny</span></div>
<div><span>Longer text that has to be truncated to fit within the section. It is far far far far too big to fit.</span></div>
</section>
<h4>4: Using fit-content(100px) in a grid does not work either. The elements are indeed not expanded if natural width is smaller than 100px. But the elements do not flex to take rest of space.<br> Besides a grid won't work because the number of columns is
not known in advance.
</h4>
<section class="use-grid">
<span>Medium length</span>
<span>Tiny</span>
<span>Longer text that has to be truncated to fit within the section. It is far far far far too big to fit.</span>
</section>
</main>
I was giving this a little play around and this was the best I could come up width. The problem that I can see is that flex-box is terrible for not obeying boxes without setting its inner elements with a max-width of some kind. There is a few other answers I found on Stackoverflow but none of them seem to really fix what you are asking for. In my answer I used max-width on the spans, along with text-overflow: ellipsis and overflow: hidden to create something close to what you had requested.
code below and codepen - here https://codepen.io/rl4444/pen/oNLQVRr?editors=1100
HTML
<main>
<h4>my solution</h4>
<section class="box-items">
<span>Medium length</span>
<span>Tiny</span>
<span>Longer text that has to be truncated to fit within the section. It is far far far far too big to fit.</span>
</section>
</main>
CSS
main {
max-width: 600px;
width: 100%;
border-style: solid;
border-color: black;
border-width: 1px;
position: relative;
box-sizing: border-box;
}
span {
background-color: skyblue;
padding: 10px;
margin: 0 10px 10px 0;
white-space: nowrap;
text-overflow: ellipsis;
max-width: 300px;
}
section {
display: flex;
box-sizing: border-box;
max-width: 100%;
}
.box-items span {
border: 1px solid red;
overflow: hidden;
}

Flexbox layout wider than browser [duplicate]

This question already has answers here:
CSS: Width in percentage and Borders
(5 answers)
Closed 2 years ago.
expected output: A horizontal line, and the word "testing" below, with no horizontal scrollbar.
actual output: A horizontal line with the word "testing" below, but there a horizontal scrollbar, which can be used to move roughly 5px, regardless of browser width.
This is the minimum code required to reproduce the problem:
body {
margin: auto;
display: flex;
flex-direction: column;
}
hr {
min-width: 100%;
}
<html>
<body>
<section>
<hr>
<span>
testing.
</span>
</section>
</body>
</html>
As you can see with "run snippet", you can scroll to the right and make the "t" in testing partially off the page.
Questions:
Why? How do I make a flexbox layout that uses only the width of the browser? I thought that adding body { width: 100vw;} would help, but it doesn't appear to change anything.
How can I debug this behavior without asking SO for help? If I take away any of the CSS lines, the problem disappears, but so does the formatting I desire, so I can't say which of them is at fault. How could I figure out what the problem is on my own?
First of all: your flex layout is working fine! The issue lies within the <hr> element, which sneakily takes up some horizontal space. It has borders on both sides – 1px each.
Here are three different solutions, take your pick!
Get rid of the borders
hr {
min-width: 100%;
border-left: none;
border-right: none;
}
Subtract the border widths from the total
hr {
min-width: calc(100% - 2px);
}
Change the element's box-sizing
hr {
box-sizing: border-box;
min-width: 100%;
}

Create a div with angled side [duplicate]

This question already has answers here:
Create a slanted edge to a div [duplicate]
(5 answers)
Closed 3 years ago.
Let's say I have a container div with two divs inside. This is the effect I want to get:
<div>
<div></div>
<div></div>
</div>
In addition, I need it to be responsive, width and height in % or viewport units. And I need to fill them with various content, some content might even be partially hidden under one of these divs.
Unfortunately CSS is not THAT advanced re: skew affecting child elements... I am sure what you are looking for is that the content will wrap at the angle that you have created there... I agree that the only way is as #user5151179 pointed out, with the 2D transforms... Just check for browser compatibility with this (There's no easy solution for solving this for all and every browser as you would know).
I think the easiest way would be for you to add a background image to the outer div, and have two rectangular divs where you can add content etc. inside the outer div, thus your text not wrapping at an angle, if that makes sense.
Try the following
<div class='container'>
<div class='div div1'>
</div>
<div class='div div2'>
</div>
<style>
.container{
height:50px;
width:100px;
position:relative;
overflow: hidden;
}
.div1 {
background: none repeat scroll 0 0 #0000FF;
left: -8px;
}
.div2 {
background: none repeat scroll 0 0 #000000;
right: -7px;
}
.div{
width: 57px;
top: -10px;
transform: rotate(20deg);
position: absolute;
height: 72px;
}
There is no css method to do it. But we can do it by some css tricks like what i did above.

css: how to center box div element directly in center? [duplicate]

This question already has answers here:
How to center an element horizontally and vertically
(27 answers)
How can I horizontally center an element?
(133 answers)
How can I vertically center a div element for all browsers using CSS?
(48 answers)
Closed 3 years ago.
when i use top:50% and left:50%
the box is not directly in center. of course when the box is very small, it appears to be centered. but when box is a bit big, it looks as if it's not centered.
how can i resolve this ?
top and left correspond to the top-left corner of your box. What you're trying to do is have them correspond to the center. So if you set margin-top and margin-left to negative of one-half the height and width respectively, you'll get a centered box.
Example for a 300x200 box:
width: 300px;
height: 200px;
top: 50%;
left: 50%;
margin-left: -150px;
margin-top: -100px;
using translate will perfectly achieve that. simply apply this
div.centered {
position: fixed; /* or absolute */
top: 50%;
left: 50%;
/* bring your own prefixes */
transform: translate(-50%, -50%);
}
source
Horizontal: Use a fixed width and
margin-left: auto;
margin-right: auto;
vertical: That's not that easy. You could use
display: table-cell
for the surrounding DIV and then give it a
vertical-align: middle
You can assign the box a fixed width and heigth, and then give it's margin-top and margin-left properties the negative half of the height and width.
EDIT: Example
div.centered {
width: 500px;
height: 400px;
top: 50%;
left: 50%;
position: absolute;
margin-top: -200px;
margin-left: -250px;
}
One way is to assign a specific width to the box, then halve the remaining distance on each (left and right) side. This may be easier if you use percentages instead of pixel widths, e.g.,
<div style="margin-left:25%; margin-right:25%">...</div>
This leaves 50% width for the div box.
The very bizarre CSS "language" does not provide a simple way to center a element in the screen. Kludges must be made! This is the only solution I came to elements that are AUTO in both height and width. Tryed in FF19 (Win+Mac), CH25 (Win+Mac) and IE9.
.overlay {
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
background-color:#eee; /* aesthetics as you wish */
}
.overlay .vref { /* it is a vertical reference to make vertical-align works */
display:inline-block;
vertical-align:middle; /* this makes the magic */
width:1px;
height:100%;
overflow:hidden;
}
.overlay .message {
display:inline-block;
padding:10px;
border:2px solid #f00; /* aesthetics as you wish */
background-color:#ddd; /* aesthetics as you wish */
vertical-align:middle; /* this makes the magic */
max-width:100%; /* prevent long phrases break the v-alignment */
}
<div class="overlay">
<div class="vref"> </div>
<div class="message">whatever you want goes here</div>
<div class="vref"> </div>
</div>
body { text-align: center; }
#box {
width: 500px; /* or whatever your width is */
margin: 10px auto;
text-align: left;
}
The above would centre your box centrally horizontally on the page with a 10px margin at the top and bottom (obviously that top/bottom margin can be altered to whatever you want). The 'text-align' on the body is required for IE, which as usual doesn't quite get the hang of it otherwise. You then need the left text-align on your box (unless you want text it in centred too) to counteract the text-align center on the body.
Trying to centre vertically is just about impossible using pure CSS though. Though there's a vertical-align in CSS, it doesn't work like the HTML vertical align in tables, so in CSS 2 there's no in-built vertical align like the HTML one. The problem is that you're dealing with an unknown height - even if you know the height of your box, the height of the page is unknown, or rather what are you trying to fix the box in the centre of? The page? The viewport? The visible screen area's going to be different for everyone, depending on their screen resolution, browser, and all of the browsers interpret the height differently.
There are various methods that claim to have solved the problem, but usually they don't reliably work in all browsers. I found this one the other day, which doesn't seem bad, but it doesn't work in Google Chrome (works in Firefox and Opera, but I didn't get chance to check out IE). There's an interesting discussion on the problem though on this thread on Webmaster World that summarises the various methods and pros and cons of them and is well worth a look.
Edit:
Dav's solution in the first response works okay as long as you (or the visitor to the site) don't increase the font size or line height. The container will be centred, but as soon as the font size is increased or more content added, it'll overflow the container.

Resources