Table-cell breaks on window resize in Safari - css

I have a table built out of div elements. By default elements display as table-cell.
On #media screen and (max-width: 769px) elements need to become table-row.
Every browser works fine except Safari.
In safari it shows fine until I re-size window to very narrow and then back full width. at that point table breaks. if I refresh page or disable and re-enable table-cell style table fixes itself.
Example:
http://jsfiddle.net/sergejpopov/TvEWf/
Is that a Safari bug? How to fix?

It sounds like you're not adhering to a correct structure- you shouldn't swap out table-cell for table-row, they serve two distinctly different purposes which are not equivalent in terms of interpreted layout, the table structure should always follow:
table (display-table)
row (display-row) <- important to denote a row of elements
cell (display-cell) <- important to denote (column based) content within a row
/cell
/row
/table
You're missing out either the row or cell level with your approach, so although everythign seems to be interpreted correctly for the most part, your css is actually in error.
I would suggest you consider using floated or inline divs, see
FIDDLE
HTML
<div class="t">
<div>1</div><div>2</div><div>3</div><div>4</div>
</div>
CSS
*{
box-sizing:border-box;
}
.t
{
width:100%;
}
.t>div
{
border:1px solid red;
display:inline-block;
width:25%;
margin:0;
padding:0;
zoom:1;
}
#media screen and (max-width: 769px) {
.t
{
width:100%;
display:table;
}
.t>div
{
border:1px solid red;
display: block;
width:100%;
zoom:1;
}
}

Related

Add margin-bottom to all column elements

In a bootstrap 3 project i've wanted some borders around cols so I made the following css Fiddle.
.admin-div{
background-color: #fff;
border-radius: 7px;
border: 1px solid #ccc;
padding:20px;
}
When I use it I place it inside a col like:
<div class="col-md-6 col-sm-8">
<div class="admin-div">
</div>
</div>
This works fine on big screens but on small screens there is no margin (note: the most left doesnt have the custom admin-div class and is a default list-group).
Large screen (nice margins beteween col's)
Small screen (no margin between col's)
One options is add
margin-bottom:20px
to all sm and sx elements but that sounds a bit overkill.
I could use
#media (max-width: 970px) { .spacing-div{ margin-bottom: 20px; } }
But than I have to add an extra class to all divs where I have a col.
So i have two solutions but they both feel like they could be replaced by something much more easy.
What is the best way to make
all col's have a margin-bottom :20px; even on small screens?
The extra admin-div is only to show the problem, without the extra div I would still have the problem but it wouldnt be visible that much.
If you want a margin on absolutely every column in Bootstrap you could use the following CSS selector which will add a margin to every element that contains col-.
[class*=col-] {
margin-bottom: 20px;
}
You could also use [class^=col-] in which the first class on an element needs to began with col-.
To extend this a bit further you could use a media query to have it only apply up to a certain screen size.
[class*=col-] {
margin-bottom: 20px;
}
#media ( min-width: 500px ) {
[class*=col-] {
margin-bottom: 0;
}
}
If you didn't want a margin on every single column then I would scope the above with a modifier selector.
<div class="row modifier">
<div class="col-6-md"></div>
<div class="col-6-md"></div>
</div>
/* fairly general - all columns in .modifier */
.modifier [class*=col-] {
margin-bottom: 20px;
}
/* a little more specific - only .col-md-6 columns in .modifier */
.modifier [class*=col-md-6] {
margin-bottom: 20px;
}

CSS table-cell in Opera with :before and :after do not behave as normal

I want to achieve the following effect in CSS:
I use CSS table-cell with :before and :after pseudo-elements so that they auto-adjust their width in one row. In other words, I want the text container have the width of the text (with some padding) and the pseudo-elements fill the rest of the area. This means that I can't use 1px background-image positioned top, because each word has a different width.
Here's the fiddle.
HTML
<div id="container">
<div id="box">
<h2 id="header">UPDATES</h2>
</div>
</div>
CSS
#container {
background:url("http://lorempixel.com/output/abstract-q-g-640-480-9.jpg") center center no-repeat;
padding-top:50px;
height:400px;
width:50%;
margin:0 auto;
}
#box {
margin:0 auto;
width:50%;
display:table;
}
#header {
color:#fff;
font:14px Arial;
font-weight:500;
line-height:10px;
height:10px;
display:table-cell;
padding:0 10px;
width:auto;
text-align:center;
}
#box:after, #box:before {
content:"";
display:table-cell;
border:1px solid #fff;
border-bottom:0;
height:10px;
width:50%;
}
#box:after{
border-left:0;
}
#box:before{
border-right:0;
}
However, it doesn't work in Opera so, I need to find a different technique to achieve the same effect. I'd prefer to avoid using HTML tables and any js. Can you provide any suggestion?
In this example I got rid of the psuedo-elements and sandwiched the header tag between two that were styled as a table to get the line effect. Although this is done using a CSS table the similar concept should be applicable to an html table.
<div id="before" ></div>
<h2 id="header">UPDATES</h2>
<div id="after"></div>
styled like so....
#before {
content:"";
display:table-cell;
border:1px solid #fff;
border-bottom:0;
border-right:0;
height:10px;
width:50%;
}
#after {
content:"";
display:table-cell;
border:1px solid #fff;
border-bottom:0;
border-left:0;
height:10px;
width:50%;
}
http://jsfiddle.net/SteveRobertson/9SBXn/12/
After several tests, I found out that Opera needs a more detailed implementation when using CSS tables with pseudo-elements. In other words, it's not enough to set the parent container as display:table and children as display:table-cell.
You need to set the whole hierarchy, meaning that:
The parent needs to be set as:
display:table
The first children needs to be set as:
display:table-row
And finally set the other children as:
display:table-cell
If you set your CSS ignoring display:table-row like I did, Opera sets the children elements (after display:table-cell) as table-row and not as table-cell, thus the width of each child extends to 100% of the parent and behaves like a row. Setting the table hierarchy like in HTML tables (table > row > cell) you get the expected format.
This seems to affect only Opera, since all other browsers do not try to fix the hierarchy of the CSS table.
Here's the demo (check in Opera as well)
Instead of CSS tables, you could use inline-blocks with percentage width and max-width so that the containers don't fall in a new line.

