Target a title having a subtitle sibiling in CSS [duplicate] - css

This question already has answers here:
Is there a "previous sibling" selector?
(30 answers)
Difference between the selectors div + p (plus) and div ~ p (tilde)
(5 answers)
Closed 4 months ago.
I want to remove the bottom margin of a title only in case it has a subtitle next to it.
Probably related to Is there a "previous sibling" selector? but that question does not answer my question.
.title, .subtitle {
border: 1px solid black
}
.title + .subtitle {
background: yellow;
margin-top: 0;
}
<header>
<h3 class="title">My title</h3>
<p class="subtitle">my subtitle: top space NOT OK!</p>
</header>
<p> some text lorep ipsum: top space OK</p>
<header>
<h3 class="title">My title</h3>
<p>my other text: top space OK</p>
</header>

as #blurk suggested .title:has(+ .subtitle) works in most modern (chromium + safari) browsers, + in FF accessible via flags (why people from FF do such a pervert things?)
.title:has(+ .subtitle) {
margin-bottom: 0;
}
.title, .subtitle {
border: 1px solid black
}
.title + .subtitle {
background: yellow;
margin-top: 0;
}
<header>
<h3 class="title">My title</h3>
<p class="subtitle">my subtitle: top space NOT OK!</p>
</header>
<p> some text lorep ipsum: top space OK</p>
<header>
<h3 class="title">My title</h3>
<p>my other text: top space OK</p>
</header>

Not sure that's what you need. Try this?
/*
This is a common technique called a CSS reset.
Different browsers use different default margins, causing sites to look different by margins.
The * means "all elements" (a universal selector), so we are setting all elements to have zero margins, and zero padding, thus making them look the same in all browsers.
*/
* {
margin: 0;
padding: 0;
}
/*
The comma groups classes (and applies the same style to them all. Just use the individually).
*/
.title {
margin-bottom: 0;
border: 1px solid black
}
.subtitle {
margin-bottom: 1rem;
background: yellow;
border: 1px solid black
}
p {
margin-bottom: 1rem;
}

Related

What is the difference between: > * and without it?

lets say i have this html:
<div class="wrapper">
<p>testOne</p>
<p>testTwo</p>
<p>testThree</p>
</div>
If i want to apply to the p tag design, i can go to CSS and use:
1)
.wrapper > * {
color: red;
}
OR
2)
.wrapper {
color: red;
}
Both of them work just fine, so, what is the difference?
I have heard once that the the first example apply the design only to the direct childs of the "wrapper", so then i did:
<div class="wrapper">
<p>testOne</p>
<div class="container">
<p>testTwo</p>
</div>
<p>testThree</p>
</div>
so testTwo is not a direct child..but he still got the color red!
so testTwo is not a direct child..but he still got the color red!
testTwo's parent <div class="container"> has the color red, though, so all of its children inherit that style. It's the same fundamental behavior as setting your body color to red and that reflecting on the whole document.
I have heard once that the the first example apply the design only to the direct childs of the "wrapper"
That's right.
Maybe border will better illustrate the difference between the selectors, since children don't inherit it:
.wrapper > * {
border: 1px solid red;
}
.wrapper {
border: 1px solid blue;
}
<div class="wrapper">
<p>testOne</p>
<div class="container">
<p>testTwoA</p>
<p>testTwoB</p>
</div>
<p>testThree</p>
</div>
Although you didn't ask about it, for context consider also .wrapper *, which selects all children regardless of depth, further illustrating >:
.wrapper * {
border: 1px solid green;
}
.wrapper > * {
border: 1px solid red;
}
.wrapper {
border: 1px solid blue;
}
<div class="wrapper">
<p>testOne</p>
<div class="container">
<p>testTwoA</p>
<p>testTwoB</p>
</div>
<p>testThree</p>
</div>
Note that order matters in the above example since .wrapper * and .wrapper > * are no longer disjoint as .wrapper and .wrapper > * are.

how to remove whitespace in css from title [duplicate]

