Vertical-centering and overflow Excel-style in CSS? - css

Is there a way to perform a vertical centering of a variable-sized multi-line content within a fixed-size div, with hidden overflow?
The aim would be to reproduce what you can see in Excel cells: when the content fits the container, it should be vertically centered, when it is larger, the parts that overflow should be hidden (and the content still vertically aligned), like in an Excel cell whose neighbours aren't empty.
I know how to vertically center using CSS, I know how to hide overflow when the content isn't vertically centered, but I've no idea how to do both at the same time... Is Javascript the only answer?
The trick is that CSS positioning approaches don't work with variable-sized content (my content is dynamic text), and when you use display:table-cell, it effectively disables CSS overflow control (and the container grows to accomodate the content).

This should make all the cells 65px high, and make the cells' text show up in the middle. When it's too much text, the text disappears bellow.
I believe it's what you want?
CSS:
.row {
border: solid 1px blue;
display: block;
height: 65px; /* arbitrary value */
overflow: hidden;
line-height: 65px; /* same as height */
}
.cell {
border: solid 1px #CCCCCC;
display: inline-block;
vertical-align: middle;
height: 100%;
}
.cellContents {
display: inline-block;
max-height: 100%;/*would 100%; work?*/
width: 100px; /* arbitrary value */
overflow: hidden;
border: solid 1px red; /* just to see that it's centered */
line-height: 100%; /* so it does not inherit the huge line-height, and we get more than one line of text per cell */
}
HTML:
<div class="table">
<div class="row">
<span class="cell"><span class="cellContents">cell 1 1</span></span>
<span class="cell"><span class="cellContents">cell 1 2</span></span>
<span class="cell"><span class="cellContents">cell 1 3</span></span>
</div>
<div class="row">
<span class="cell"><span class="cellContents">cell 2 1</span></span>
<span class="cell"><span class="cellContents">This should make all the cells 65px high, and make the cells' text show up in the middle. When it's too much text, the text disappears bellow.</span></span>
<span class="cell"><span class="cellContents">cell 2 3</span></span>
<span class="cell"><span class="cellContents">cell 2 4</span></span>
</div>
</div>
You can try it on JSFiddle.

Related

Why is the min-height not overriding the height?