Set parent to display:none, set child to display:block

Working on a responsive website, I want to remove a certain element, however, I want the child element to still be displayed.
Setting the CSS rule for parent element to display:none; removes that element and all the children. Event if I set the child element to display:block; it still doesn't appear on the site.
Something like this:
HTML:
<div id="parent">
<div id="child">Some text.</div>
</div>
CSS:
#parent {
display:block;
width:500px;
height:200px;
background:blue;
}
#child {
display: inline-block;
padding:20px 5px;
background: red url(someimage.jpg);
}
#media only screen
and (max-device-width : 700px) {
#parent {
/* code that makes the browser disregard the height of this div and not display its background */
}
#child
/* the child is still displayed */
}
}
What would be the proper CSS solution?
It looks like you just want to knock out the background of the parent in certain layouts. To do that, just use
#knockout {
background: transparent;
border: none;
outline: none;
box-shadow: none;
padding: 0;
}
This will remove the background, the borders and any shadow effects on the parent item - as though it wasn't rendered at all.
You could try setting all children to display:none, and then override it with the display:block for the relevant child. Example:
#parent>* {display:none}
#parent>#child {display:block}

Center bootstrap's brand and list items

There are several questions about centering Twitter bootstrap's brand or centering the list items in the navigation bar, but I haven't figured out, how to center both.
Here is an example, used in Modify twitter bootstrap navbar, but it only centers the list items, not the brand.
Here is the structure of the HTML:
<div class="navbar navbar-fixed-top center">
<div class="navbar-inner">
....
</div>
</div>
And the CSS:
.center.navbar .nav,
.center.navbar .nav > li {
float:none;
display:inline-block;
*display:inline; /* ie7 fix */
*zoom:1; /* hasLayout ie7 trigger */
vertical-align: top;
}
.center .navbar-inner {
text-align:center;
}
Here a live demo: http://jsfiddle.net/C7LWm/
How would I center both the brand and the list items, so that both are centered on one line?
EDIT:
I just noticed that if you have a dropdown in the nav bar (like in your updated answer), the dropdown is really messed up (dropdown not showing up at all, if it shows up, the form background disappears).
A better way would probably be, if all the items are not centered and have a line by its one, instead they should all be on one line and then be centered, similiar to the non-responsive view, except now, there is a second line.
Is that possible?
To center a UL you don't need to write any classses.
Bootstrap provides everything you need, just do this:
<ul class="list-inline center-block text-center">
// your list
</ul>
What you need to center is not the <li> but their container. It doesn't matter if a child element is floating, only the parents that you actually want to center need to be inline-blocks.
I wouldn't say that it's nice, and you may need a different behavior on smaller screens, but this works in the demo :
.navbar .brand,
.nav-collapse {
float:none;
display:inline-block;
*display:inline; /* ie7 fix */
*zoom:1; /* hasLayout ie7 trigger */
vertical-align: top;
}
.navbar-inner > .container { text-align:center; }
Make sure your selectors are specific enough to target only the elements you want (i.e. not the collapse button)
Update with responsive navbar : Responsive demo
#media (max-width: 979px) {
.navbar .brand,
.nav-collapse {
display: block;
}
}

