Can I make a property to apply only to selected child elements? - css

Say for example I have the following code!
<div class="container">
<div class="container__first">I am a box maybe!</div>
<div class="container__second">I am a circle maybe!</div>
</div>
.container {
overflow: hidden; /*How can I make it so this property only applies to container__first but not
the second*/
}

you can do this with :nth-child(), select the div after .container with .container div and in the :nth-child() you can select wich child to select.
.container div:nth-child(1) {
overflow: hidden; /*How can I make it so this property only applies to container__first but not */
background: green; /* the second*/
}
<div class="container">
<div class="container__first">I am a box maybe!</div>
<div class="container__second">I am a circle maybe!</div>
</div>
edit the easiest way would be just styling on .container__first{} or .container .container__first{} if only selecting that child is what you need.

If you've already set the classes, container_first and container_second, you could just set different properties in the CSS. Just to make it simple, I'll make the text in first container bolded and the text in the second container italicized. See:
.container__first {
overflow: hidden;
font-weight: bold;
}
.container__second {
overflow: visible;
font-style: italic;
}
<div class="container">
<div class="container__first">I am a box maybe!</div>
<div class="container__second">I am a circle maybe!</div>
</div>
If you don't want to assign classes, there are a few other options. Like #ramon-de-vires said above, you could assign an :nth-child or :last-child node to the last child (or a specific child) in the CSS, as shown:
.container p {
overflow: hidden;
font-weight: bold;
}
.container p:last-child {
overflow: visible;
font-style: italic;
font-weight: normal;
}
<div class="container">
<p>I am a box maybe!</p>
<p>I am a circle maybe!</p>
</div>
Possibly the easiest way, though, is to utilize an !important declaration, which overrides and ignores subsequent styling rules in the CSS. Just add !important after the parameter of any property (but before the ;) to indicate that the values should supersede values defined elsewhere.

Related

alignment box for inline-block non-replaced elements

