css grid stretch row contents to fit parent container - html

Is there a way to get grid items to stretch the length of the parent container? I cannot for the life of me figure it out.
basically im trying to build a calendar with grid because idk it seemed like the best option. ive got the 7 columns and they stretch the width of the parent container. however, the grid rows do not. i've tried loads of potential solutions from SO and other places but none of them seem to work.
setting days height:100%; causes it to stretch too far down the page and overflow, which is undesirable. if i take that out, then they don't fill in the space and just bunch up. ideally I would like 7 x 5 with square boxes, but at this point i'll take evenly spaced rectangles. what am I doing wrong or misunderstanding?
here's a snippet: (css is scss)
.main-container {
display: flex;
width: 100%;
height: 100%;
}
.calendar {
background-color: transparent;
width: 100%;
height: 100%;
//remove italics is for testing. delete after done
font-style: normal;
position: relative;
}
.month {
padding: 7rem 10rem;
width: 100%;
background: #eee;
text-align: center;
}
.month ul {
display: flex;
justify-content: space-between;
list-style: none;
& a{
color: #222;
text-decoration: none;
}
}
// use grid 7 x 5 (modify for february in js)
.weekdays {
background: #222;
color: #eee
display: grid;
grid-template-columns: repeat(7,1fr);
list-style: none;
text-align: center;
font-weight: bold;
}
.days {
list-style: none;
text-align: center;
font-weight: 200;
text-decoration: none;
background: #eee;
display: grid;
grid-template: repeat(5,1fr) / repeat(7,1fr); // rows / columns
justify-content: stretch;
width: 100%;
height: 100%;
position: absolute;
& > li {
background: #www;
height: 100%;
}
}
<div class="main-container">
<div class="calendar">
<div class="month">
<ul>
<li class="prev">&#10094</li>
<li>August<br><span style="font-size:18px">2020</span></li>
<li class="next">&#10095</li>
</ul>
</div>
<ul class="weekdays">
<li>Monday</li>
<li>Tuesday</li>
<li>Wednesday</li>
<li>Thursday</li>
<li>Friday</li>
<li>Saturday</li>
<li>Sunday</li>
</ul>
<ul class="days">
<li>1</li>
<li>2</li>
<li> 3</li>
<li> 4</li>
...
<!--and so on-->
logic is: wrap all the grid containers in a flex item because flex is the "layout" and grid is the organisation.

I figured out a solution that worked. I added a display:flex and set it to column in a parent element but I forgot where because I was just trial and erroring a lot of things. I think it was the calendar element since that's not in the OP. it gave me this output which is what I was looking for (sorry for the colours).

Related

html css full width, images only, resizable horizontal menu

I' trying to make a horizontal menu with special conditions
these are the rules I have to stick with:
html + css
menu should resize to the width of the container (100% of container).
so the wider the container the bigger (height, width) the menu
menu elements are images with different width
every image(menu element) is close to the next and previous (no gaps in between)
all dimensions should be expressed in % (no fixed size)
the code:
<div id="menu-container">
<ul>
<li><img src="myImg01"></li>
<li><img src="myImg02"></li>
<li><img src="myImg03"></li>
</ul>
</div>
css
#menu-container{
width:100%;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
display: table;
}
li {
display: table-cell;
}
li img{
width:100%;
}
this works in firefox and safari
does not in chrome and similar... (it seems like all images are scaled in different %)
I've searched and did not found a similar issue
could you help please?
Will try to clarify.
I need that all images retain their aspect ratio even after scaling
you should add max-width in your div , and make display flex wrap
hay I hope this example will be helpful, so try like this:
CSS
#menu-container{
width:100%;
border: 1px solid red;
}
ul {
margin: 0;
padding: 0;
display: flex;
align-items: center;
flex-wrap: nowrap;
list-style-type: none;
}
li {
width: 10%;
height: 0;
padding-bottom: 10%;
background-repeat: no-repeat;
/*background-size: contain;*/
background-size: cover;
background-position: center center;
}
li a {
display: block;
width: 100%;
height: 0;
padding-bottom: 100%;
}
HTML
<div id="menu-container">
<ul>
<li style="background-image: url(https://static.scientificamerican.com/sciam/cache/file/4E0744CD-793A-4EF8-B550B54F7F2C4406_source.jpg);">
</li>
<li style="background-image: url(https://www.afd.fr/sites/afd/files/styles/visuel_principal/public/2019-01-07-16-19/mangrove%20couv.jpg);">
</li>
<li style="background-image: url(https://blog.nationalgeographic.org/wp-content/uploads/2020/05/May-11_Dorset-heathland_shutterstock_1332881306_sml-1140x450.jpg);">
</li>
</ul>
</div>
You can CSS grid.
#menu-container {
width:100%;
}
ul.menu {
display: grid;
grid-template-columns: 1fr 25% 2fr; // You can use percentages or the fr unit It represents a fraction of the available space in the grid container (works like Flexbox’s unitless values).
list-style-type: none;
margin: 0;
padding: 0;
}