Float bug in chrome? 1px extra padding, but it's not padding

The following html and css shows two divs inside a container. The left div isn't floated; the right div is floated right.
The right div seems to be one pixel too narrow, and the red background color of the container is therefore showing through in that one pixel gap.
This is a simplification of my problem. http://jsfiddle.net/XPd9J/
HTML
<div class="inner-wrapper">
<div class="right-sidebar">
</div>
<div class="content">
<br /><br />
</div>
</div>​
CSS
.inner-wrapper {
position:relative;
background-color:red;
overflow:auto;
width:90%;
padding:0;
margin:20px 0 0 20px;
}
.right-sidebar {
position:relative;
width:40% !important;
background-color:lime;
float:right;
margin:0;
padding:0;
}
.content {
position :relative;
width:60%;
background-color:silver;
margin:0;
padding:0;
}
​
It's not the float that makes the problem. It's the percentage width. In FF and IE it works perfect, but Chrome calculates percentage width so, that not always the pixels sum up to the full 100%. Just try to slighty change the window width and you will notice the extra 1 px to disappear/appear sometimes.
How to avoid this behavior? You need to have use the same percentage somehow, so it is calculated just exactely the same. The right sidebar is 40% wide, so you need to have a right margin of 40% for the content div (these 40% are 40% of the containing block element)
http://jsfiddle.net/XPd9J/1/
.inner-wrapper {
background-color:red;
overflow:auto;
width:90%;
padding:0;
margin:20px 0 0 20px;
}
.right-sidebar {
width:40% !important;
background-color:lime;
float:right;
margin:0;
padding:0;
}
.content {
background-color:silver;
margin:0 40% 0 0;
padding:0;
}
​
Another easy option to get the full 100% is to set the parent element to overflow:hidden and your element to width:101%.
I also encountered that issue and I use two option the display:inline-table and display:table-cell in the parent div of the floated elements..although it is not a table, I use that as an alternative
For anyone coming to this in the future, it's possible to create left sidebar / content / right sidebar with liquid floats using the above method. It might be done like this:
Container div
right-sidebar width:30%;float:right;margin:0;padding:0;
content width:40%;float:right;margin:0;padding:0;
left-sidebar margin-right:70%;margin:0;padding:0;
End container div
Provided all the containers have margin:0;padding:0; then this works in FF, IE, Chrome, Safari and Opera (latest) without a problem. Genius. The dodgy browsers should have had this problem solved a long time ago - one can only guess that web designers don't often need pixel perfect placement of sidebars otherwise there would have been huge pressure on the browser builders.
You got two non-breaking spaces there. character causes the 1px extra space on the left of the right sidebar. Btw, position: relative is redundant in this context (it's only useful when you have to fix something in IE6).
Set "inner-wrapper" to overflow hidden (just in case). Then on the right div use calc(40% + 1px) to fix the issue.

Resources