ChatGPT解决这个技术问题 Extra ChatGPT

How to make an inline-block element fill the remainder of the line?

Is such a thing possible using CSS and two inline-block (or whatever) DIV tags instead of using a table?

The table version is this (borders added so you can see it):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head></head>
<body>
<table style="width:100%;">
<tr>
<td style="border:1px solid black;width:100px;height:10px;"></td>
<td style="border:1px solid black;height:10px;"></td>
</tr>
</table>
</body>
</html>

It produces a left column with a FIXED WIDTH (not a percentage width), and a right column that expands to fill THE REMAINING SPACE on the line. Sounds pretty simple, right? Furthermore, since nothing is "floated", the parent container's height properly expands to encompass the height of the content.

--BEGIN RANT-- I've seen the "clear fix" and "holy grail" implementations for multi-column layouts with fixed-width side column, and they suck and they're complicated. They reverse the order of elements, they use percentage widths, or they use floats, negative margins, and the relationship between the "left", "right", and "margin" attributes are complex. Furthermore, the layouts are sub-pixel sensitive so that adding even a single pixel of borders, padding, or margins will break the whole layout, and send entire columns wrapping to the next line. For example, rounding errors are a problem even if you try to do something simple, like put 4 elements on a line, with each one's width set to 25%. --END RANT--

I've tried using "inline-block" and "white-space:nowrap;", but the problem is I just can't get the 2nd element to fill the remaining space on the line. Setting the width to something like "width:100%-(LeftColumWidth)px" will work in some cases, but performing a calculation in a width property is not really supported.

I don't think there is a sane way to do this except turning this into a display: table-* construct which will work, but isn't really "more semantic" either (being a terrible case of div soup) and breaks IE6 compatibility. I personally would stick with the <table>, unless somebody manages to come up with a genius simple idea that works without
Yeah. I keep running into all these "avoid tables" arguments from the dawn of the CSS age, and they're worded to make you sound like an incompetent lazy moron if you still use tables for layouts. Fast forward a decade, and it's still an idealistic pipe-dream. The fact is, flow layout semantics SUCK for fixed-but-flexible layouts like user interfaces and forms. The truth is that smart people will use tables where convenient, because they've exhausted every possible CSS solution and realized that they're all imperfect and significantly more complex than just using a table.
Floats? Show me working code, where end-of-line elements don't line-wrap unpredictably and borders and margins don't break the layout. That's what's wrong with them. Also, does the automatically-sized parent container properly expand to encompass floating elements with out the "clear fix" hacks? I didn't think so.
If you've got at least one non-floated element in your parent container, then it's not really a "hack" to clear floats, now is it? Remember that CSS has its roots in printing - see css-tricks.com/containers-dont-clear-floats for a good discussion of why you don't get auto-clearing.
@Triynko: This is what I made earlier: jsfiddle.net/thirtydot/qx32C - I think it hits most of your points. I'll hear your critique of that demo I did, and try to fix it afterwards.

T
TylerH

See: http://jsfiddle.net/qx32C/36/

