CSS :nth-child(even) doesn't work correctly - css

I have simple css and html code and i wondering why last vertical image not working. I mean it border and margin should be added to last element not first.
Is anyone knows why this not work?
See in https://jsfiddle.net/st2Lwrgj/
* {margin: 0; padding: 0;}
.wrap {width: 250px; border: 1px solid red;overflow:hidden;}
img {
display: block;
width: 100%;
height: auto;
margin-bottom: 10px;
}
img.vertical {
width: 45%;
float: left;
margin-right: 10px;
}
img.vertical:nth-child(even) {
margin-right: 0px;
border: 2px solid blue;
}

:nth-child(even) will apply to every second image (second, fourth and so on). When you insert a horizontal image without the .vertical class you will break this order.
The following is a bit of a workaround, but the logic is pretty simple.
First we select every second image using img.vertical:nth-child(even)
We then find images without the .vertical class using:not(.vertical)
We then use the general sibling selector to select the following images and revert the order using img.vertical:nth-child(odd) instead of even.
As we have now applied borders to both odd and even ocurances of img.vertical, we need to remove the styling from the images we selected at point 1. We do this with a selector as set in point 3, but with even instead of odd: img:not(.vertical) ~ img.vertical:nth-child(even)
TLDR; change this part:
img.vertical:nth-child(even) {
margin-right: 0px;
border: 2px solid blue;
}
Into the following:
img.vertical:nth-child(even),
img:not(.vertical) ~ img.vertical:nth-child(odd) {
margin-right: 0px;
border: 2px solid blue;
}
img:not(.vertical) ~ img.vertical:nth-child(even) {
margin-right: 10px;
border: 0;
}
You can see how this works in this fiddle.

Related

How to get rid of white space without breaking words?

I am trying to make a paragraph to fit the width of a text however, I am getting this white space on line breaks. I am looking for any solution that wouldn't affect text and wouldn't require JavaScript (that could cause a reflow). Doesn't have to be inline-block.
* {
margin: 5px;
padding: 5px;
}
div {
background: gray;
}
p {
background:white;
border-bottom: 1px dotted black;
display: inline-block;
max-width: 130px;
}
<div id=container>
<p>technique and statement a landscape or discovery a injection or fic</p>
</div>
Demo Fiddle
Is there any way that I can make paragraph width match the width of the longest line?
Here is the expected and current result:
* {
margin: 5px;
padding: 5px;
}
div {
background: gray;
max-width: 130px; // you can ignore this if you dont need to be 130 px
}
p {
background:white;
border-bottom: 1px dotted black;
display: inline-block;
width:100%;
}
As #skyline3000 mentioned:
"match the longest line" - as #James said, there is only one line. You are artificially making line wraps with the max-width. You either need to put real line wraps into the text, or continue to adjust the max-width.
You need to manually specify line breaks which work for me - handling line breaks is rather an easy job for regular users.
body {
background: gray;
}
#container {
background: white;
display: inline-block;
}
span {
border-bottom: 1px dotted black;
max-width: 130px;
background: white;
}
<div id=container>
<span>technique and<br>statement alandscape<br> ordiscovery ainjectn or
fic i</span>
</div>
JsFiddle
Also, I have decided to move to the span element and wrap it into display: inline-block to achieve this result. I don't know if this result is satisfying to you, I'm not sure if I was trying to fight HTML/CSS spec here. Real line breaks are probably the only solution.

how to extract css rule with special color in files

