I have markup that goes something like this
<div class='wrap'>
<div class='container'>
Body Container content
</div>
<div class='container'>
Footer Container content
</div>
</div>
I want to display a header containing, amongst other things, a logo above the first, body, container. This I accomplished by defining
.container::before
{
background-image(url(path/to/image.jpg);
background-size:cover;
content:'';
}
The above works. The problem is that the logo ends up not onlyu above the body content but also above the footer content which is not quite the desired result. I have played around with various combinations of
.container::before:nth-of-child(1)
{
}
.container:nth-of-child(1)::before
{
}
but I haven't quite found the right syntax to target the ::before pseudo element for the first .container instance. I hope that someone here will be able to tell me how it should be done.
If the worst comes to the worst I can do it with a spot of jQuery but I would like to avoid that.
Would you consider using <main> W3 4.4.14 The main element and <footer> 4.4.9 The footer element per HTML5 elements with class of .container on each? That way you can reference/target those elements without psuedo elements
main::before
{
background-image(url(path/to/image.jpg);
background-size:cover;
content:'';
}
This way the header/logo you are looking for would only appear above the first container only. Then if you need to apply pseudo elements to <footer> you could do something like:
footer::before
{
background-image(url(path/to/image.jpg);
background-size:cover;
content:'';
}
OK so I'll add another answer because it doesn't appear that anyone has solved all of your issues.
First, there is a typo in your css: background-image(url(path/to/image.jpg) is missing the closing paren.
To do what you want, however, there is a simple css selector :). In your example, you try nth-to-child(), but the correct syntax for what you want is nth-child(). Look below for two options, with a working demo.
.container:first-child:before
{
display: block;
content: "Before Element";
/* other styling that you choose*/
}
/* the following selector will also work
.container:nth-child(1):before
{
display: block;
content: "Before Element";
}
*/
<div class='wrap'>
<div class='container'>
Body Container content
</div>
<div class='container'>
Footer Container content
</div>
</div>
Note that the display: block; part is so that the before content appears on it's own line, since :before elements by default are display: inline-block;.
I dont think that there is a way to making it work with nth-of-child, but it will definitely work with first-child (if you always need it only in the first element with class .container):
.container:first-child:before
{
background-image(url(path/to/image.jpg);
background-size:cover;
content:'';
}
My first thought here is that there should be an additional class for the header, or use the <header> and <footer> elements in place of divs. For example:
<div class="wrap">
<div class="container header">
Header
</div>
<div class="container footer">
Footer
</div>
</div>
and
.header::before {
// stuff to make your logo
}
However, if for some reason you can't change the html, then the :first-child selector should work for your needs, as others have answered.
If you want to use nth-child() you need to add it to the parent of the element that you want to select. In this case .wrap.
.wrap:nth-child(1):before
{
background-image(url(path/to/image.jpg);
background-size:cover;
content:'';
}
Related
I was trying to parse from a complicated html page, but someone told me a better way is to inject my own css into that html. So I have the following situation:
<html>
<head>
<link rel="stylesheet" type="text/css" href="test.css" />
</head>
<body>
<div>
layer one div
<div id="center">
layer two div
<div>
layer three div
</div>
</div>
</div>
</body>
</html>
As you can see the div with id is sandwiched between a parent div and a child div.
I wonder if it is possible to hide the parent and child, making the page only show layer two div line. I try doing
div { display: none; }
div#center { display: inline;}
but without success.
I am using the indent method now, thank you for all the help, guys! : )
Here is kind of a hack, but it works:
HTML
<div>
layer one div
<div id="center">
layer two div
<div>
layer three div
</div>
</div>
</div>
CSS
div {
text-indent: -9999px;
}
div#center {
text-indent: 0px;
}
div#center div {
display: none;
}
Fiddle: http://jsfiddle.net/fPdda/2/
As far as I know, there is no option to show element which is placed under hidden element. So CSS will not do the trick. The only possible option is use javascript, which move element which is supposed to be visible out of parent. This can be easily done with jQuery.
However I don't know why you need this and what you mean with word "parse". CSS will affect only what you see, but under "parse" I understand processing data - and for processing is not important how it is shown. Maybe if you specify more detailed what you need, I can help.
This method will not work. Sadly, because your displayed div is inside a hidden div, you're sunk if you're stuck with that markup. You could get fancy and use text-indent: -9999px instead of display: hidden, then text-indent: 0px on the one you want to show, but the negative indented elements will still take up vertical space. Alternately, you could use JS to duplicate the node and re-insert it into the DOM at a different point, maybe inside an element that isn't hidden.
var nodeToShow = document.getElementById('center').cloneNode();
nodeToShow.setAttribute('id', 'centerClone');
document.body.appendChild(nodeToShow);
I don't think that is possible. Hiding the parent div takes precedence on the child, so your child with id is visible but only in the scope of parent div which is hidden. In order to accomplish what you trying to do just wrap the parent text in a span and hide the span;
div span{
display:hidden;
}
div#center div{
display:hidden;
}
You can't hide a parent yet make a child element visible, it just doesn't work that way. I would suggest doing something like this:
<div class="layer-one">
<span class="layer-one">layer one div</span>
<div id="center">
layer two div
<div>
layer three div
</div>
</div>
</div>
.
div,
span.layer-one {
display: none;
}
div.layer-one,
div#center {
display: block;
}
Let's say I have this HTML page:
<body>
<p id="alice">Alice</p>
<p id="bob">Bob</p>
</body>
and this pretend CSS syntax:
p#alice:before { p#bob }
In other words, I want to override the HTML using CSS, placing the Bob element ABOVE the Alice element. Why? Because in my case I can edit the CSS, and I cannot edit the HTML.
Bob doesn't have to actually occur before Alice in the DOM, but it does need to appear ABOVE Alice visually.
The only way to do this with pure CSS that is completely flexible is with flexbox.
http://jsfiddle.net/S9L3r/ (prefixes not included)
body {
display: flex;
flex-flow: column nowrap;
}
#alice {
order: 2;
}
http://caniuse.com/#feat=flexbox
You can always do this with jQuery if you are able to add the code.
$('#bob').insertBefore('#alice');
Thats easy but ugly and you shouldnt do it.
However here is how to do it:
http://jsbin.com/azevet/2/edit
<div class="first-in-dom">
Im first in DOM
</div>
<div class="second-in-dom">
Im second in DOM
</div>
div {
height:100px;
border:solid;
}
.first-in-dom, .second-in-dom {
position:relative;
}
.first-in-dom {
margin-bottom:-100px;
top:110px;
}
I'm trying to convert my site from using tables to just using css and divs but I'm running into a lot of problems with trying to figure how to exactly do it, I've been looking for tutorials on centering a site with css and how to put divs side by side but I can't really find one that does both and I keep getting confused by how to exactly achieve this, I asked around a bit and I got told to use absolute positioning but still I can't really wrap my head around this.
So basically how would I arrange the 2 central div side by side while keeping the whole thing centered in the browser? The following image is the layout I'm trying to achieve:
the blue boxes are eventual other stuff I might want to put in them, such as a blog requiring again the use of side by side divs.
right now I have the following layout:
<div id="wrap">
<div id="banner"> banner </div>
<div id="navbar"> navigation links </div>
<div id="body"> stuff </div>
<div id="footer"> stuff </div>
</div>
General idea: http://jsfiddle.net/JjbJE/
A little specific but provide you a great adventure to learn HTML | CSS : http://jsfiddle.net/JjbJE/3/
float:left|right this property does the side by side trick
clear:both this property clear away the float property
Other things are pretty easy to learn, just head to W3Schools
First you need a main container to center everything. Then two separate divs. See the HTML below:
<div id="main">
<div class="box">Left Box</div>
<div class="box">Right Box</div>
<div class="clear"></div>
</div>
Here is the CSS you will need:
#main{
width:960px;
margin:0 auto;
}
.box{
width:450px;
float:left;
border:solid 1px #000000;
}
.clear{
clear:both;
}
Hope that helps.
Here's my general overview on converting to a CSS based layout - if you have a table based layout, this is a good plan - in the end you can do more, Google will like you more, and it's much cooler.
My strategy is to look at all the groups of things on your page. Whatever needs to go into a group together, put inside a div. Assign this div a class and/or id to style it. If the divs are grouped, put them together in a div too.
In your case, you have two chunks of content to group inside of divs. Style them to be the size and shape you like, background, border, whatever is needed. Then group them together in an additional div, and center it. This and the rest of the page content can go inside a container div, which will determine the width of the page, how it's aligned, etc.
One possibility is to have a centered wrapper class and contain the divisons inside of that:
<div class="wrapper">
<header></header>
<div id="middle">
<div class="main-article clearfix"></div>
<aside></aside>
</div>
<footer></footer>
</div>
Then to style, center the wrapper, float the aside and main-article:
.wrapper { width: 1024px; margin: 0 auto; /* the auto centers it */ }
header, footer, aside, { display: block; }
.main-article { width: 50%; float: right; }
aside { width: 50%; float: left; }
.clearfix:before, .clearfix:after { content: ""; display: table; }
.clearfix:after { clear: both; }
.clearfix { *zoom: 1; }
Note: This is untested, and uses the clearfix from the HTML5 Boilerplate.
Update 01.22.2014: This "Holy Grail Layout" has ben solved by Flexbox. Check out Solved By Flexbox for more information on recreating this layout (and many more).
In the html fragment below, I want the "main" div to have a background image only if "menu" div is not present in the markup. Is this possible?
<div class="header">
<div class="siteTitle">site title</div>
<div class="tagline">site tagline</div>
<div class='menu'></div>
</div>
<div class="main"></div>
http://www.w3.org/TR/css3-selectors/
E + F Matches any F element immediately preceded by a sibling element E.
E:not(s) an E element that does not match simple selector s
edit :not uses a simple selector, so unfortunately you can't use it to filter by properties of children, only attributes of the element.
A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class.
You could however put a .empty class on the menu and still use it.
.header .menu:not(.empty) + .main {
background:pink;
}
This solution is the best of both worlds, javascript but using css as per normal.
javascript:
if ($('.menu').length == 0){
$('body').addClass('no_menu');
}
css :
body.no_menu .main{
background:pink;
}
The only pure css solution i see is only possible if you rearrange your html like so:
<div class="header">
<div class="siteTitle">site title</div>
<div class="tagline">site tagline</div>
</div>
<div class="menu"></div>
<div class="main"></div>
then you can use this css to only apply a property):
.menu { background: none }
.menu ~ .main{ background: url() } /* or .menu + .main if they are guaranteed to be adjacent to each other on the code */
in this example, you can see it at work: http://jsfiddle.net/tYhxr/
(test it by deleting the menu div and running it again)
check Keyo's asnwer for a link about how selectors work.
If you can't change the html, the javascript is the way to go.
I hope this helps.
You could add a second class to your main <div> that only serves to add the background you want. Then when you create the markup, you just add the second class specifier to the <div> if you need it, or omit it if you don't.
div.main {
//main stuff
}
div.mainbg {
background: *background-specifications*;
}
When your menu div is present, you use this:
<div class="main mainbg">
And when it's missing, you stick with:
<div class="main">
I haven't played with CSS for too long a time and am without references at the moment. My question should be fairly easy but googling isn't bringing up a sufficient answer. So, adding to the collective knowledge...
|#header---------------------------------------------------------------|
| TITLE |
|#sub-title------------------------------------------------------------|
|bread > crumb | username logout |
|#sub-left | #sub-right|
|---------------------------------|------------------------------------|
That's what I'm wanting my layout to be. The heading anyways. I wanted sub-title to contain sub-left AND sub-right. What css rules do I use to ensure a div is bound by the attributes of another div. In this case, how do I ensure that sub-left and sub-right stay within sub-title?
Its quite a common misconception that you need a clear:both div at the bottom, when you really don't. While foxy's answer is correct, you don't need that non-semantic, useless clearing div. All you need to do is stick an overflow:hidden onto the container:
#sub-title { overflow:hidden; }
When you float sub-left and sub-right they no longer take up any space within sub-title. You need to add another div with style = "clear: both" beneath them to expand the containing div or they appear below it.
HTML:
<div id="sub-title">
<div id="sub-left">
sub-left
</div>
<div id="sub-right">
sub-right
</div>
<div class="clear-both"></div>
</div>
CSS:
#sub-left {
float: left;
}
#sub-right {
float: right;
}
.clear-both {
clear: both;
}
This should do what you are looking for:
<html>
<head>
<style type="text/css">
#header {
text-align: center;
}
#wrapper {
margin:0 auto;
width:600px;
}
#submain {
margin:0 auto;
width:600px;
}
#sub-left {
float:left;
width:300px;
}
#sub-right {
float:right;
width:240px;
text-align: right;
}
</style>
</head>
<body>
<div id="wrapper">
<div id="header"><h1>Head</h1></div>
<div id="sub-main">
<div id="sub-left">
Right
</div>
<div id="sub-right">
Left
</div>
</div>
</div>
</body>
</html>
And you can control the entire document with the wrapper class, or just the two columns with the sub-main class.
I agree with Darko Z on applying "overflow: hidden" to #sub-title. However, it should be mentioned that the overflow:hidden method of clearing floats does not work with IE6 unless you have a specified width or height. Or, if you don't want to specify a width or height, you can use "zoom: 1":
#sub-title { overflow:hidden; zoom: 1; }
This answer adds to the solutions above to address your last sentence that reads:
how do I ensure that sub-left and sub-right stay within sub-title
The problem is that as the content of sub-left or sub-right expands they will extend below sub-title. This behaviour is designed into CSS but does cause problems for most of us. The easiest solution is to have a div that is styled with the CSS Clear declaration.
To do this include a CSS statement to define a closing div (can be Clear Left or RIght rather than both, depending on what Float declarations have been used:
#sub_close {clear:both;}
And the HTML becomes:
<div id="sub-title">
<div id="sub-left">Right</div>
<div id="sub-right">Left</div>
<div id="sub-close"></div>
</div>
Sorry, just realized this was posted previously, shouldn't have made that cup of coffee while typing my reply!
#Darko Z: you are right, the best description for the overflow:auto (or overflow:hidden) solution that I have found was in a a post on SitePoint a while ago Simple Clearing of FLoats and there is also a good description in a 456bereastreet article CSS Tips and Tricks Part-2. Have to admit to being too lazy to implement these solutions myself, as the closing div cludge works OK although it is of course very inelegant. So will make an effort from now on to clean up my act.
Seriously try some of these, you can choose fixed width or more fluid layouts, the choice is yours! Really easy to implement too.
IronMyers Layouts
CSS Layouts
Layouts Customization Guide
750 Pixel CSS Layouts
950 Pixel CSS Layouts
100 Percent CSS Layouts
more more more
Layout Gala CSS Layouts
Glish CSS Layouts
Code Sucks CSS Layouts
Max Design CSS Layouts
CSS Play CSS Layouts
You can also achieve this using a CSS Grids framework, such as YUI Grids or Blue Print CSS. They solve alot of the cross browser issues and make more sophisticated column layouts possible for use mere mortals.
Best and simple approach with css3
#subtitle{
/*for webkit browsers*/
display:-webkit-box;
-webkit-box-align:center;
-webkit-box-pack: center;
width:100%;
}
#subleft,#subright{
width:50%;
}
Something like this perhaps...
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<style>
#container
{
width:600px;
}
#head, #sub-title
{
width:100%;
}
#sub-left, #sub-right
{
width:50%;
float:left;
}
</style>
</head>
<body>
<div id="container">
<div id="head">
#head
</div>
<div id="sub-title">
#sub-title
<div id="sub-left">
#sub-left
</div>
<div id="sub-right">
#sub-right
</div>
</div>
</div>
</body>
</html>
#sub-left, #sub-right
{
display: inline-block;
}
Via Bootstrap Grid, you can easily get the cross browser compatible solution.
<div class="container">
<div class="row">
<div class="col-sm-6" style="background-color:lavender;">
Div1
</div>
<div class="col-sm-6" style="background-color:lavenderblush;">
Div2
</div>
</div>
</div>
jsfiddle: http://jsfiddle.net/DTcHh/4197/
You do it like this:
<table>
<tr>
<td colspan="2">TITLE</td>
</tr>
<tr>
<td>subleft</td><td>subright</td>
</tr>
</table>
EASY - took me 1 minute to type it.
Remember the CSS file needs to be downloaded to the client, so don't worry about the waffle about extra tags, its irrelavent in this instance.