.lineContainer { overflow: hidden; /* clear the float */ border: 1px solid #000 } .lineContainer div { height: 20px } .left { width: 100px; float: left; border-right: 1px solid #000 } .right { overflow: hidden; background: #ccc }

left
right

Why did I replace margin-left: 100px with overflow: hidden on .right?


Can you get this to work if the second div element is instead an input text field ?
@tribalvibes: Like this? Or maybe this?
Overflow hidden is not a solution. Suppose you don't want the overflow of the right container hidden. This doesn't make the size of the right container fill the remaining space on the line. This is an example of a two-year-old question that I still haven't marked an answer for, because there's still no satisfactory answer.
Triynko: even though you're using 'overflow:hidden', nothing will generally be hidden (at least if you just have text in there). The text/elements inside the div will be arranged so that they fit inside the div (unless you have an element that is larger than the div, of course).
@RMorrisey: Probably just needs some box-sizing: border-box on the divs. Just a guess, since you didn't provide a demo showing the behaviour you describe. That being said, the display: table-based solution is usually better. This is a very old question, but I think I was trying to avoid anything to do with tables in this question due to behaviour of OP.
P
Panu Horsmalahti

A modern solution using flexbox:

.container { display: flex; } .container > div { border: 1px solid black; height: 10px; } .left { width: 100px; } .right { width: 100%; background-color:#ddd; }

http://jsfiddle.net/m5Xz2/100/


display flex and width 100% .. gotta remember
when using flex, why not use flex: 1 instead of width: 100% ?
For those new to flexbox: flex: 1 is shorthand for flex-grow: 1. It's a combination attribute: flex: <grow> <shrink> <basis>.
Just a quick note that display: flex is unsupported in IE < 11, and very buggy in 11.
@EricShields this shouldn't prevent anyone from using Flexbox. Nowadays we have flexbugs you know.
F
Frosty Z

Compatible with common modern browers (IE 8+): http://jsfiddle.net/m5Xz2/3/

.lineContainer { display:table; border-collapse:collapse; width:100%; } .lineContainer div { display:table-cell; border:1px solid black; height:10px; } .left { width:100px; }

left
right


The argument against using tables has nothing to do with its presentation characteristics. It has to do with unmanageable markup, style/document muddling, and improper semantics. None of these arguments applies to display:table.
This doesn't answer how to make inline-block fill the remainder of the line.
@TranslucentCloud I agree that my answer does not exactly answers the question title, but it provides a way to fill the available width using divs, as asked in the question body.
I like this solution a lot. You're not force to use some weird stylings which araise from hidden CSS logic (like for overflow hidden).
S
SuperIRis

You can use calc (100% - 100px) on the fluid element, along with display:inline-block for both elements.

Be aware that there should not be any space between the tags, otherwise you will have to consider that space in your calc too.

.left{
    display:inline-block;
    width:100px;
}
.right{
    display:inline-block;
    width:calc(100% - 100px);
}


<div class=“left”></div><div class=“right”></div>

Quick example: http://jsfiddle.net/dw689mt4/1/


V
Vladislav Kovechenkov

I've used flex-grow property to achieve this goal. You'll have to set display: flex for parent container, then you need to set flex-grow: 1 for the block you want to fill remaining space, or just flex: 1 as tanius mentioned in the comments.


C
Chris Forrence

If you can't use overflow: hidden (because you don't want overflow: hidden) or if you dislike CSS hacks/workarounds, you could use JavaScript instead. Note that it may not work as well because it's JavaScript.

var parent = document.getElementsByClassName("lineContainer")[0]; var left = document.getElementsByClassName("left")[0]; var right = document.getElementsByClassName("right")[0]; right.style.width = (parent.offsetWidth - left.offsetWidth) + "px"; window.onresize = function() { right.style.width = (parent.offsetWidth - left.offsetWidth) + "px"; } .lineContainer { width: 100% border: 1px solid #000; font-size: 0px; /* You need to do this because inline block puts an invisible space between them and they won't fit on the same line */ } .lineContainer div { height: 10px; display: inline-block; } .left { width: 100px; background: red } .right { background: blue }

http://jsfiddle.net/ys2eogxm/


F
Fanky

When you give up the inline blocks

.post-container {
    border: 5px solid #333;
    overflow:auto;
}
.post-thumb {
    float: left;
    display:block;
    background:#ccc;
    width:200px;
    height:200px;
}
.post-content{
    display:block;
    overflow:hidden;
}

http://jsfiddle.net/RXrvZ/3731/

(from CSS Float: Floating an image to the left of the text)


c
chowey

If, like me, you want something that will expand to the end of the line even if the left-hand box wraps, then JavaScript is the only option.

I'd make use of the calc feature to get this right:

Array.from(document.querySelectorAll(".right")).forEach((el) => { el.style.width = `calc(100% - ${el.offsetLeft + 1}px)`; }); .container { outline: 1px solid black; } .left { outline: 1px solid red; } .right { outline: 1px solid green; }

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin tristique aliquet quam, at commodo lorem fringilla quis.