could every one help me in this case, i have arounds 20k line css from multiple file css,
i need export only one rule for common style :
the file css example :
#course-main .lay-06 .content-01,
#course-main .lay-06 .content-02,
#course-main .lay-06 .content-03 {
width: calc(100% - 10px) !important;
height: calc(33% - 10px) !important;
margin: 5px !important;
flex-shrink: 0;
flex-grow: 0;
}
.view-slide {
width: 14px;
height: 14px;
display: inline-block;
border-radius: 7px;
cursor: pointer;
border: 1px solid #colorPrimary;
}
and i want to export this to:
.view-slide {
border: 1px solid #colorPrimary;
}
mean remove another rules except css have line with #colorPrimary;
could i achieve my goal with regex ?
You can try this:
/([\w#\.\-]+)\s*{[^{]*?([^;{]*#colorPrimary)/gms
The first group has the CSS selector and the second has the propriety.
You can try it here

How to add this vertical divider in navbar?

I need to create this kind of divider (the vertical line before browse and avatar). I don't want to use images, so is there a way to make in css?
I have tried:
.hr_v {
width: 1px;
height: 80px;
border: 0;
border-left: 1px solid;
color: gray;
background-color: gray;
}
The css shall be applied on the floated div, not a hr tag.
hr cannot be applied vertically Is there a vr (vertical rule) in html?.
You need to only set the border-left and add the border color since it was missing in your code, you can also add a left padding for better view :
#floatingAvatarDiv
{
border-left: 1px solid gray;
padding-left: 2px;
}
or create a class since you need it for both divs :
.leftBorderDiv
{
border-left: 1px solid gray;
padding-left: 2px;
}
and add it to your menu container and the avatar container divisions
You could use :before
.avatar {
position: relative;
height: 80px;
border-left: 1px solid gray;
}
.avatar:before {
position: absolute;
top: 0;
bottom: 0;
left: 1px;
content: '';
width: 1px;
background-color: #333; /* different gray */
}
In case your "Browse" button's container is bigger, you may get longer borders. In such case, you may simply try a "|" (a pipe) in a span before the "Browse" button and style to however you want. In this case, you wont have to use a lot of css styling.

How to make last element in a series of wrapped inline-block elements fill the available horizontal space?

I have an element which will contain an unspecified number of inline-block elements which may wrap if there are enough elements.
I want the last element to fill the remaining space on the line. How can this be accomplished?
Example HTML
<div class="tags">
<span class="tags__item">First Tag</span>
<span class="tags__item">Another One</span>
<span class="tags__item">Long Tag Name Here</span>
<span class="tags__item">Last tag should fill</span>
</div>
Example CSS
.tags { border: solid 1px #000; padding: 0; }
.tags__item {
display: inline-block;
margin: 2px;
padding: 1px 5px;
background: #eee;
border: solid 1px #eee;
}
.tags__item:last-child {
background: #fff;
border: dashed 1px #eee;
}
Attempt #1 (doesn't work)
One answer (which was deleted) mentioned trying table-cell layout like this..
.tags {
border: solid 1px #000;
display: table-row;
white-space: nowrap;
}
.tags__item {
display:table-cell;
width:auto;
margin: 2px;
padding: 1px 5px;
background: #eee;
}
.tags__item:last-child {
background: #fff;
border: dashed 1px #ccc;
width:99%
}
This solution works reasonably well for a single line. However, it doesn't allow wrapping. http://cdpn.io/omFuy
Attempt #2 (doesn't work)
Someone else linked to another SO answer as a possible solution.
.tags {
border: solid 1px #000;
}
.tags__item {
display: block;
float: left;
margin: 2px;
padding: 1px 5px;
background: #eee;
}
.tags__item:last-child {
float: none;
display: block;
border: dashed 1px #ccc;
background: #fff;
}
.tags__item:last-child::after {
clear:both;
}
But it doesn't work. See my implementation.
For browsers that support it, the natural solution is to use the flexible layout module, aka flexbox—this is exactly the sort of scenario it is intended for. Here are the bare essentials:
Demo on Dabblet
.tags {
display: flex;
flex-wrap: wrap;
}
.tags__item:last-child {
flex: auto;
}
The (not insignificant) downside to this approach is the lack of browser support and the attendant mess of prefixes and fallbacks if you need to support older browsers. As suggested by Rafael in the comments, this CSS Tricks article outlines the required prefixes and the legacy syntax.
Definitely not the best solution ... but I just did not resisted to try a javascript solution.
http://codepen.io/rafaelcastrocouto/pen/morlb
Still need to check for "line-breaks", but it can be useful since jQuery probably turns this cross browser.

CSS Borders - outlining a group of DIVs neatly

I'm having a 'blonde moment' here - I'm sure this is easy but I can't seem to figure it out.
I have a grid of DIVs (10 rows which are CLEAR:BOTH - each with 10 FLOAT:LEFT DIVs of a fixed size).
What I want to do is assign a border to a group of these and this works (with the non-bordered sides/cells having a transparent border to keep everything aligned) BUT the way individual borders work, the 'corners' leave an ugly effect.
See this for an example
Am I missing an obvious trick to just make that a solid box rather than the 'dotted line' effect the corners are creating??
To clarify my CSS - the rows have this class
.row {
clear: both;
}
and the cells have this class
.cell {
float: left;
border: 5px solid transparent;
}
as well as between 0 and 4 classes like this one
.top { // repeated for bottom, left and right ofc.
border-top: 5px solid black;
}
Compare this:
div {
border: 3px solid white;
border-right: 3px solid black;
}
To this:
div {
border: none;
border-right: 3px solid black;
}
EDIT
The accepted solution was to make the padding take the place of the border, which would make the borders squared off. See:
http://jsfiddle.net/kCd7s/2/
If you put a border on the entire square, this is how border behaves. If you want to avoid this you should give the boxes with a black border dimensions on the sides not having a border equal to the width of the border, so add border: none first, then add dimensions, like if normal height is 20 and border is 5, and you want a border on the right, you would set: height: 30; width: 25; border-right: 5px solid;
Or try this way:
.top::before,
.bottom::before,
.left::after,
.right::after {
content: ".";
width: 100%;
height: 100%;
background: black;
display: block;
font-size: 0;
position: absolute;
}
.top::before {
height: 5px;
}
.bottom::before {
height: 5px;
top: 35px;
}
.left::after {
width: 5px;
}
.right::after {
width: 5px;
left: 35px;
}

Resources