Please run the demo:
* {
margin: 0;
padding: 0;
}
.body {
font-family: Microsoft Yahei;
font-size: 16px;
background-color: lightblue;
height: 400px;
width: 400px;
line-height: 2;
vertical-align: baseline;
}
.body span {
background-color: pink;
}
.body .inline-block {
display: inline-block;
background: orange;
height: 50px;
}
.inline-block.text {
vertical-align: text-top;
}
<div class="body">
<span>
words-g words words-g
<span class="inline-block text">with inline-block box child</span> words-g w
</span>
</div>
The point is that I set
.inline-block.text {
vertical-align: text-top;
}
According to the specification:
In the following definitions, for inline non-replaced elements, the box used for alignment is the box whose height is the 'line-height' (containing the box's glyphs and the half-leading on each side, see above). For all other elements, the box used for alignment is the margin box.
and in the section 'line-height':
On a block container element whose content is composed of inline-level elements, 'line-height' specifies the minimal height of line boxes within the element. The minimum height consists of a minimum height above the baseline and a minimum depth below it, exactly as if each line box starts with a zero-width inline box with the element's font and line height properties. We call that imaginary box a "strut." (The name is inspired by TeX.).
So,in this case,.inline-block.textis a
block container element whose content is composed of inline-level elements
whose height is 50px and line-height is 32px
also is an inline non-replaced elements
And here is my question:
the box used for alignment is the box whose height is the 'line-height'
What is the above box point at in this case for .inline-block.text?
As the demo shows,I think it is the box with height 50px. However,the box's height is not the line-height which conflicts with the specification above. So,I was confused and don't understand the above sentence in the specification.
And if you think the above box is the box with height 50px,how do you explain the fact that height 50px is not the line-height 32px?
Please notice:
I just want to understand this sentence which is the box used for alignment is the box whose height is the 'line-height',so I can understand the vertical-align better.
I am not asking for a specific solution.
Whatever thanks for your help!
The statement
for inline non-replaced elements, the box used for alignment is the box whose height is the 'line-height'
does not apply to inline-blocks. Inline-blocks are not inline elements. Inline elements are elements with display: inline, and generate inline boxes. Inline-blocks are not inline boxes, but inline-level (the "-level" part is important!) block container boxes. Therefore, the statement
For all other elements, the box used for alignment is the margin box.
applies instead, which results in vertical-align: text-top causing the top outer edge of the inline-block to align with the top of the line box.
Any part of the specification that is said to apply to inline elements does not apply to inline-blocks.
I guess you are confusing about the reference of the alignment (it aligns relatively to what?).
I will try to explain this with easy words. When using vertical-align with an element a you align it relatively to its parent element b whataver is the height of a (b is the reference). Using correct words it's like this:
The vertical-align property can be used in two contexts:
To vertically align an inline element's box inside its containing line
box. For example, it could be used to vertically position an <img> in
a line of text.ref
So the a element is the inline element's box and the b element is the containing line box and the height of b is defined by it's line-height as you already read in the specification.
Now let's consider your code and add properties step by step.
Initially let's remove the inline-block
.body {
font-family: Microsoft Yahei;
font-size: 16px;
background-color: lightblue;
}
.body span {
background-color: pink;
}
.body .inline-block {
background: orange;
}
.inline-block.text {
vertical-align: text-top;
}
<div class="body">
<span>
words-g
<span class="inline-block text">inline-block</span> words-g w
</span>
</div>
As you can see the inner span has the same height/line-height as the outer span and both are using the same font-family. So logically we see nothing when using text-top as vertical alignment.
Now let's add line-height:2 to the container:
.body {
font-family: Microsoft Yahei;
font-size: 16px;
background-color: lightblue;
line-height:2;
}
.body span {
background-color: pink;
}
.body .inline-block {
background: orange;
}
.inline-block.text {
vertical-align: text-top;
}
<div class="body">
<span>
words-g
<span class="inline-block text">inline-block</span> words-g w
</span>
</div>
In this situation, both span will inherit the line-height:2 thus the computed value will be 32px (2 * font-size) and this will make the top reference different from text-top. To remind about this, here is a figure I shared with your beforeref:
And if we read the definition about the value text-top of vertical-align:
Aligns the top of the element with the top of the parent element's
font.
So the top of the inner span will align with the text-top of the outer span, that's why it moved to the bottom. Then the height of the main container .body will not be equal to 32px but it will be bigger because it will consider the movement of inner span (we will have 37px).
Now let's add inline-block to the inner element:
.body {
font-family: Microsoft Yahei;
font-size: 16px;
background-color: lightblue;
line-height:2;
}
.body span {
background-color: pink;
}
.body .inline-block {
background: orange;
}
.inline-block.text {
vertical-align: text-top;
display:inline-block;
}
<div class="body">
<span>
words-g
<span class="inline-block text">inline-block</span> words-g w
</span>
</div>
The first thing you will notice is that the text didn't move BUT the orange background is covering a bigger height. This is because our element will behave as block container and this height is the line-height of the text (32px) which is also the distance between the top and bottom in the image above (Initially it was covering from text-bottom to text-top).
It's also like the blue background of the .body element since this one is a block element. Try to make the .body element inline and see what will happen.
Now you can also add a specific height to the element and nothing will change because we align relatively to the parent element. You can also play with all the vaues of vertical-align to see the different behaviors:
.body {
font-family: Microsoft Yahei;
font-size: 16px;
background-color: lightblue;
line-height:2;
margin:5px;
}
.body span {
background-color: pink;
}
.body .inline-block {
background: orange;
}
.inline-block.text {
display:inline-block;
height:50px;
}
<div class="body">
<span>
Align the
<span class="inline-block text" style="
vertical-align: text-top;">top of this</span> with text-top
</span>
</div>
<div class="body">
<span>
Align the
<span class="inline-block text" style="
vertical-align: top;">top of this</span> with top
</span>
</div>
<div class="body">
<span>
align the
<span class="inline-block text" style="
vertical-align: text-bottom;">bottom of this</span> with text-bottom
</span>
</div>
<div class="body">
<span>
align the
<span class="inline-block text" style="
vertical-align: bottom;">bottom of this</span> with bottom
</span>
</div>

CSS: nth-of-type(2) is not being applied to class

Example page
The bottom right div containing "Student Visas" I thought would be affected by CSS:
.front-page-widget-portrait2:nth-of-type(2) .second-half {
height: 240px;
color: #FFF;
padding: 40.28436018% 40px 0 40px;
position: relative;
}
.front-page-widget-portrait2:nth-of-type(2) .second-half img {
position: absolute;
bottom: 0;
width: 49px;
margin: 0 auto;
display: inline-block;
}
It is contained in the 2nd div of class front-page-widget-portrait2, but .front-page-widget-portrait2:nth-of-type(2) is not being applied.
Can you see why not? Help appreciated.
Your markup is something like this
<div></div> <!-- Some more div elements around on the same level -->
<div class="front-page-widget-portrait2"></div>
<div class="front-page-widget-portrait2"></div>
<div></div> <!-- Some more div elements around on the same level -->
Instead of this, try wrapping your front-page-widget-portrait2 inside another div like
<div></div> <!-- Some more div elements around on the same level -->
<div class="front-page-widgets">
<div class="front-page-widget-portrait2"></div>
<div class="front-page-widget-portrait2"></div>
</div>
<div></div> <!-- Some more div elements around on the same level -->
Now, you can use a selector like
.front-page-widgets > div:nth-of-type(2) .second-half {
/* Styles goes here */
}
Let me break down the selector to explain to you how it works. We first select the wrapper element that is front-page-widgets (we just created a new one). Moving further, we use > which selects immediate children to wrapper element i.e div with a class of front-page-widget-portrait2. But as I already mentioned that nth- won't respect classes, so using it in the selector makes no sense. Lastly I use .second-half which selects the second block in your second widget.

Can I principally style the parent element based on child element using CSS3?

An Example: Only DIVs, that containing a LABEL should get the style text-align: right
Following try did not work:
div label:only-child {
text-align: right;
}
Not the label but the div should get this style.
you can use this way
div class="test" style="text-align:left"
div class="test" style="text-align:right"
The solution is to set the width of the label and display property to block. Here's the code
div{
width: 500px;
padding: 20px;
background: #fff;
border: 1px solid #ddd;
}
div>label:only-child{
text-align: right;
width: 100%;
display: block;
}
<div>
<label>adfasdf</label>
</div>
this cannot be done with CSS .
CSS = Cascading Style Sheets so by definition you can select elements from top to bottom of the HTML structure, not the other way around.
so you can't select a parent depending on it's children
you can do this with JQ , there are a number of ways to do it but this would be one of them :
$( "div:has(label)" ).css({ "text-align":"right" });
.div {
height:50px;
border:2px solid red;
margin:2px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="div">
<label>Has Label</label>
</div>
<div class="div">
<p>
i am NOT a label
</p>
</div>
<div class="div">
<label>Has Label</label>
</div>
You can't style parent element based on child element using CSS.
Since, it seems that you are trying to align the label element to right, you can do that using float as shown below:
div label:only-child {
float: right; /* instead of text-align: right */
}
Updated (parent has flexbox layout):
div label:only-child {
flex: auto;
text-align: right;
}
You cant't do this in CSS only. Well, of course you can add class to div but there is no parent selector.
But there will be in the future (selectors lvl4 - see last row of selectors overview): https://www.w3.org/TR/selectors4/

CSS Container Min-Height Max-Height declarations

I have some divs with alternating background-colors that i want to adjust in height depending on the heights of the nested divs within them.
Example is:
<div class="tableHolder">
<div class="oddRow">
<div class="col1">test1</div>
<div class="col2">test2</div>
<div class="col3">test3</div>
<div class="col4">test4</div>
</div>
<div class="evenRow">
<div class="col1">test1</div>
<div class="col2">test2</div>
<div class="col3">test3</div>
<div class="col4">test4</div>
</div>
</div>
the CSS declarations would be something along these lines.
.oddRow{
width: 130px;
min-height: 27px; (this is the default height for all rows unless "col" class grows larger/taller)
height:auto; (would like it to be able to grow if internal div is taller than 27px)
}
.evenRow would be along the same lines for css declarations. There are also obviously more with the background colors and stuff but i figured that would get the point across. Any help would be great.
fiddle: http://jsfiddle.net/AL7LB/
You are floating your elements. This is why the height doesn't work. You need to apply a clearfix.
.clearfix:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
* html .clearfix { zoom: 1; } /* IE6 */
*:first-child+html .clearfix { zoom: 1; } /* IE7 */
and you need to give the containing element the clearfix class, in your case <div class="tableHolderOdd">.
Working fiddle
Some infos about clearfix

How to make <div> inline? All <div>, even when their total width more than width of their parent?

I need to make <div> displayed inline and hide them with "overflow: hidden" for their parent.
Width for <div> is set to 20% with "box-sizing" property, so they are exactly 20% of their parent width.
The usual method, using "float: left" doesn't help, because it makes only 5 <div> displayed in one line, and the rest of them shown in new line under the first 5 <div>.
How to make all <div> displayd inline and hide the rest of them if they are too wide to be shown inside of their parent, using "overflow: hidden"?
I have the following document structure:
<body>
<div class="column">
<div class="header">Some text</div>
<ul class="item_list">
<li class="simple">Some text<br></li>
<li class="simple">Some text<br></li>
<li class="simple">Some text<br></li>
...
</ul>
</div>
You can see what I mean here. But I've made it using javascript (setted for <div> "position: absolute" and generated "margin-left" for each elemet) and it causes great problems for future development.
DEMO: http://jsfiddle.net/marcuswhybrow/7YDfE/3/
Use display: inline-block and white-space: nowrap in combination:
<div class="wrapper">
<div class="inline"></div>
<div class="inline"></div>
<div class="inline"></div>
</div>
Then use the appropriate CSS:
div.wrapper {
width: 200px; /* or whatever */
overflow: hidden;
white-space: nowrap;
}
div.inline {
display: inline-block;
}
The demo contains a little jQuery animation to illustrate the effect:
DEMO: http://jsfiddle.net/marcuswhybrow/7YDfE/3/
If the div elements are display: inline then applying white-space: nowrap; to the parent element will prevent their wrapping to new lines.
Since you have a known number of divs, have you tried using absolute positioning instead of floats, and specifying left:20% left:40%, etc.?
If you set the container div's height to a fixed value, and give all the inner elements display: inline-block, this should do the trick. inline-block will make each element align to the left, but keep it's dimensions, while the fixed height container will hide any that overflow to a new line.
This will do what you want with the addition of removing the white space between while allowing nice code formatting. The container gets font-size:0px ftw.
Markup
<div class="wrapper">
<div class="inline">Some text </div>
<div class="inline">Some sample text </div>
<div class="inline">Some Other text </div>
</div>
CSS
div.wrapper {
width: 250px; /* or whatever */
overflow: hidden;
white-space: nowrap;
border: 1px solid red;
font-size:0px;
}
div.inline {
display: inline-block;
width: 80px;
height: 20px;
background-color: black;
color:white;
margin: 0; padding: 0;
border: 1px solid blue;
font-size:12px;
}

Resources