this is my first post on stack overflow so I hope I'm doing it right, but I'm having this css problem on the home page of a website I'm creating where it has different sections and I want to make it so that the height of the sections are 80vh but will have a min-height of fit-content so that the content is never cut off if it exceeds 80vh height. However, it seems as if the min-height is not overriding the height and the section height is not big enough to fit the content.
here's the html and css for the section it is not working with:
<section class="home-section" id="home-shopcontact">
<div id="home-shopcontact-container">
<div id="home-shop" class="home-shopcontact-card">
<div class="home-shopcontact-card-content content-div">
<h1>See Something You Like?</h1>
<ul>
<li>Prints available for A5 to A1.</li>
<li>Optional bespoke framing.</li>
<li>Original handmade works.</li>
<li>Commissions.</li>
</ul>
<form action="shop.html">
<button class="pink-button">SHOP</button>
</form>
</div>
</div>
<div id="home-contact" class="home-shopcontact-card content-div">
<div class="home-shopcontact-card-content content-div">
<h1>Get in Touch.</h1>
<ul>
<li>Commission work.</li>
<li>General enquiries.</li>
<li>Any related questions.</li>
</ul>
<form action="contact.html">
<button class="pink-button">CONTACT ME</button>
</form>
</div>
</div>
</div>
</section>
here's the css:
.home-section {
border: 6px solid red;
min-height: fit-content;
height: 720px;
}
#home-shopcontact-container {
border: 6px solid blue;
display: flex;
gap: 3.125rem; /* 50px */
justify-content: center;
flex-wrap: wrap; /* when the cards are too big on the screen to both fit on the same line, move it underneath */
padding: 3rem; /* so it doesnt touch the edge of the screen so you can see the cards clearly */
}
.home-shopcontact-card {
position: relative; /* so I can position the link buttons relative to the card */
box-sizing: border-box; /* so the padding doesnt affect the size of the cards */
border: 1.5px solid var(--theme-grey);
min-width: fit-content; /* make sure that the cards have at least enough width to display the content */
min-height: fit-content;
width: 34.375rem; /* 550px */
height: 42.5rem; /* 680px */
border-radius: 50px;
padding: 2.8125rem 0 2.8125rem 0; /* 45px padding at the top and bottom of the card */
overflow: hidden; /* done this to make the transparent background not overflow with the rounded corners */
}
here's what it comes out looking like:
(hopefully you all can see that)
the red border shows the parenting section div and the blue border shows the content container div. My real question boils down to - why is the min-height not ensuring that the height of the red bordered section div is at least big enough to fit the content? You can see the blue bordered content div overflow underneath.
Any help would be greatly appreciated, sorry if I missed important details and if I have please let me know and i'll get it for you. Thanks! :D
If I`ve undestanded correctly, you want to create a section with height: 80vh, but if the content of the section is bigger than 80vh the section must to grow. Is this? If Yes, you must to do this in your section: height: fit-content; min-height: 80vh

Center a div, expand sibling divs to remaining space

I'm attempting to center a div and fill in to the left and right with divs.
The center div will be text of variable length, and the sibling divs will be lines filling in the available space.
Here's what I envision it looking like:
Here's the markup:
<div class='heading'>
<div class='lines'></div>
<div class='heading-link'>
<a>Link Text</a>
</div>
<div class='lines'></div>
</div>
<div class='heading'>
<div class='lines'></div>
<div class='heading-link'>
<a>Really Long Link Text that is still centered</a>
</div>
<div class='lines'></div>
</div>
Here's the barebones css:
.lines {
display: inline-block;
border-top: 1px solid #2c2c2c;
border-bottom: 1px solid #2c2c2c;
}
.heading {
text-align: center;
display: inline-block;
}
.heading-link {
display: inline-block;
}
The key point is that the text in .heading-link is variable in length, and I would like the .lines divs to fill the remaining space to the left and right of .heading-link
I don't want to set a percentage width on .heading-link because I don't know how wide the text will be. Should I be using a table based layout? Or just inlined divs?
Solution Using CSS Tables
The following might be close to what you need.
Your HTML is good as is:
<div class='heading'>
<div class='lines'></div>
<div class='heading-link'><a>Link Text</a></div>
<div class='lines'></div>
</div>
<div class='heading'>
<div class='lines'></div>
<div class='heading-link'> <a>Really Long Link Text that
is still centered</a></div>
<div class='lines'></div>
</div>
Try the following CSS:
.heading {
text-align: center;
display: table;
margin: 30px 0; /* for demo only */
}
.lines {
display: table-cell;
width: 48%; /* the exact value is not that critical... */
border-top: 1px solid #2c2c2c;
border-bottom: 1px solid #2c2c2c;
}
.heading-link {
display: table-cell;
white-space: nowrap; /* keeps the text from wrapping... */
padding: 10px 20px; /* for demo only, as needed... */
}
How This Works
Apply display: table to the parent container .heading, and then display: table-cell to the child elements .lines and .heading-link.
I am using the table display type to take advantage of the auto-sizing features of table cells.
I am assuming that your .heading-link text will fit on one line, so I force the text to stay on a single line by using white-space: nowrap. This will force the .heading-link element to expand to contain the text. You can use padding to control the white space as needed.
For the left and right .lines elements, set the with to be something like 48%. This will keep force the left and right .lines elements to compute to the same width, half of whatever space remains after the space used up by .heading-link.
You can also specify an overall width to .heading if needed.
Demo Fiddle: http://jsfiddle.net/audetwebdesign/eyGdG/

How to vertically align div in another div with text?

I'm trying to center a div vertically in a parent div, where text is present. Here's what I've got:
It looks a little funny because the text seems to be centered properly, but the yellow boxes aren't. This is how I'm doing it:
.btn {
background-color: #ccc;
color: #000;
width: 200px;
border: solid 1px black;
text-align: center;
vertical-align: middle;
display: table-cell;
}
.square {
background-color: #ff0;
width: 20px;
height: 20px;
display: inline-block;
}
.inner {
display: inline-block;
}
<div class="btn">
<div class="square"></div>
<div class="inner">Hello</div>
<div class="square"></div>
</div>
Should my usage of "table-cell" + vertical-align be working? I only care about html5, I'm really just targeting the latest versions of mobile safari, so don't have to worry about older browsers etc.
Here's a js fiddle of this:
http://jsfiddle.net/TrJqF/
Thanks
Set vertical-align:top on the square class. The extra space comes from space reserved for descendant text elements like j, g, y etc. that drop below the line.
jsFiddle example
Actually there is no difference between both the height. Apply yellow background color to inner class and see the difference in explicit and no height.
both square div doesn't have content and inner div have content. The css box aligning by itself based on its content. Add empty space to the square div as follows:
<div class="btn">
<div class="square"> </div>
<div class="inner">Hello</div>
<div class="square"> </div>
</div>
If you want you can add top and bottom margin 1 or 2 pixel which will show your expectation.

CSS min height not working

I have a large div that I want to put content in. I want the div to be padded and have a minimum height so that if there is too much text in the div it expands down to maintain the padding. But I also don't want it to get less than 100px in height. Currently, when I run this code, some of the text falls outside of the div.
HTML:
<div id='content'>
<div>lots of text in here</div>
</div>
CSS:
#content {
position: relative;
margin-left: auto;
margin-right: auto;
border: 1px solid gray;
min-height: 100px;
width: 800px;
padding: 60px;
}
Well, try to use paragraphs in your HTML, instead of duplicating divs. It does not work because the duplicate div is not styled in your CSS.
<div id='content'>
<p>lots of text in here</p>
</div>
If this solves your problem, feel free to accept this answer.
You can add height:auto; to your css, it may help.

How to make <div> inline? All <div>, even when their total width more than width of their parent?

I need to make <div> displayed inline and hide them with "overflow: hidden" for their parent.
Width for <div> is set to 20% with "box-sizing" property, so they are exactly 20% of their parent width.
The usual method, using "float: left" doesn't help, because it makes only 5 <div> displayed in one line, and the rest of them shown in new line under the first 5 <div>.
How to make all <div> displayd inline and hide the rest of them if they are too wide to be shown inside of their parent, using "overflow: hidden"?
I have the following document structure:
<body>
<div class="column">
<div class="header">Some text</div>
<ul class="item_list">
<li class="simple">Some text<br></li>
<li class="simple">Some text<br></li>
<li class="simple">Some text<br></li>
...
</ul>
</div>
You can see what I mean here. But I've made it using javascript (setted for <div> "position: absolute" and generated "margin-left" for each elemet) and it causes great problems for future development.
DEMO: http://jsfiddle.net/marcuswhybrow/7YDfE/3/
Use display: inline-block and white-space: nowrap in combination:
<div class="wrapper">
<div class="inline"></div>
<div class="inline"></div>
<div class="inline"></div>
</div>
Then use the appropriate CSS:
div.wrapper {
width: 200px; /* or whatever */
overflow: hidden;
white-space: nowrap;
}
div.inline {
display: inline-block;
}
The demo contains a little jQuery animation to illustrate the effect:
DEMO: http://jsfiddle.net/marcuswhybrow/7YDfE/3/
If the div elements are display: inline then applying white-space: nowrap; to the parent element will prevent their wrapping to new lines.
Since you have a known number of divs, have you tried using absolute positioning instead of floats, and specifying left:20% left:40%, etc.?
If you set the container div's height to a fixed value, and give all the inner elements display: inline-block, this should do the trick. inline-block will make each element align to the left, but keep it's dimensions, while the fixed height container will hide any that overflow to a new line.
This will do what you want with the addition of removing the white space between while allowing nice code formatting. The container gets font-size:0px ftw.
Markup
<div class="wrapper">
<div class="inline">Some text </div>
<div class="inline">Some sample text </div>
<div class="inline">Some Other text </div>
</div>
CSS
div.wrapper {
width: 250px; /* or whatever */
overflow: hidden;
white-space: nowrap;
border: 1px solid red;
font-size:0px;
}
div.inline {
display: inline-block;
width: 80px;
height: 20px;
background-color: black;
color:white;
margin: 0; padding: 0;
border: 1px solid blue;
font-size:12px;
}

Resources