I tried to move the grid at center of the page, I dont know why it doesn't work
I looked a lot of example, I see people using this:
justify-content: center;
Even if I tried it and it doesn't work.
Here's my code
ul {
list-style-type: none;
background-color: silver;
padding: 10px;
text-align: center;
margin: none;
}
p {
text-align: center;
padding: none;
}
li {
display: inline;
padding: 10px;
}
a {
color: yellow;
}
.testing {
padding: 150px;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 10px;
/* next comment was fixed to meet syntax in a plain style sheet */
justify-content: center;
/* its not moving to the center of the page*/
}
.testing div {
width: 225px;
height: 225px;
background-color: blue;
}
<ul>
<li><a href=" ">Home</a ></li>
<li><a href="#news">News</a ></li>
<li><a href="#contact">Contact</a ></li>
</ul>
<p>hellow world</p >
<div class = "testing">
<div></div>
Just change padding: 150px; to padding: 50%;, on .testing ('testing' class).
This should work.
Best regards,
Brhaka
The grid is centered, you just gave it 3 equal columns but only one child element, so the div is showing in the left-most column of the grid. If you change the CSS to grid-template-columns: 1fr or define a template area in the center it will display as you expected, but having only one column begs the question of why you are using a grid layout to begin with. What kind of layout are you trying to build? Maybe a flexbox solution would better fit your needs?
Related
I need to put the li's side by side but I'm having trouble doing that.
.logo {
display: grid;
grid-column: span 2;
justify-content: start;
}
.logo h4 {
grid-column: 2;
}
nav {
display: grid;
}
ul {
text-transform: uppercase;
list-style: none;
gap: 20px;
}
<header>
<div class="logo">
<img src="image 17.png" alt="My Learning Journal logo">
<h4>My learning journal</h4>
</div>
<nav>
<ul>
<li>About Me</li>
<li>Contact</li>
</ul>
</nav>
</header>
You can use display:flex to put the li's side by side
ul {
text-transform: uppercase;
list-style: none;
gap: 20px;
display: flex
}
<ul>
<li>About Me</li>
<li>Contact</li>
</ul>
Horizontal menu can be done on both Flex and Grid.
If you are mastering Grid, either set general flow direction using grid-auto-flow rule, or declare dynamic column layout using grid-template-columns along with auto-fit/auto-fill.
ul {
text-transform: uppercase;
list-style: none;
display: grid;
grid-auto-flow: column; /* first way */
grid-template-column: repeat(auto-fill, 1fr) /* second way */
column-gap: 20px;
}
There were a few problems with your posted code; mainly that you were trying to position elements within a grid that was declared on their ancestor or – in the case of the .logo CSS – trying to position the element in grid-column: 2, despite that element not being a grid-item (the element itself had display: grid but it – obviously? – can't be placed in the second column of itself.
The following approach – with explanatory comments in the code – seems to do as you require:
/* removing browser default margins and padding, setting the sizing
algorithm to border-box; this includes border-sizes and padding
in the declared width of the elements: */
*,
::before,
::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.logo {
/* you've set display: grid; which means the children of this element
become grid-items, but this element is not (unless its parent is
also set to display: grid, but you haven't shown that in your code: */
display: grid;
/* setting the same gap as declared for the <ul> element: */
gap: 20px;
/* the following rule has no effect, as this element isn't a grid-item: */
grid-column: span 2;
justify-content: start;
/* to create a two-column grid layout, we use the following: */
grid-template-columns: repeat(2, 1fr);
}
/* this is just so that we can visualise the <img> element's placement,
adjust to your taste: */
.logo img {
background-image: repeating-linear-gradient( -45deg, transparent 0 5px, #eee9 5px 7px);
/* setting the maximum width (in left-to-right, top-to-bottom languages, like Latin and
its derivatives) of the element to be 100% of the available space: */
max-inline-size: 100%;
/* and for the <img> to fill the available space: */
object-fit: cover;
}
.logo h4 {
grid-column: 2;
}
ul {
display: grid;
/* setting two grid-columns, with the repeat() function; this sets the 2 columns
to both have the size of 1fr (one fraction of the available space), so that
they are each equally sized: */
grid-template-columns: repeat(2, 1fr);
text-transform: uppercase;
list-style: none;
gap: 20px;
}
nav a {
background-color: lightskyblue;
color: #fff;
display: block;
}
<header>
<div class="logo">
<img src="image 17.png" alt="My Learning Journal logo">
<h4>My learning journal</h4>
</div>
<nav>
<ul>
<li>About Me</li>
<li>Contact</li>
</ul>
</nav>
</header>
It's worth pointing out that, in this instance, display: flex may be be preferred:
*,
::before,
::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.logo {
/* you've set display: grid; which means the children of this element
become grid-items, but this element is not (unless its parent is
also set to display: grid, but you haven't shown that in your code: */
display: grid;
/* setting the same gap as declared for the <ul> element: */
gap: 20px;
justify-content: start;
/* to create a two-column grid layout, we use the following: */
grid-template-columns: repeat(2, 1fr);
}
.logo img {
background-image: repeating-linear-gradient( -45deg, transparent 0 5px, #eee9 5px 7px);
min-inline-size: 100%;
object-fit: cover;
}
.logo h4 {
grid-column: 2;
}
ul {
/* setting flex layout: */
display: flex;
text-transform: uppercase;
list-style: none;
/* using gap as before: */
gap: 20px;
}
li {
/* instructing the <li> element(s) to expand to fill available space: */
flex-grow: 1;
}
nav a {
background-color: lightskyblue;
color: #fff;
display: block;
}
<header>
<div class="logo">
<img src="image 17.png" alt="My Learning Journal logo">
<h4>My learning journal</h4>
</div>
<nav>
<ul>
<li>About Me</li>
<li>Contact</li>
</ul>
</nav>
</header>
References:
CSS Logical Properties.
display.
gap.
grid-column.
grid-template-columns.
justify-content.
max-inline-size.
object-fit.
repeat().
I am using CSS grid for a website, and in the information section I have 2 columns:
on the left a paragraph with information, on the right the image.
However, when I want to add an h1 to the paragraph it creates an extra column, resulting in:
On the left the header, on the right the image and underneath the header is now the paragraph.
I've now avoided the problem by using and making a class for the first sentence of the paragraph (making that sentence look like a h1) but it feels like a makeshift solution. Is there a better way to solve this problem?
I've tried 2fr 2fr, still the same problem
I've added a screenshot of what it looks like
(I'm still very new to CSS grid)
.block1{
display:grid;
grid-template-columns: 1fr 2fr;
column-gap: 250px;
background-color: #EFEDE3;
padding: 150px;
}
.block1 img{
justify-self: end;
border-radius: 5px;
width: 75%;
}
.block1 span {
font-weight: bolder;
font-size: 32px;
}
You can try this one.
HTML:
<div class="grid">
<div class="paragraph">
<h1>Paragraph</h1>
</div>
<div class="imageBox">
</div>
</div>
and CSS:
.grid {
display: grid;
grid-template-columns: 1fr 2fr;
column-gap: 250px;
}
.paragraph {
border: 1px solid green;
height: 40vh;
}
.imageBox {
border: 1px solid red;
height: 40vh;
}
I'm trying to use grid layout to create two columns. The right column has a fixed width but the left one should take whatever's left out. However, the problem is that when the content is too long, it extends the left column and causes a horizontal scrollbar in the container.
Now I can achieve this with other methods like calc but I'm trying to learn grid layout.
Here's a fiddle to demonstrate: https://jsfiddle.net/pta2c7um/
Ideally I would want the long title to get truncated respecting the grid structure.
Solution:
#ticket-viewer .list li{
/* grid-template-columns: auto 80px; */
grid-template-columns: minmax(0, 1fr) 80px;
padding: 1rem;
cursor: pointer;
}
Working example:
.list{
margin: 0;
padding: 0;
}
.list li {
padding: 0.8rem 0;
position: relative;
}
.list li small {
color: #777777;
}
.list li .content {
padding: 0 !important;
}
.list li .right-assist {
text-align: right;
}
.list.left-assist li, .list.right-assist li {
display: grid;
}
.list.right-assist li {
grid-template-columns: auto 40px;
}
.list.dividers li:before {
content: "";
position: absolute;
height: 1px;
background: #CCC;
bottom: 0px;
left: 0;
right: 0;
}
#ticket-viewer{
border: 1px solid #CCC;
display: flex;
}
#ticket-viewer .list{
width: 40%;
height: 560px;
overflow-y: auto;
border-right: 1px solid #CCC;
}
#ticket-viewer .list li{
/* grid-template-columns: auto 80px; */
grid-template-columns: minmax(0, 1fr) 80px;
padding: 1rem;
cursor: pointer;
}
.truncate {
display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<div id="ticket-viewer">
<ul class="list right-assist dividers">
<li data-id="1" class="">
<div class="content"><span class="truncate">Test</span><small>Bug/Error on Website</small></div>
<div class="right-assist">Resolved</div>
</li>
<li data-id="2" class="active">
<div class="content"><span class="truncate">This is a very very long subject</span><small>Feature Request</small></div>
<div class="right-assist">Resolved</div>
</li>
</ul>
</div>
Explanation:
grid-template-columns: minmax(0, 1fr) 80px; step-by-step explanation:
Define two columns.
The last has fixed 80px width;
The first occupies remaining space.
minmax(0, ..) is used to tell browser to shrink width of column, if its content is wider than 1fr (i.e. 1 fraction of remaining space).
More info on MDN
i was using grid property to build web site. but i got a problem that i can't use background property as i expect.
#wrap {
height: 100%;
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 35px 125px;
}
.line1 {
width: 1px;
height: 16px;
background: #ccc;
}
header {
background-color: #221816;
grid-column: 2/12;
}
header .topNav {
color: #fff;
}
header .topNav ul {
height: 35px;
display: flex;
flex-direction: row;
justify-content: flex-end;
}
header .topNav ul li {
align-self: center;
padding-right: 16px;
}
*,
:before,
:after {
margin: 0;
padding: 0;
border: 0;
color: #fff;
list-style: none;
}
<div id="wrap">
<header>
<nav class="topNav">
<ul>
<li>login</li><span class="line1"></span>
<li>signin</li>
<li>bags</li>
<li>mypages<span></span></li>
<li>customer</li>
</ul>
</nav>
</header>
</div>
i expected the header's width 100%. so i put 'grid-column:1/-1;' and i got problem that contents have to be narrow. so i fix property like 'grid-column:2/12' then now i got a problem the background can't be wide. do i have solution?
change your header to read: header{background-color:#221816; grid-column: 1/13;}
This is why: You have 12 divisions along the width of your page, but you don't count the area by divisions, you count by the line.Take a piece of scratch paper, draw three lines from side to side, then 13 lines top to bottom to represent your 12 columns and 2 rows of your header/navigation area. Now, the three lines across are numbered 1, 2, and 3 (one at the top, two in the middle, three at the bottom). The 13 verticle lines start with line number one, and if you count all the way across end with line number 13. So, to get your header to go from one side of the page to the other, it needs to start on line 1 and end on line 13 (1/13). Does that make sense?
If I understand correctly what you're trying to do, you can get what you want with a lot less effort, as I've shown below. Just do this row with flex. You don't need to use grid.
After I wrote up this answer, your subsequent comments say that you want to do something that you haven't shown us with some more rows that are different from this one. You can do things the way I've shown you for this row, and then add another div with the grid in it and do what you want with it.
If that doesn't work for you, then you'll need to further clarify what you're trying to do.
.line1 {
width: 1px;
height: 100%;
background: #ccc;
}
header {
background-color: #221816;
}
header .topNav {
color: #fff;
}
header .topNav ul {
height: 35px;
display: flex;
flex-direction: row;
justify-content: flex-end;
}
header .topNav ul li {
padding: 0 2%;
align-self: center;
}
*,
:before,
:after {
margin: 0;
padding: 0;
color: #fff;
list-style: none;
}
<div id="wrap">
<header>
<nav class="topNav">
<ul>
<li>login</li><span class="line1"></span>
<li>signin</li>
<li>bags</li>
<li>mypages<span></span></li>
<li>customer</li>
</ul>
</nav>
</header>
</div>
I have a horizontal flex box (i.e. flex-direction: row, i.e. side-by-side) with a few items. Each item can be a single line of text, or can have multiple lines. I want to vertically-align the contents of each flex item.
If each item had a transparent background, I could easily use align-items: center. However, I want each item to be stretched vertically, because I want to set a background (or maybe borders, or maybe it is a clickable region) to the entire available height.
So far, I know:
Stretching: align-items: stretch
Aligning: align-items: center
Stretching and aligning: ???
Demo available at http://codepen.io/denilsonsa/pen/bVBQNa
ul {
display: flex;
flex-direction: row;
}
ul.first {
align-items: stretch;
}
ul.second {
align-items: center;
}
ul > li {
flex-grow: 1;
flex-shrink: 0;
flex-basis: 5em;
text-align: center;
}
ul > li:nth-child(2) {
background: #CFC;
}
/* Visual styles, just ignore. */
html, body { font-family: sans-serif; font-size: 25px; }
ul, li { list-style: none; margin: 0; padding: 0; }
ul { background: #CCF; width: 25em; }
<ul class="first">
<li>Sample</li>
<li><span>span</span></li>
<li><span>multiple</span> <span>span</span></li>
<li>text <span>span</span></li>
<li>multi<br>line</li>
</ul>
<hr>
<ul class="second">
<li>Sample</li>
<li><span>span</span></li>
<li><span>multiple</span> <span>span</span></li>
<li>text <span>span</span></li>
<li>multi<br>line</li>
</ul>
Similar questions:
Question 14012030 and question 23442692 and question 27729619 and question 25311541 ask essentially the same thing, but they either have a single element or plain text as child of each flex item. As soon as we have mixed content, possibly with multiple elements, those solutions do not work.
Question 19026884 is unrelated, the issue there was the wrong markup.
Unfortunately, it is impossible to achieve the desired effect while using the exact markup posted in the question.
The solution involves:
Setting display: flex; on <li>.
Wrapping the <li> contents into another element.
This is required because <li> is now a flex container, so we need another element to prevent the actual contents from becoming flex items.
In this solution, I introduced a <div> element, but it could have been other element.
Now that <li> is a flex container and it contains only a single child, we can use align-items and/or justify-content to align this new and only child.
The DOM tree looks like this:
<ul> flex-parent, direction=row
├ <li> flex-item && flex-parent && background && JavaScript clickable area
│ └ <div> flex-item as a single transparent element
│ ├ Actual contents
│ └ Actual contents
├ …
Note: The solution in this answer uses 2 nested flex boxes. The solution by Michael_B uses 3 nested flex boxes, because it has the added challenge of expanding the <a> element to fill the entire <li>. Which one is preferred depends on each case. If I could, I would accept both answers.
/* New code: this is the solution. */
ul > li {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
/* Old code below. */
ul {
display: flex;
flex-direction: row;
align-items: stretch;
}
ul > li {
flex-grow: 1;
flex-shrink: 0;
flex-basis: 5em;
text-align: center;
}
ul > li:nth-child(2) {
background: #CFC;
}
/* Visual styles, just ignore. */
html, body { font-family: sans-serif; font-size: 25px; }
ul, li { list-style: none; margin: 0; padding: 0; }
ul { background: #CCF; width: 25em; }
button:focus + ul {
font-size: 14px;
width: auto;
}
<button>Click here to set <code>width: auto</code> and reduce the font size.</button>
<!-- New code: there is a single <div> between each <li> and their contents. -->
<ul>
<li><div>Sample</div></li>
<li><div><span>span</span></div></li>
<li><div><span>multiple</span> <span>span</span></div></li>
<li><div>text <span>span</span></div></li>
<li><div>multi<br>line</div></li>
</ul>
I want each item to be stretched vertically, because I want to set a
background (or maybe borders, or maybe it is a clickable region) to
the entire available height.
You can achieve this layout without any changes to your HTML structure. There's no need for additional containers.
You already have a primary flex container and a group of flex items. Simply make those flex items into nested flex containers. That will enable you to align the content with flex properties.
(Since you mentioned that you may need clickable regions, I switched from li to a elements.)
nav {
display: flex;
background: #CCF;
width: 25em;
}
nav > a {
flex: auto; /* flex-grow: 1, flex-shrink: 1, flex-basis: auto */
text-align: center;
text-decoration: none;
display: flex;
align-items: center;
justify-content: center;
}
nav > a:nth-child(2) {
background: #CFC;
}
html, body {
font-family: sans-serif;
font-size: 25px;
}
<nav>
Sample
<span>span</span>
<span>multiple</span> <span>span</span>
text <span>span</span>
multi<br>line
</nav>
revised codepen
Note that content placed directly inside a flex container is wrapped in an anonymous flex item:
From the spec:
4. Flex Items
Each in-flow child of a flex container becomes a flex item, and each contiguous run of text that is directly contained inside a flex
container is wrapped in an anonymous flex item.
So, because the text is automatically wrapped in flex items, you can keep the full height of each item (align-items: stretch from the primary container) and vertically center the content (align-items: center from the nested containers).
Make the li flex-containers with flex-direction:column. I think that's what you are after.
html,
body {
font-family: sans-serif;
font-size: 25px;
}
ul,
li {
list-style: none;
margin: 0;
padding: 0;
}
ul {
background: #CCF;
width: 25em;
display: flex;
flex-direction: row;
}
ul.first {
align-items: stretch;
}
ul > li {
flex-grow: 1;
flex-shrink: 0;
flex-basis: 5em;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
/*outline: 1px dotted #444;*/
}
ul > li:nth-child(2) {
background: #CFC;
}
<ul class="first">
<li>Sample</li>
<li><span>span</span>
</li>
<li><span>multiple</span> <span>span</span>
</li>
<li>text <span>span</span>
</li>
<li>multi
<br>line</li>
</ul>
Flex-child items can also be flex-parent items.
*,
*:before,
*:after {
box-sizing: inherit;
}
html {
box-sizing: border-box;
font-family: sans-serif;
font-size: 25px;
}
body {
display: flex;
flex-flow: column nowrap;
background-color: #333;
overflow: hidden;
}
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
.List {
padding: 0;
margin: 0;
background: #CCF;
width: 25em;
list-style: none;
display: flex;
flex-flow: row nowrap;
justify-content: center;
}
.ListItem {
flex-basis: 5em;
display: flex;
flex-flow: row wrap;
text-align: center;
align-items: center;
}
.ListItem:nth-child(2) {
background: #CFC;
}
.ListItem__content {
width: 100%;
}
<ul class="List">
<li class="ListItem">
<span class="ListItem__content">Sample</span>
</li>
<li class="ListItem">
<span class="ListItem__content">span</span>
</li>
<li class="ListItem">
<span class="ListItem__content">multiple <br> span</span>
</li>
<li class="ListItem">
<span class="ListItem__content">span</span>
</li>
<li class="ListItem">
<span class="ListItem__content">multi<br>line</span></li>
</ul>