This question already has answers here:
What is the default padding and/or margin for a p element (reset css)?
(5 answers)
How wide is the default `<body>` margin?
(4 answers)
Closed 1 year ago.
i am trying to place a title above some words but my title has a white space underneath, my css is
.title{
grid-template-areas:"image" "title"
}
.title_word{
grid-area: title;
}
.title_img{
grid-area: img;
}
<div class="title">
<p class="title_word">hello</p>
<img src="https://live.staticflickr.com/5549/10549969363_76ccf43946_b.jpg" alt="not working" class="title_img">
</div>
as you can see, this works but in firefox and chrome it is giving me lots of white space
Adding margin-bottom: 0 to the title class will do the job. the reason for that is because margins are used to create space around elements, outside of the defined borders so setting it to 0 will eliminate that extra gap.
the <p> tag has a default css property of margin-block-end: 1em; which is causing that extra gap you see.
.title{
grid-template-areas:"image" "title"
}
.title_word{
grid-area: title;
margin-bottom: 0;
}
.title_img{
grid-area: img;
}
<div class="title">
<p class="title_word">hello</p>
<img src="https://live.staticflickr.com/5549/10549969363_76ccf43946_b.jpg" alt="not working" class="title_img">
</div>
Before I start tinkering with CSS - I add an * selector, which removes default margins and padding.
* {
margin: 0;
padding: 0;
}
.title{
grid-template-areas:"image" "title"
}
.title_word{
grid-area: title;
}
.title_img{
grid-area: img;
}
<div class="title">
<p class="title_word">hello</p>
<img src="https://live.staticflickr.com/5549/10549969363_76ccf43946_b.jpg" alt="not working" class="title_img">
</div>
If you want to delete the whitespace underneath add:
margin-bottom: 0;
to your
.title
In the end it should look like this.
.title {
grid-template-areas:"image" "title"
margin-bottom: 0;
}
This is likely because of the margin that html things tend to have. try a margin: 0; or a margin-bottom: 0; if that doesn't work, try the same with the border: 0; and padding: 0; as that's what makes up the whole block.

What is the meaning of * in the following example? [duplicate]

This question already has answers here:
What does an asterisk (*) do in a CSS selector?
(5 answers)
Closed 7 years ago.
What is the meaning of * in this code ?
.descendants * {
display: block;
border: 2px solid lightgrey;
color: lightgrey;
padding: 5px;
margin: 15px;
}
<div class="descendants" style="width:500px;">div (current element)
<p class="1">p (child)
<span>span (grandchild)</span>
</p>
<p class="2">p (child)
<span>span (grandchild)</span>
</p>
</div>
* in CSS represents "any element".
In the above example, this will target any and all sub-elements of .descendants. Notice how the text in the first div is black, and the p and span content is grey and has a border? That is because the CSS selector is targeting those elements.

Pure CSS collapse/expand div

