CSS stretching child elements across parent element - html

I'm trying to get some list items to stretch across a list
This is the relevant code
#navbar ul
{
list-style-type: none;
margin: 0;
padding: 0;
width: 100%;
}
#navbar li
{
display: inline;
float: left;
width: 33.33%;
}
Here's what it normally looks like:
But sometimes when I leave the page and come back later (not after reloading) this happens:
Setting the individual item width to 33.3% makes it one pixel short and making it 33.333% makes the problem worse...

You could easily achieve this layout using css tables instead. Widely supported and semantically sound.
#navbar ul {
width: 100%;
display: table;
table-layout: fixed; /* makes all cells equal width */
}
#navbar li {
display: table-cell;
}
http://jsfiddle.net/kBnrz/1/

remove padding of parent of "ul"

Just fake it:
#navbar ul li{
width:33%;
}
#navbar ul li:last-child{
width:34%;
}
Also include this style:
* { box-sizing: border-box }
ref: http://www.paulirish.com/2012/box-sizing-border-box-ftw/

Suggestion:
#Miro try CSS Flexbox layout, it will help you, but it works only in modern browsers.
CSS Flexbox
The CSS Flexible Box Layout Model, or "flexbox", is one of the specification in CSS3. It provides for the arrangement of elements on a page such that the elements behave predictably when the page layout must accommodate different screen sizes and different display devices. For many applications, the flexible box model provides an improvement over the block model in that it does not use floats, nor do the flex container's margins collapse with the margins of its contents.
Here is one example
Html
<div class="box">
<div class="A">A</div>
<div class="B">B</div>
<div class="C">C</div>
</div>
StyleSheet
html, body{
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
.box {
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-content: center;
align-items: flex-start;
}
.box div.A {
order:1;
flex: 1 1 auto;
align-self: auto;
min-width: 0;
min-height: auto;
}
.box div.B {
order:2;
flex: 1 1 auto;
align-self: auto;
min-width: 0;
min-height: auto;
}
.box div.C {
order:2;
flex: 1 1 auto;
align-self: auto;
min-width: 0;
min-height: auto;
}
Here is the Demo
This Link will help you.

Related

CSS/HTML - How can I center something when auto-margin does not seem to work?

This is part of the CSS for my menu:
ul {
text-align: left;
display: inline;
margin: auto;
width: 50%;
position: fixed;
top: 0;
list-style: none;
}
I have tried auto-margin left and right. All of the methods I have tried have never resulted in the entire page being center with itself.
Here is what I have done with the main 'box' that is under the above menu.
.box {
margin: auto;
width: 50%;
padding: 20px;
background-color: #FFFFFF;
word-break: break-all;
}
Full page source is at: https://pastebin.com/56HbfaGM
What also bothers me is that different browsers show different results.
I have not done much with HTML/CSS in years so sorry if this is super basic of a problem.
I just simply want to know some more holistic methods of centering.
You can't center using margin: 0 auto if your element is position: fixed. And you can't use margin: 0 auto on an inline element.
Another problem you have is that the ul element has padding on its left side. You'll want to remove that to center things correctly.
And your final problem is even if you successfully center the ul element, it won't look centered because there'll be a portion of the element not filled with list items depending on the width of the screen since the background is transparent. You can fix that by either adding background: #A4A4A4 to give the ul element a solid background matching the li elements, or you can center the li elements by using text-align: center on the ul element.
The following is an example of centering a fixed element correctly, along with centering the list items.
ul {
text-align: center;
display: inline;
padding: 0;
width: 50%;
position: fixed;
top: 0;
left: 50%;
margin: 0 0 0 -25%;
list-style: none;
}
IIRC, you can't use auto without a defined width. Also, it's margin:0 auto;, though that might not matter with html5's lack of strictness.
The right way is use margin:0 auto; below I've made two ways to center a box.
HTML
<!-- Margin box -->
<div class="container">
<div class="box-centered">
</div>
</div>
<br>
<!-- Flexbox box -->
<div class="Aligner">
<div class="Aligner-item"></div>
</div>
CSS
/* Margin:auto way */
.container {
width: 100%;
}
.box-centered {
width: 50%;
height: 300px;
margin: 0 auto;
background-color: red;
}
/* Flexbox way */
.Aligner {
display: flex;
align-items: center;
justify-content: center;
}
.Aligner-item {
width: 50%;
height: 300px;
background: blue
}
Here the example in jsfiddle: http://jsfiddle.net/1h0f74qb/
Hope this can help you.
depends on how you need to center the item.
display: flex, with align-items:center
Simple example using flex box in HTML/CSS
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<style>
body {
display: flex;
flex-direction: column;
align-items: center;
background-color: #ccc;
}</style>
</head>
<body>
<h1>This is a Heading</h1>
<p>This is a paragraph.</p>
</body>
</html>
Instead of display: inline, you could use display: flex:
ul{
...
display: flex;
align-content: center;
...
}

CSS Flex stretching out links

So I am learning a bit more about using CSS flex instead of using static positioning of content. However, I have defined my link styles as well as bold styles. My guess is that it's adapting to the container that is in (which is using flex feature) and that is why it is stretching across the size of the container it is inside. My question now is, how do I fix this? I've seen that I can do "display:inline-block" on the link, but that has not fixed it.
Here is my code:
.container{
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
width: 80%;
margin: auto;
background-color:#fff;
overflow: hidden;
font-size: 15px;
line-height: 20px;
padding:1em;
}
.container > * {
padding: 15px;
-webkit-flex: 1 100%;
flex: 1 100%;
}
a{
text-decoration:none;
border-bottom-style:double;
border-bottom-width:2px;
color:#99d3df;
display:inline-block;
padding:0px;
overflow: hidden;
}
i{
display:inline-block;
color:#88bbd6;
text-decoration:italic;
}
And what I have:
This is a Google Link<BR>
Google is <i>extremely helpful</i>!
This is what it looks like for reference.
Problem image
It seems you missed the .container wrapper div in the markup you provided.
Let's look at this code:
<!-- HTML -->
<div class="container">
<span>This is a </span><a href="http://google.com">Google Link</a
</div>
<div class="container">
<span>Google is </span><i>extremely helpful</i>!
</div>
<!-- /HTML -->
/* CSS */
.container > * {
padding: 15px;
-webkit-flex: 1 100%;
flex: 1 100%;
}
Property flex with value of 1 100% means we tell the browser to style any elements (the asterisk *) nested in .container to have 100% width of their parent's width.
I would suggest you to just remove that part to fix the problem.
Here's my approach to your markup.
.container {
display: flex;
width: 80%; /* flexible value */
flex-direction: row; /* this is to make sure that we'll have side-to-side layout within .container */
}
a {
text-decoration: none;
border-bottom-style: double;
border-bottom-width: 2px;
color: #99d3df;
display: inline-block;
padding: 0px;
}
a, i{
margin-left: 5px; /* this is to give a 10px spacing */
}
<div class="container"><span>This is a </span>random link<span></span></div>
<div class="container"><span>Google </span><i>is extremely helpful! </i></div>
It is working fine when I tried your code in js fiddle
see in this image
May be some other css is affecting your links to stretch it out.

Determine layout based on flex children count?

Is there a way to determine layouts with css/html based on the specific child amounts?
See below for a layout example.
I've attempted to get it to work with nth-child, but I may be doing this incorrectly..
https://codepen.io/brycesnyder/pen/EvBzWq
But I'm not sure if there is a way to make all elements span 50% width, and if there are more than 1 the following should stack.
/* three items */
li:first-child:nth-last-child(3):not(:first-child),
li:first-child:nth-last-child(3) ~ li {
background: green;
}
EDIT: I know this is possible via standard elements like so: https://codepen.io/brycesnyder/pen/GvbbyY I want to be able to use just a UL > LI
So... it's not exactly "based on the number of children", but you can achieve the layout you're looking for by changing your flex direction to column, setting width to 50%, and having the first element have flex; 0 0 100%. You'll also need to set the special case of a 1 child list (:first-child:nth-last-child(1)) to be width 100%.
The key css ends up looking like this:
ul {
padding:10px 1px;
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 200px;
list-style-type: none;
}
li {
outline:1px solid gray;
text-align:center;
width: 50%;
margin: 0;
padding: 0;
flex: 1 1 auto;
}
li:first-child {
height: 100%;
flex: 0 0 100%;
}
/* one item */
li:first-child:nth-last-child(1) {
width: 100%;
}
Here's a codepen I set up forked from yours:
https://codepen.io/kball/pen/yomyyg

Fit 3 elements in the same line

I have 3 elements in HTML as follows:
.navigation {
display: inline-block;
width: 25%;
}
.content {
display: inline-block;
width: 50%;
}
.sidebar {
display: inline-block;
width: 25%;
}
<nav class="navigation">Navigation</nav>
<section class="content">Section</section>
<aside class="sidebar">Aside</aside>
This should fit in the 100% width of the container (<body> or any other <div>). However the .sidebar is being dropped to the next line. I tried to setup border, margin and padding to 0 with the !important definition (just to test) but the result is the same. How can I fit this 3 elements in the same line keeping the width property?
Thanks in advance for your answers.
As someone else mentioned, the issue is that when using display: inline-block, white-space - even between element tags - is accounted for in rendering. There are a few ways to get around this.
Setting display: table-cell rather than inline-block can work in a simple situation like this; just note that it prevents the blocks from wrapping
You can set font-size:0; on the parent to get rid of the whitespace, but you'll have to reset it on all the direct children.
Unless you have to support pre-IE10 browsers, I'd recommend flexbox here! You may need to add some browser prefixes, but the base would look like this (name your parent element something better than 'parent', though!):
.parent { display: flex; }
.navigation, .sidebar { flex: 1 }
.content { flex: 2 }
What that snippet is saying is "make the children fit, and make .content twice as big as the other two".
Even though you removed the padding, margin, and border, inline elements are actually sensitive to white space in the code itself. Remove that and they line up:
.navigation {
display: inline-block;
width: 25%;
}
.content {
display: inline-block;
width: 50%;
}
.sidebar {
display: inline-block;
width: 25%;
}
* {
margin: 0;
padding: 0;
border: 0;
}
<nav class="navigation">Navigation</nav><section class="content">Section</section><aside class="sidebar">Aside</aside>
When you're using display inline-block, it takes the space in your code as a character(space), so, you have 100% + the space required for 2 characters, you could keep the formatting of your code and ¨remove¨ the space between your containers setting the font-size of the parent to 0
.container{
font-size:0;
}
.container *{
font-size:12px;
}
.navigation {
display: inline-block;
width: 25%;
}
.content {
display: inline-block;
width: 50%;
}
.sidebar {
display: inline-block;
width: 25%;
}
<div class="container">
<nav class="navigation">Navigation</nav>
<section class="content">Section</section>
<aside class="sidebar">Aside</aside>
</div>
It's because you're using the style of display:inline-block which will recognize and create a space between element if your code have a space (either space, or new line), so what you need to do is just remove the space like answered by j08691 here
Or you can either remove the spacing by using a comment like this one
.navigation {
display: inline-block;
width: 25%;
}
.content {
display: inline-block;
width: 50%;
}
.sidebar {
display: inline-block;
width: 25%;
}
<nav class="navigation">Navigation</nav><!--
--><section class="content">Section</section><!--
--><aside class="sidebar">Aside</aside>
Or other way around is using the style margin like in this example, the background is used to visualize the size of the the inline-block element only
.navigation {
display: inline-block;
width: 25%;
margin: 0 -0.4em 0 0; background: red;
}
.content {
display: inline-block;
width: 50%;
margin: 0 -0.4em 0 0; background: green;
}
.sidebar {
display: inline-block;
width: 25%;
margin: 0 -0.4em 0 0; background: blue;
}
<nav class="navigation">Navigation</nav>
<section class="content">Section</section>
<aside class="sidebar">Aside</aside>

How to use css3 flexbox to create multi-column layout without expanding vertically?

I'm playing with css3's flexbox in Chrome (no need to worry about cross-browser for this). I'm having a hard time convincing it to lay out my content the way I'd like. Here's a sketch of my goal:
Here's a jsFiddle of my attempt: http://jsfiddle.net/Yht4V/2/ This seems to work great except each .group will expand its height rather than create multiple columns.
I'm using flexbox pervasively here. The body lays out vertically, with the #content div taking the remaining height of the page. Each .group is laid out horizontally. Finally, each .item is laid out within a .group vertically with wrapping.
Unfortunately, each .group ends up as a single column by expanding the #content height, which causes a vertical scrollbar (unwanted). If I set the height of each .group to a fixed pixel size, the items break out into multiple columns, but this defeats the fluidity of the flexbox. Here's what it looks like with fixed heights: http://jsfiddle.net/Yht4V/3/
So, how can I get my #content div to not expand vertically since everything is managed with flexboxes without setting a fixed height? I was expecting the flexbox to trigger more columns instead of expanding the height of its parent and causing a scrollbar.
From what I've seen with the Chrome and Opera implementations for Flexbox, a flex-direction of column requires restricting the height of the element, otherwise it will continue expanding vertically. It doesn't have to be a fixed value, it can be a percentage.
That said, the layout you want for your .group elements can also be achieved by using the CSS Columns module. The flow of the elements will be similar to that of the flexbox column orientation, but it will create columns as long as there's enough width for them, regardless of how long the document is.
http://jsfiddle.net/Yht4V/8/ (you'll have to excuse the lack of prefixes)
html {
height: 100%;
}
body {
height: 100%;
display: flex;
flex-flow: column nowrap;
}
h1 {
padding: 1em;
}
#content {
padding: 10px;
background-color: #eee;
display: flex;
flex-grow: 1;
}
#content > .group {
margin: 10px;
padding: 10px;
border: 1px solid #cfcfcf;
background-color: #ddd;
flex: 1 1 auto;
}
#content > .group:first-child {
columns: 10em;
flex-grow: 2;
}
#content > .group .item {
margin: 10px;
padding: 10px;
background-color: #aaa;
break-inside: avoid;
}
#content > .group .item:first-child {
margin-top: 0;
}
Leaving it as a bunch of nested flexboxes, this was about as close as I could get it:
http://jsfiddle.net/Yht4V/9/ (again, no prefixes)
html {
height: 100%;
}
body {
height: 100%;
display: flex;
flex-flow: column nowrap;
}
h1 {
padding: 1em;
}
#content {
padding: 10px;
background-color: #eee;
display: flex;
flex: 1 1 auto;
height: 100%;
width: 100%;
}
#content > .group {
margin: 10px;
padding: 10px;
border: 1px solid #cfcfcf;
background-color: #ddd;
display: flex;
flex-flow: column wrap;
flex: 1 1 30%;
max-height: 100%;
}
#content > .group .item {
margin: 10px;
padding: 10px;
background-color: #aaa;
}
Replace the following in your css -
display: -webkit-flex;
to the following -
display: -webkit-box;
This worked very well for me :-)