How to align one item on viewport center using flexbox or grid? [duplicate]

This question already has answers here:
Align 3 unequal blocks left, center and right
(4 answers)
Closed 3 years ago.
I am creating simple navigation with flexbox CSS3 and I have a list with 3 items but those items have not specified width. Now I want to have the middle item to be placed in the center of the viewport. When I have that kind of situation my middle li is not centered on the viewport. Is there any way to center one item and other elements to be relative to this item?
See the differences between first and second navigation. On second navigation when there is one item it's properly centered to the viewport. I want to center the first one like second. Li element with class middle must be at the center of the viewport.
EDIT
Some of the answers did the typical moving first and last LI to the edges of the UL LIST. That's not the point, MIDDLE li must be at the center of the viewport and first and last LI should have only paddings and width: initial
ANSWER
I cannot add answer here so I paste 'codepen' link with answer which I want to get
https://codepen.io/freestyle09/pen/xxxvwPm
UPDATED CODE
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
nav {
border: 1px solid red;
display: flex;
justify-content: center;
}
ul {
display: flex;
justify-content: center;
list-style: none;
border: 1px solid green;
width: 1200px;
}
ul > li {
padding: 20px;
white-space: nowrap;
border: 1px solid blue;
}
li:not(.middle) {
flex-basis: 0%;
flex-grow: 1;
}
nav .test {
display: flex;
justify-content: center;
width: 800px;
border: 2px solid pink;
padding: 20px
}
<nav>
<ul>
<li><span>Lorem ipsum sit</span></li>
<li><span>Lorem ipsum sit</span></li>
<li class='middle'><span>Vey long string, very very very long string</span></li>
<li><span>About</span></li>
<li><span>About</span></li>
</ul>
</nav>
<nav>
<div class='test'>
<p>Vey long string, very very very long string</p>
</div>
</nav>
I'm not entirely sure I understand what you're trying to accomplish but this sounds like maybe what you're after?
Addendum, you just described the purpose of a table for tabular data. Hope this helps, cheers!
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
nav {
border: 1px solid red;
}
ul {
display: table;
width: 100%;
list-style: none;
align-items: center;
border: orange 3px dashed;
}
ul > li {
display: table-cell;
text-align: center;
padding: 20px;
border: green 1px dotted;
}
ul > li:nth-child(odd) {
width: 20%;
}
<nav>
<ul>
<li>Lorem ipsum sit</li>
<li class='middle'>Vey long string, very very very long string</li>
<li>About</li>
</ul>
</nav>
<nav>
<ul>
<li>Vey long string, very very very long string</li>
</ul>
</nav>
On way to approach this is to give the li.middle element a higher flex-grow priority and a lower flex-shrink priority than the other li elements.
The style flex is a shorthand for:
flex-grow
flex-shrink
flex-basis
It will take flex values such as these:
flex: 1 1 20%; // flex-grow priority of 1, flex-shrink priority of 1, pre-flex starting width of 20%
flex: 2 0 60%; // flex-grow priority of 2, will never shrink, pre-flex starting width of 60%
Using these two values above we can declare that:
one class of element has a default width of 20% and can both grow and shrink to fill the width available
another class of element has a default width of 60%, is twice as likely to grow wider than the other elements, but can never shrink to less than 60%
Working Example:
nav {
border: 1px solid red;
}
ul {
display: flex;
list-style: none;
justify-content: center;
border: 1px solid green;
margin-left: 0;
padding-left: 0;
}
ul > li {
padding: 20px;
}
li {
border: 1px solid blue;
}
li {
flex: 1 1 20%;
}
li.middle {
flex: 2 0 60%;
text-align: center;
}
<nav>
<ul>
<li>Lorem ipsum sit</li>
<li class="middle">Very long string, very very very long string</li>
<li>About</li>
</ul>
</nav>
<nav>
<ul>
<li class="middle">Very long string, very very very long string</li>
</ul>
</nav>
Adding the following properties to your style should fix your problem.
ul > li {
padding: 20px;
flex: 1;
text-align: center;
}
That will set all the li element sizes to be equal and align their text to the center of it.