I have a pure CSS collapsable div which is based on someone else's code who uses the :target psuedoclass. What I am trying to set up is a page with 12+ questions, and when you click on the + button the answer div expands beneath. I cannot figure out how to make multiple collapsing div elements on this page without writing a ton of extra CSS. Anyone have suggestions on how to write this so my CSS code is minimized? (i.e., so i dont have to input a bunch of unique selectors for each of the 12+ questions).
I cannot use Javascript since this is going on a wordpress.com site which does not allow JS.
Here is my jfiddle: http://jsfiddle.net/dmarvs/94ukA/4/
<div class="FAQ">
+
-
<div class="question"> Question Question Question Question Question Question Question Question Question Question Question? </div>
<div class="list">
<p>Answer Answer Answer Answer Answer Answer Answer Answer Answer Answer Answer Answer Answer Answer Answer Answer Answer Answer </p>
</div>
</div>
/* source: http://www.ehow.com/how_12214447_make-collapsing-lists-java.html */
.FAQ {
vertical-align: top;
height:auto !important;
}
.list {
display:none;
height:auto;
margin:0;
float: left;
}
.show {
display: none;
}
.hide:target + .show {
display: inline;
}
.hide:target {
display: none;
}
.hide:target ~ .list {
display:inline;
}
/*style the (+) and (-) */
.hide, .show {
width: 30px;
height: 30px;
border-radius: 30px;
font-size: 20px;
color: #fff;
text-shadow: 0 1px 0 #666;
text-align: center;
text-decoration: none;
box-shadow: 1px 1px 2px #000;
background: #cccbbb;
opacity: .95;
margin-right: 0;
float: left;
margin-bottom: 25px;
}
.hide:hover, .show:hover {
color: #eee;
text-shadow: 0 0 1px #666;
text-decoration: none;
box-shadow: 0 0 4px #222 inset;
opacity: 1;
margin-bottom: 25px;
}
.list p{
height:auto;
margin:0;
}
.question {
float: left;
height: auto;
width: 90%;
line-height: 20px;
padding-left: 20px;
margin-bottom: 25px;
font-style: italic;
}
Depending on what browsers/devices you are looking to support, or what you are prepared to put up with for non-compliant browsers you may want to check out the <summary> and <detail> tags. They are for exactly this purpose. No css is required at all as the collapsing and showing are part of the tags definition/formatting.
I've made an example here:
<details>
<summary>This is what you want to show before expanding</summary>
<p>This is where you put the details that are shown once expanded</p>
</details>
Browser support varies. Try in webkit for best results. Other browsers may default to showing all the solutions. You can perhaps fallback to the hide/show method described above.
Using <summary> and <details>
Using <summary> and <details> elements is the simplest but see browser support as current IE is not supporting it. You can polyfill though (most are jQuery-based). Do note that unsupported browser will simply show the expanded version of course, so that may be acceptable in some cases.
/* Optional styling */
summary::-webkit-details-marker {
color: blue;
}
summary:focus {
outline-style: none;
}
<details>
<summary>Summary, caption, or legend for the content</summary>
Content goes here.
</details>
See also how to style the <details> element (HTML5 Doctor) (little bit tricky).
Pure CSS3
The :target selector has a pretty good browser support, and it can be used to make a single collapsible element within the frame.
.details,
.show,
.hide:target {
display: none;
}
.hide:target + .show,
.hide:target ~ .details {
display: block;
}
<div>
<a id="hide1" href="#hide1" class="hide">+ Summary goes here</a>
<a id="show1" href="#show1" class="show">- Summary goes here</a>
<div class="details">
Content goes here.
</div>
</div>
<div>
<a id="hide2" href="#hide2" class="hide">+ Summary goes here</a>
<a id="show2" href="#show2" class="show">- Summary goes here</a>
<div class="details">
Content goes here.
</div>
</div>
#gbtimmon's answer is great, but way, way too complicated. I've simplified his code as much as I could.
#answer,
#show,
#hide:target {
display: none;
}
#hide:target + #show,
#hide:target ~ #answer {
display: inherit;
}
Show
Hide
<div id="answer"><p>Answer</p></div>
You just need to iterate the anchors in the two links.
+
-
See this jsfiddle http://jsfiddle.net/eJX8z/
I also added some margin to the FAQ call to improve the format.
Or a super simple version with barely any css :)
<style>
.faq ul li {
display:block;
float:left;
padding:5px;
}
.faq ul li div {
display:none;
}
.faq ul li div:target {
display:block;
}
</style>
<div class="faq">
<ul>
<li>Question 1
<div id="question1">Answer 1 </div>
</li>
<li>Question 2
<div id="question2">Answer 2 </div>
</li>
<li>Question 3
<div id="question3">Answer 3 </div>
</li>
<li>Question 4
<div id="question4">Answer 4 </div>
</li>
<li>Question 5
<div id="question5">Answer 5 </div>
</li>
<li>Question 6
<div id="question6">Answer 6 </div>
</li>
</ul>
</div>
http://jsfiddle.net/ionko22/4sKD3/

xHTML/CSS: How to make inner div get 100% width minus another div width

