Is it possible to have a CSS rule that matches an element only if it contains a certain child?
Basically I have post content, where there could be inline images. I want all images to be centered but not the text. It looks like there is a patter to the inline images. They appear like this:
<p>Some text</p>
<p>
<!-- I want this p to be centered since it's an image -->
<img src="http://fpoimg.com/500x500"/>
</p>
<p>Some more text</p>
Is there any possible way without modifying the html to do this solely with some fancy CSS selectors? I know how to do it with jQuery, but I've always been interested if there are some new CSS selectors to help achieve this.
try this:
p>a>img{
display: block;
margin-left: auto;
margin-right: auto;
}
You can use something like p:nth-child(-n+3) to select elements of a certain type and pattern. (You'd have to create a parent selector though).
You could also use the basic cascade to apply a style to elements:
p img {styles}
see https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child for more info on patterns and how to use nth selectors.
For example:
p:nth-child(2n+1) {
background-color: lime;
}
<div>
<span>This span is limed!</span>
<span>This span is not. :(</span>
<em>This one is odd. </em>
<span>Sadly, this one is not...</span>
<span>But this one is!</span>
</div>
Tell me if this solves your problem:
p img {
display: block;
margin: 0 auto;
}
JSFiddle: http://jsfiddle.net/dpmytcjL/1/
Related
I have a problem in that I'm trying to show an <aside> text inline when a mouse is hovering over a defined keyword. The way I planned to do this to utilize the <span>, which wraps the <aside> and then I could use CSS selectors like #main > article > .inline-aside, aside { display: none; } to choose the descendant <aside> elements within these special purpose regions.
I seem to be able to hide the contents, but not to get them back. The problem might be, I'm a total CSS rookie, the display: none somehow removes the element. Is there a way to accomplish this using CSS alone?
Here are the relevant pieces and I have a fuller Fiddle at https://jsfiddle.net/Veksi/z0d5j1xb/.
<article id="faq-section-general" class="tab-content">
<h1>General</h1>
<p>The four Byzantine <span class="inline-aside">generals.<aside>General inline aside.</aside></span></p>
<p>Some more general text.</p>
</article>
The thing is that you can't use <aside> inside of a <p>. The <aside> would then be moved outside of the <p> which changes your DOM what makes it impossible to select the <aside> on hover of the .inline-aside as you can't go back in the DOM.
However, if you change your <p> for example to a <div> the correct selector logic would look like the following:
/* By default, hide aside blocks that have .inline-aside elements as parents. */
#main > article .inline-aside aside {
display: none;
}
/* Show the aside elements inside .inline-aside elements when they're hovered. */
#main > article .inline-aside:hover aside {
display: inline; /* or block */
}
Updated JSFiddle.
try (for you code example)
tab-content > p > span.inline-aside:hover + aside{
display:block/*or anything else*/
}
EDIT
You can also use transition to make things smoother, like this :
tab-content > p > span.inline-aside:hover + aside{
display:block;
transition: all 0.5s ease-in-out;
}
If the <aside> element is not critical for you, you could consider using an inline element as pop-up text.
I modified your code to use another <span> inside the .inline-aside element. Check it out here: https://jsfiddle.net/z0d5j1xb/3/
Hope that's what you needed.
Also, a general recommendation - avoid using deep nesting in CSS like #main > article > .inline-aside.
you have three issues
1
the span is inline element but aside is a block element
you can't put a block element inside inline element
the issue is that when you do so the browser render the block element outside the inline element
you can turn span to div
2
your selector > mean a direct child not a descendant so you must include the p element in your selector #main > article > p > .inline-aside or just use the space selector #main .inline-aside
3
is that you can't hover an element with display: none; you should use visibility: hidden;
here is a solution but you can still do better
We can use javascript/jquery for hiding or displaying data on hover event check out the following code,, In the snippet when u hover on the generals word it will show the content
$(document).ready(function(){
$( ".inline-aside" ).hover(
function() {
$('aside').css( 'display','initial')},function(){$('aside').css('display','none')} );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<body>
<article id="faq-section-general" class="tab-content">
<h1>General</h1>
<p>The four Byzantine <span class="inline-aside">generals.<aside class="a" style="display:none">General inline aside.</aside></span></p>
<p>Some more general text.</p>
</article>
</body>
I am making a theme for a website, but I ran into a problem. I can't change their HTML or use javascript, only CSS.
This is what the site's HTML looks like:
<div class="container">
<div style="margin:a ridiculously massive number">
<p id="title"> Title of page </p>
<p> Words that cannot be read because of the ridiculous margin </p>
</div>
<div id="otherContent"> There a lot of divs without ridiculous margin all with different ids </div>
</div>
I want to remove the ridculous margin without affecting the other divs margins. Is this possible?
yes you can target the div that is the first-child inside of .container as to not effect other divs.
.container div:first-child{
//code
}
EXAMPLE 1
Example 1 is specifically for the example you posted where the div you would like to target is the first child of it's parent. Also note if the margin is inline like your example you're going to have to over-ride it with !important like so:
.container div:first-child{
margin: 0 !important;
}
OR
You could also use the :not selector if the other's have a similar class
.container div:not(.classname) {
//code
}
EXAMPLE 2
The point of example 2 is if your div isn't the first child and the only without a class (it would probably be unlikely you would have multiple divs with the same classname except one but it's possible). in your example you could also use :not() to target that other div with id #otherContent like so:
.container div:not(#otherContent) {
//code
}
OR
The last option you can use if the others don't apply would be nth-of-type() to target specifically which one you want to effect:
.container div:nth-of-type(2) {
//code
}
EXAMPLE 3
In this case you will have to use first-child selector with !important keyword, as this is the only way to make rule more specific than style="margin" rule:
.container > div:first-child {
margin: 0 !important;
}
If all the other divs have ID you can use the following:
div>div:not([id]) {
margin: 0 !important;
}
I need to align pic-text-pic in a row.
<style type="text/css">
#element1 {background: url('url1'); margin-right: 10px}
#element2 {margin-right: 10px}
#element2 {background: url('url2')}
</style>
<div id="element1">
element 1 markup
</div>
<div id="element2">
element 2 markup
</div>
<div id="element3">
element 2 markup
</div>
I tried playing with it, just cant make it happend.
Any ideas?
You need to research the various display properties of CSS and how these create layout in the browser. DIVs are by default "block level elements" which means they're each going to break onto a new line.
For your example, you'll want to look into the "inline" or "inline-block" display properties, which will get your elements to line up next to each other (as long as there is enough space in the parent container). So, try this:
#element1,
#element2,
#element3 {
display: inline-block;
}
Try using <span> tags instead of <div>s.
Use display: inline-block:
#element1,
#element2,
#element3 {
display:inline-block;
}
use <span> and not <div>
I have this code.
<div class="myDiv">
<div>
I want to be red.
</div>
</div>
<p>I'm some other content on the page</p>
<div class="myDiv">
<div>
I want to be blue.
</div>
</div>
.myDiv div:nth-child(odd) {
color: red;
}
.myDiv div:nth-child(even) {
color: blue;
}
I see why it's not working. It's making every odd div within myDiv be red. What I want it to do is make every odd example of a div within myDiv be red. How can I write that?
Here's a JSFiddle.
There are a couple of problems here. The :nth-child is on the wrong element. The inner divs are always the first child, so the :nth-child(odd) selector works for both. Instead move to
.myDiv:nth-child(odd) div
...however this does not work either because of the <p>. A working solution with your sample is
.myDiv:nth-of-type(odd) div
http://jsfiddle.net/tvKRL/1/
NOTE that the nth-of-type only works because the .myDiv elements are all divs (it's based on the element, not the selector), so the selector ignores the <p>. If there can be another div between .myDivs I don't think any CSS will work for what you want to do.
You can't do this generically, for the reason given by Domenic. To put it simply: there's no selector that lets you filter an existing subset of matched elements.
On the off chance that among your p and div.myDiv siblings the only div elements are the ones with that class anyway, then you could use :nth-of-type() to have it look at those intermediate divs only:
div.myDiv:nth-of-type(odd) div {
color: red;
}
div.myDiv:nth-of-type(even) div {
color: blue;
}
Or if there are other divs without that class which should be excluded, then unless there is some sort of pattern in which they're laid out, you're out of luck.
This is not possible. There is no CSS selector that will do what you want, as you can see by perusing the complete list of selectors.
In general CSS selectors do not "reach out" to encompass elements above the DOM tree of the one selected. You are asking for something even more sophisticated than that, combining characteristics of parent elements with ordinal properties of the targeted elements, even though those targeted elements are distributed among entirely different places in the DOM tree.
Just applynth-childto the first member of the descendant selector, not the last one.
div:nth-of-type(odd) > div {
color: red;
}
div:nth-of-type(even) > div {
color: blue;
}
<div class="myDiv">
<div>
I want to be red.
</div>
</div>
<p>I'm some other content on the page</p>
<div class="myDiv">
<div>
I want to be blue.
</div>
</div>
I am trying to get a background color to stick strictly to the text of the heading and not span the entire width of the page. I understand that block level elements take up the entire width of the page, so I was wondering if there was a way around this besides forcing inline styles.
EDIT: If I were to use display: inline-block; why is it that even though I specify text-align: center; my headers are still left aligned? Should I use a float instead?
Or displaying as an inline-block could meet most use cases:
h1 {
background-color: red;
display: inline-block;
}
Perhaps something like this:
In HTML:
<div id="Heading">
<span id="HeadingText">HEADING TEXT</span>
</div>
In CSS:
#Heading
{
/* Formatting of full heading */
}
#HeadingText
{
/* Formatting for just heading text */
background-color: #00ff00;
}
Guessing from your question, this isn't the answer you are looking for, but it may be useful.
EDIT:
Alternatively, this should work as well. But I'm pretty sure this is what you want to avoid (inline, right?)...
<h1 style="background-color:#660000; display:inline;">Heading<h1>
This would solve this problem I think:
<div id="Heading">
<div id="HeadingText">HEADING TEXT</div>
</div>
And your css would be:
#Heading{
background-color:#CCC;
}
#HeadingText{
display:inline-block;
background-color:#FF0000;
}
You must specify the text-align:center; attribute to the parent element containing your div block to center your header and its background with display:inline-block;