Update
Note: Primarily targeting Chrome (and maybe Firefox) for an extension. However, open to suggestions for a universal solution.
Additional Information
Note: Discovered that lack of spaces in text for A
causing overflow issues with B
. Situation seems more complex than anticipated. Updated code now allows user input. Test sample without spaces.
I have a fixed positioned box with full width and fixed height placed within a dynamic environment.
+-----------------------------+
| |
| |
[=============================] << The box.
| |
| |
...
<- dynamic width ->
The box consists of two key elements A and B. B
takes priority in width and is responsible for accommodating its content within the given height, avoiding greedy behavior. A
fills the remaining space greedily. When there is text overflow in A, ellipsis should be added, which is where I'm encountering challenges.
Here are some examples:
1. B occupies designated space, A expands to fill width.
+-------------------+--------+
| A________ | __B___ |
+-------------------+--------+
2. A overflows with ellipsis.
+-------------------+--------+
| A_____________... | __B___ |
+-------------------+--------+
3. B grows, A shrinks.
+----------------+-----------+
| A__________... | __B______ |
+----------------+-----------+
After experimenting with various techniques like floats, absolute positioning, and others, I arrived at utilizing a table layout in CSS as my chosen approach. Other methods didn't produce the desired effect. If anyone has alternative solutions, please feel free to share.
The main challenge lies in implementing ellipsis when A overflows.
Is there a way to modify how A
is structured to achieve this?
Sample code:
Please disregard the JavaScript, it serves as a tool for displaying overflow visually. (Convenient feature while editing in Firefox's Style Editor)
/* Code may seem messy with unconventional variable usage. */
function Hack() {
var x = 0,
n = 150,
wrap = document.querySelector('#wrap'),
left = document.querySelector('#left'),
right = document.querySelector('#right'),
txt = document.querySelector('#txt'),
ent = document.querySelectorAll('.entry'),
log = document.querySelector('#log'),
run = document.querySelector('#run'),
rt = document.querySelector('#rt'),
samp = document.querySelector('#sample'),
t = samp.value
;
this.rt = parseInt(rt.value) || 1000;
function getComp(e) {
var x = window.getComputedStyle(e, null);
return ''+
~~(parseInt(x.getPropertyValue('height'))) + 'x' +
~~(parseInt(x.getPropertyValue('width')))
;
}
this.status = function () {
log.textContent = 'Height / Width for:\n' +
' wrap : ' + getComp(wrap) + '\n' +
' left : ' + getComp(left) + '\n' +
' right : ' + getComp(right) + '\n' +
' sample: ' + getComp(txt) + '\n'
;
}
/* Switch between long and short text in sample cells. */
this.flip = function () {
txt.textContent = x ? t : (new Array(n)).join(t);
Array.prototype.forEach.call(ent, function (e) {
e.textContent = x ? 'abc' : 'abcabc';
});
x ^= 1;
this.status();
}
/* Toggle auto run. */
this.update = function () {
t = samp.value;
this.rt = parseInt(rt.value);
if (!this.rt || this.rt < 10)
rt.value = this.rt = 100;
clearInterval(this.ttt);
if (run.checked)
this.ttt = setInterval(this.flip.bind(this), this.rt);
}
document.addEventListener('click', this.flip.bind(this));
run.addEventListener('click', this.update.bind(this));
rt.addEventListener('change', this.update.bind(this));
samp.addEventListener('keyup', this.update.bind(this));
this.update();
}
window.addEventListener('load', function () {
var hack = new Hack();
hack.flip();
});
* { margin : 0; padding : 0; }
#log { margin : 5pt; border : 1px solid #ccc; }
#filler { margin-top : 90px; height : 2000px; background : #efefef; }
label,
input { cursor : pointer; }
/* inner elements of cells in right -- (B) */
.hdr,
.entry { padding : 2px 5px; }
.hdr { font-weight: bold; }
#wrap { /* the red thing -- aka (the box) */
position : fixed;
top : 135px;
height : 23px;
background : #600;
color : #999;
height : 20px;
width : 100%;
display : table-row;
}
#left { /* the green thing -- aka (A) */
background : #044;
display : table-cell;
width : 100%;
}
#txt { /* sample text in left */ /* Where I want ellipsis */
display : block;
height : 20px;
width : 100%;
overflow : hidden;
text-overflow: ellipsis;
}
#right { /* the purple / blue thing -- aka (B) */
background : rgba(0,0,200,.5);
height : 20px;
display : table-cell;
width : 100%;
white-space: nowrap;
}
<p>Click document to expand text, or auto-run:</p>
<div>
<input type="checkbox" id="run" checked /><label for="run">Change every </label>
<input type="number" id="rt" value="1000" step="100" /> millisecond.
Sample text: <input type="text" value=" sample" id="sample" />
</div>
<pre id="log"></pre>
<!-- The box -->
<div id="wrap">
<div id="left">
<span id="txt">sample <!-- ellipsis here --> </span>
</div>
<div id="right">
<span class="hdr">Foo</span><span class="entry">abcd</span>
<span class="hdr">Bar</span><span class="entry">abcd</span>
</div>
</div>
<!-- End of File: The box -->
<div id="filler">dummy filler page height</div>