I have 2 nested divs inside outer one, which has width:100%. Both nested divs should be in one line and first should get it size from it's contents:
<div id="#outer" style="width:100%; border:1px">
<div id="#inner1" style="border:1px; display:inline">
inner div 1. Some text...
</div>
<div id="#inner2" style="width:100%????; border:1px; display:inline">
inner div 2...
</div>
</div>
Question is how to make #inner2 div to get rest of the horizontal space if width of the #inner1 div is not specified and depends on what it is inside?
P.S. All styles are in separate classes in my case, here I putted CSS into style attributes just for simplification.
I want result to work in IE7+ and FF 3.6
In more details for me it looks like this:
<style type="text/css">
.captionText
{
float:left;
}
.captionLine
{
height: 1px;
background-color:black;
margin: 0px;
margin-left: 5px;
margin-top: 5px;
border: 0px;
padding: 0px;
padding-top: 1px;
}
</style>
<table style="width:300px;">
<caption width="100%">
<div class="captionText">Some text</div>
<div class="captionLine"> </div>
</caption>
<tr>
<td>something</td>
</tr>
</table>
Here is the image of what I want:
The mysterious overflow: hidden; is your friend here. It stops elements adjacent to floats from extending behind the float — I think that’s the layout you’re looking for.
Here’s some slightly edited HTML: I don’t think you can have # characters in your ids:
<div id="outer">
<div id="inner1">
inner div 1. Some text...
</div>
<div id="inner2">
inner div 2...
</div>
</div>
And here’s the CSS to achieve the layout you want.
(I put in additional CSS for IE 6 with HTML conditional comments. I just noticed you didn’t actually need it to work in IE 6 too, but if you fancy being nice to the IE 6 users out there...)
<style type="text/css">
#outer {
overflow: hidden;/* Makes #outer contain its floated children */
width: 100%;
/* Colours and borders for illustration purposes */
border: solid 3px #666;
background: #ddd;
}
#inner1 {
float: left;/* Make this div as wide as its contents */
/* Colours and borders for illustration purposes */
border: solid 3px #c00;
background: #fdd;
}
#inner2 {
overflow: hidden;/* Make this div take up the rest of the horizontal space, and no more */
/* Colours and borders for illustration purposes */
border: solid 3px #00c;
background: #ddf;
}
</style>
<!--[if lte IE 6]>
<style type="text/css">
#inner2 {
zoom: 1;/* Make this div take up the rest of the horizontal space, and no more, in IE 6 */
}
#inner1 {
margin-right: -3px;/* Fix the 3-pixel gap that the previous rule introduces. (Shit like this is why web developers hate IE 6.) */
}
</style>
<![endif]-->
Tested and working in IE 6, 7, and 8; Firefox 3.5; and Chrome 4.
If you're reading this now you can probably use calc, so be thankful.
HTML
<div class="universe">
<div class="somewidth">
</div>
<div class="everythingelse">
</div>
</div>
CSS
.universe {
width: 100%;
height: 100%;
}
.somewidth {
width: 200px;
height: 100%;
}
.everythingelse {
width: 800px; /* fallback for emergencies */
width: calc(100% - 200px);
width: -moz-calc(100% - 200px);
width: -webkit-calc(100% - 200px);
height: 100%;
}
See the working example on JSFiddle.
You would need to float the inner1 div to the left, like so:
<div id="#outer" ....>
<div id='#inner1" style="float:left; border: 1px solid #000;">
blabla
</div>
<div id="#inner2" style="... DON'T USE WIDTH AND DISPLAY HERE! ...">
gnihihi
</div>
</div>
This should do the trick. Check it out!
bye
You do not need to use div for nested element, just use SPAN like this
<div>
<span style="display:inline-block;width: auto;border: solid 1px black;">
hey you
</span>
<span style="display:inline-block;marging: 0px 2px;border: solid 1px black;">
always use proper tools.
</span>
</div>
Expanding on #Nasser Hajloo's answer, this works for me (even in IE6)
<div style="width: 400px; border: solid 1px red;">
<span style="float:left;width: auto;border: solid 1px black;">
hey you
</span>
<div style="display:inline-block;margin: 0px 2px;border: solid 1px black;">always use proper tools.</div>
</div>
Try it with the main div smaller than 400px to see how it adjusts. (It also works with divs rather than spans - the key is the width: auto in the first div/span.)
Try this: nest inner1 inside inner2, and remove the display:inline from inner2, like this:
<div id="#outer" style="width:100%; border:1px solid red">
<div id="#inner2" style="width:100%; border:1px solid black;">
<div id="#inner1" style="border:1px solid blue; display:inline">
inner div 1. Some text...
</div>
inner div 2...
</div>
</div>
You can see it working here: http://jsbin.com/adiwi
From your code it looks like you are trying to get a horizontal line to fill the empty space in your div. If I'm correct your looking to create a visual effect with markup. Correct me if I'm wrong.
(Would be nice to see an image of what you want)
Example:
Title ---------------------------
or
Title: Caption ------------------
This is not best practice. You should try to get this effect with CSS.
Try making your code more semantic first:
<div id="#outer" style="width:100%; border:1px">
<h3 style="border:1px; display:inline">
Caption
</h3>
</div>
To get the line:
create an image with the color you
want
make its height the same that you
want the line to be in px
position it with the background
property
.
#outer h3 {
display: inline;
background-color: #000;
color: #FFF;
}
#outer {
width: 100%; /* is the default of block element but just for celerity */
background: #000 url('image path') center left; /* position the image */
}
Your first problem is that you are prefixing your ids with a '#'. The # is only used in CSS to refer to the element with that id, e.g. the CSS rule #outer{width:100%} refers to your element:
<div id="outer"></div>
Also you don't need to use width's on div's (or any other block elements) that aren't floated, as they already automatically take up 100% of the available width.
If you want to the 2 DIVs to appear on the same line you have to float the first one to the left. The adjacent DIV will then appear on the side, again you don't need to sepecify widthd for the second element. Here is your complete example including a different coloured border for each div.
I've made the borders bigger so you can see clearer whats going on.
<html><body>
<style type="text/css">
#outer {
border: solid 5px #c00;
}
#inner1 {
border: solid 5px #0c0;
float: left;
width: 200px;
height: 300px;
}
#inner2 {
border: solid 5px #00c;
height: 300px;
margin-left: 210px; /* 200px left width + 2 x 5px borders */
}
</style>
<div id="outer">
<div id="inner1">
inner div 1. Some text...
</div>
<div id="inner2">
inner div 2...
</div>
</div>
</body></html>
Another solution is to run a javascript which resizes the captionLine class when document has loaded like this.
Took some time to get it working under IE8, have not tried IE7 but should work.
2 things to note.
IE does not support getElementsByClassName, therefor this function is rewritten.
IE handles margins differently when objects are resized and moved with style.marginLeft, somehow IE seems to keep the margin in the class declaration and adds this to the new style.margin.
<body onload="resizeCaptionLine()">
<style>
caption {
border: 1px solid blue;
padding: 0px;
}
.captionText {
border: 1px solid red;
float: left;
}
.captionLine {
background-color:black;
margin: 0px;
margin: 5px 0px 0px 5px;
border: 0px;
padding: 0px;
padding-top: 1px;
}
</style>
<table style="width:300px;">
<caption width="100%" name="caption1">
<div class="captionText">Some text</div>
<div class="captionLine"> </div>
</caption>
<tr>
<td>something</td>
</tr>
</table>
<table style="width:300px;">
<caption width="100%" name="caption2">
<div class="captionText">Some text</div>
<div class="captionLine"> </div>
</caption>
<tr>
<td>something</td>
</tr>
</table>
<script type="text/javascript">
function getElementsByClassName(node, class_name) {
elems = node.all || node.getElementsByTagName('*');
var arr = new Array();
for(j = 0; j < elems.length; j++)
{
if (elems[j].className == class_name)
arr[arr.length] = elems[j];
}
return arr;
}
function resizeCaptionLine()
{
var elems = getElementsByClassName(document, 'captionLine');
for(i = 0; i < elems.length ; i++)
{
var parent = elems[i].parentNode;
var sibling = getElementsByClassName(parent, 'captionText');
var width = parent.offsetWidth - sibling[0].offsetWidth;
if(elems[i].currentStyle)
{
var currentMargin = elems[i].currentStyle.marginLeft;
var margin = parseInt(currentMargin.substr(0,currentMargin.length-2));
elems[i].style.marginLeft = (sibling[0].offsetWidth) + "px";
}
else if (document.defaultView && document.defaultView.getComputedStyle)
{
var currentStyle = document.defaultView.getComputedStyle(elems[i], '');
var currentMargin = currentStyle.marginLeft;
var margin = parseInt(currentMargin.substr(0,currentMargin.length-2));
elems[i].style.marginLeft = (sibling[0].offsetWidth + margin) + "px";
}
else
{
var currentMargin = elems[i].style.marginLeft;
var margin = parseInt(currentMargin.substr(0,currentMargin.length-2));
elems[i].style.marginLeft = (sibling[0].offsetWidth) + "px";
}
elems[i].style.width = (width - margin)+"px";
}
}
</script>
</body>
Answer is really simple! If you have fixed div (menu) on the left side, then give fixed div float: left and your right flexible div margin-left that is bigger then width of first fixed div.

Resources