Header with three elements, one left, one center, one right

I'm just starting to develop in HTML and CSS, and despite reading about the box model I am still having trouble with some of the basics of positioning.
I want to create a header navigation bar with three elements - one to the left of the page, one to the right, and one in the center. I want these elements to be inline with each other.
At the moment, they are represented in HTML like so
<body>
<div class="header">
<ul class="child">
<li id="lodestone">The Lodestone</li>
<li id="mogstation">The Mog Station</li>
<li id="user">User Account</li>
</ul>
</div>
I have then attempted to align them using the 'text-align' property in CSS.
.header {
background-color: #ffd9e7;
border: black;
display: block;
box-sizing: border-box;
}
.header ul {
display: inline-block;
}
.header > ul > li {
display: inline-block;
}
#lodestone {
text-align: left;
}
#user {
text-align: right;
}
#mogstation {
text-align: center;
}
However, instead of the expected result it produces this.
The three items are aligned, next to each other, on the left.
Can anyone recommend what css property I should be using to solve this problem? My research has shown there are ways of using float, but other people recommend against it, and when I try I get issues with the text overflowing off the page.
If you give the ul and lis a width and (100 ul /30 for li s for example) then they should display correctly
.header {
background-color: #ffd9e7;
border: black;
display: block;
box-sizing: border-box;
}
.header ul {
display: inline-block;
width:100%;
}
.header > ul > li {
display: inline-block;
position:relative;
vertical-align:top;
width:30%;
}
#lodestone {
text-align: left;
}
#user {
text-align: right;
}
#mogstation {
text-align: center;
}
<div class="header">
<ul class="child">
<li id="lodestone">The Lodestone</li>
<li id="mogstation">The Mog Station</li>
<li id="user">User Account</li>
</ul>
</div>
I added vertical-align:top; but it's excess to requirements, you could take that out..
Fiddle
Hope this helps
Take a look at CSS Flexbox for a different approach to layout your elements
header{
display: flex;
justify-content: space-around;
}
<header>
<div>A</div>
<div>B</div>
<div>C</div>
</header>
Why not make the li elements a third of the width?
First make the ul 100% width, you'll also need to ensure there's no padding on the right of the ul as it tends to be automatically added by browsers:
.header ul {
display: inline-block;
padding: 0;
width: 100%;
}
Then have each li 33%
.header > ul > li {
display: inline-block;
width: 33%;
}
Style the rest as required

Adapt all childs width with parent width

I have an html page structure like this:
<div id="list">
<ul>
<li style="background-color:orange;">Lorem</li>
<li style="background-color:red;">Lorem</li>
.............
<li style="background-color:black;">Lorem</li>
<li style="background-color:blue;">Lorem</li>
</ul>
</div>
On this page, I want all list element to have the same width - I don't care about the content, only the color is really important in this case - and I want all thos elements to fit in their parent div (#list) when the page just loaded, this mean no scroll.
And this list is not final, I can add or delete somme elements in my list after the page load. I would like to know if there is a CSS way to get this result, JavaScript is not really suitable in this case.
Is that possible ?
You can achieve this kind of behavior by using flex:
HTML structure:
<div id="list">
<ul>
<li style="background-color:orange;">Lorem</li>
<li style="background-color:black;">Lorem</li>
...
<li style="background-color:blue;">Lorem</li>
</ul>
</div>
CSS:
#list {
border-style: solid;
border-width: 3px;
white-space: nowrap;
}
#list ul {
display: flex;
flex-direction: row;
margin: 5px;
padding: 0;
}
#list ul li {
border-style: solid;
height: 50px;
list-style-type: none;
}
Here is a working demo: http://jsfiddle.net/kmbxawdd/1/
Yes, you can use flexible boxes:
#list {
display: flex; /* Magic begins */
border: 3px solid;
padding: 1em;
}
#list > li {
width: 0; /* Ignore the width of the content */
flex-grow: 1; /* Distribute remaining space equally */
overflow: hidden; /* Hide possible overflow */
height: 50px;
border-style: solid;
}
<ul id="list">
<li style="background-color:orange;">Lorem</li>
<li style="background-color:red;">Lorem</li>
<li style="background-color:black;">Lorem</li>
<li style="background-color:blue;">Lorem</li>
</ul>
JSFiddle Example
Flexbox is your friend.
div#list {
height: 800px; /*Whatever you want, really*/
width: 800px; /*Again, substitute this with whatever size you like*/
}
div#list ul {
height: 100%;
width: 100%;
display: flex;
flex-flow: row nowrap;
align-content: stretch;
list-style: none;
padding: 0;
margin: 0;
}
div#list ul li {
-webkit-flex: 0 1 100%;
flex: 0 1 100%;
}
You can try to set display to "table" on list and "table-cell" on li. But it will work as you expect only if all li elements will contain content with same width. And list itself must have explicitly defined width, of course.

How to justify and center my vertical navigation links

If I understood how Justify works, it will fill or remove the needed spacing to my words to make it the same width like the others. My problem is I want to make my links centered, and justified at the same time, I want to add some spacing so that the other links are aligned with PORTFOLIO.
I've tried giving the div a text-align: center, and created a class for each of my a tags and gave it a text-align: justify. Sadly, it didn't work and I'm lost.
#side-nav-menu {
width: 40%;
position: fixed;
text-align: center;
top: 50%;
bottom: auto;
left: auto;
right: auto;
transform: translate(0, -50%);
display: none;
}
#side-nav-menu ul li a {
text-align:justify;
color: white;
}
EDIT:
Something like this
This was a huge pain in the ass to get to work, but here it is:
Example fiddle
Here's the relevant code:
JavaScript
$('#side-nav-menu li a').each(function() {
var t = $(this),
letters = $(this).text().split(''),
width = $(this).width(),
output = "";
for (var i=0,l=letters.length;i<l;i++){
output += "<span style='width:" + ((i===(l-1)) ? 0 : width/(l-1)) +"px;'>" + letters[i] + "</span>";
}
t.html(output);
});
CSS
body {
background-color: #999;
font-family: sans-serif;
}
#side-nav-menu {
width: 200px;
position: fixed;
text-align: center;
top: 50%;
bottom: auto;
left: auto;
right: auto;
transform: translate(0, -50%);
list-style: none;
padding: 0;
margin: 0;
}
#side-nav-menu li {
height: 30px;
}
#side-nav-menu li a {
display: block;
color: white;
text-align: justify;
}
#side-nav-menu li a span {
display: inline-block;
}
HTML
<ul id="side-nav-menu">
<li>
<a>HOME</a>
</li>
<li>
<a>BLOG</a>
</li>
<li>
<a>ABOUT</a>
</li>
<li>
<a>RESUME</a>
</li>
<li>
<a>PORTFOLIO</a>
</li>
<li>
<a>PROFILES</a>
</li>
<li>
<a>CONTACT</a>
</li>
</ul>
Update - A cooler way to do it
If you're up to using a monospace font, you can do something like this:
Fiddle with monospace
Here's what's different from the first:
CSS
body {
background-color: #999;
font-family: monospace;
}
JavaScript
for (var i=0,l=letters.length;i<l;i++){
output += "<span style='font-size:" + width/l +"px;'>" + letters[i] + "</span>";
}
Sample output:
I think you can fiddle some with flexbox:
.container {
width: 200px;
height: 300px;
padding: 5px;
background: #555;
color: white;
font-size: 24px;
}
.item {
display: flex;
justify-content: space-between;
}
<div class="container">
<div class="item">
<i>F</i><i>i</i><i>r</i><i>s</i><i>t</i>
</div>
<div class="item">
<i>S</i><i>e</i><i>c</i><i>o</i><i>n</i><i>d</i>
</div>
<div class="item">
<i>L</i><i>a</i><i>s</i><i>t</i>
</div>
</div>
Flexbox to justify text
The best way I can think of doing this would be like this (using inline styles for brevity).
inline-block elements use the minimum space necessary, which can come in handy.
li {
display: block;
}
<div style="text-align: center; width: 100%;">
<div style="text-align: left; display: inline-block;">
<ul>
<li>
Home
</li>
<li>
Blog
</li>
<li>Supercalafragilistic</li>
</ul>
</div>
</div>
Essentially what you need is the UL (container) to be centered, while the LI (content) to be left aligned, but the way I know requires a width to be set on the container.
ul {
display: block;
margin: auto;
width: 40%;}
li {
display: block;
text-align: left;}
To get it centered as much as possible, the width needs to be a tad wider than the longest word. You can play with the value until it's perfectly centered.
The 'text-align: justify' styling causes the render engine to alter the width of whitespace spans so that the lines are all the same width (with the exception of the trailing orphan line). Since your anchor texts have no whitespace spans, the render engine can't do anything.
What you need to be adjusting is letter-spacing style. Here's a different StackOverflow answer with a bit of jQuery showing how it is done:
Stretch text to fit width of div
I caution you however: the difference in lengths between "HOME" and "PORTFOLIO" are likely to look very odd when you make the words be the same length.