CSS selector to create a CSS style if a parent has one child, and a different one for two children - selector

Is it possible to use pure CSS selectors to give a nodes children (in my case ULs) different properties, in particular height, based on the amount of siblings the child have?
For example, if a node has 1 child, the height of the UL is automatic, however if the node has 2 children, then those children's height is say '200px'?

Are you looking for:
If the list item is the only child, its height will be auto. If there are multiple list items, the list items will all have a height of 200px.
ul li {
height: 200px;
}
ul li:only-child {
height: auto;
}
Just to note, only-child is supported on all browsers except for IE8 and older.
http://reference.sitepoint.com/css/pseudoclass-onlychild

I'm not fully sure about browser compability, but
ul li:first-child:last-child {
height: auto;
}
Works aswell and in the end, makes a whole lot of sence :)

Assuming that the reason of the question is that your UL's are generated dynamically you can use the same code to define an unique ID's to those UL's so the CSS can be applied properly

CSS is not a logical language. You can't use "if this do that" logic. So you should use jQuery for this practice.
EDIT
Here is your required code
var liCount = $("ul li").size(); // How many list items UL' have
var constant = 10; // Constant px Value for calculate new pixel.
$("ul li").css("height",constant*liCount); //Css manipulation
$(".result").html(constant*liCount+"px is the li's height"); // what is the result
<ul>
<li>First List Item</li>
<li>Second List Item</li>
<li>Third List Item</li>
<li>Fourth List Item</li>
</ul>
You can test this
in jsfiddle (i defined height in jquery for seeing changes)
http://jsfiddle.net/guJBt/1/

Related

Smalltalk Seaside display in threes without using tables

I have built a web site for my local plastic model club which involves showing multiple images on a page. I like to show them 3 abreast. Up to now, I have done this using a nested series of table codes which gets very messy.
Is there a simpler way. Let us say that I have 12 images and I want to show them three across and 4 rows down. I can do this using html table, html table row, etc. but it gets very complicated with lots of if statements, etc.
As I have had problems maintaining the web site from day to day, I have taken down the seaside version but you can see an example of the type of display on the current home page at http://www.ipms-clacton.org.uk under "A selection of member's models"
David
If you want to make the table programmatically you could use the following code as a new message in your class. If you pass it the html and an orderedCollection it makes a new table 3 items wide and as many rows as it takes. The final row can be less than three elements. You will need to change it to display images rather than text but it's a place to start. The removeFirst: command removes a number of items from an ordered collection and returns those items as a new collection. That lets you break the collection apart into elements for your individual rows. Here is the message's definition:
make3Table: html using: anOrdCollection
html table: [
[ anOrdCollection size >= 3 ] whileTrue: [ html tableRow: [
(anOrdCollection removeFirst: 3) do: [ :item | html tableData: item ]
].
].
anOrdCollection isNotEmpty ifTrue: [
html tableRow: [
anOrdCollection do: [ :item | html tableData: item ]
]
].
]
The question isn't Seaside specific, but HTML/CSS related.
The solution for that is to use any element inside a container, and use CSS-grid layout for that container.
E.g.
.gallery-container {
display: grid;
grid-template-columns: repeat(1, 1fr);
grid-gap: 20px;
padding: 20px;
}
.image-container {
display: flex;
background-color: navy;
color: white;
align-items: center;
justify-content: center;
height: 150px;
}
#media (min-width: 600px) {
.gallery-container {
grid-template-columns: repeat(2, 1fr);
}
}
#media (min-width: 960px) {
.gallery-container {
grid-template-columns: repeat(4, 1fr);
}
}
<html>
<body>
<div class="gallery-container">
<div class="image-container"></div>
<div class="image-container">2</div>
<div class="image-container">3</div>
<div class="image-container">4</div>
<div class="image-container">5</div>
<div class="image-container">6</div>
<div class="image-container">7</div>
<div class="image-container">8</div>
<div class="image-container">9</div>
<div class="image-container">10</div>
</div>
</html>
It will work for any number of elements, and it has two CSS width breakpoints to show 1, 2 or 4 elements per row.
Then the Seaside part is only about generating that container and the elements using the canvas tags.
If you don't want to use a table another couple simpler ways to do it with css + seaside is with CSS columns:
html div
style:'columns:3';
with:[ myCollection do:[:ea | html div:ea]]
There are several css styling rules for columns.
Or using CSS flexbox
html div
style:'display:flex; flex-direction:row; flex-wrap:wrap; justify-content: space-between';
with:[
myCollection do:[:ea | html div
style:'width:32%';
with: ea]
]
Those style: rules could/should be in your CSS file as a CSS class

Can I get specific "dl" i.e. at First or Second index out of many identified by a CSS Selector in my App

I'm trying to automate a functionality using selenium in my Application Chrome browser. It's an SVG graph based page and shows details upon mouse over it. And this is identifiable with a CSS selector which is returning more than one matching elements(i.e. 6-7 dl , these dls has few child tags then internally containing the values I need to verify -as attached), now my need to select them one by one at a time and verify text of them(which displayed on mouse over).
I got to know on google how to read nth-child from dl but not getting a way to select particular dl at first place.
For example-
my selector is: .d3-tip.n>dl
if I use -.d3-tip.n>dl>dt:nth-child(odd): its giving me all the attributes of dt.. ie 6 values but I nedd values only from fst dl.
Similarly.d3-tip.n>dl>dd:nth-child(even) returning the 6 values of respected dds..
In Actual my app has only one dl (on UI) but don't know why it displaying 6 in DOM...
Plz refer attachment and HTML for a clear understanding of DOM
<div class="d3-tip n" style="position: absolute; top: 44.5px; opacity: 0; pointer-events: none; box-sizing: border-box; left: 515px;">
<dl style="width:335px">
<dt>Space Name:</dt>
<dd>Space</dd>
<dt>Property Type:</dt>
<dd>Office</dd>
<dt>Quoted Area:</dt>
<dd>444 sf</dd>
<dt>Space Usage:</dt>
<dd>Business Park,Commercial School</dd>
<dt>Space Status:</dt>
<dd>For Lease</dd>
<dt>Possession Status:</dt>
<dd>Vacant</dd>
</dl>
<span class="d3-tip__pin"/>
</div>
<div class="d3-tip n" style="position: absolute; top: 44.5px; opacity: 0; pointer-events: none; box-sizing: border-box; left: 515px;">
<dl style="width:335px">
<dt>Space Name:</dt>
<dd>Space</dd>
<dt>Property Type:</dt>
<dd>Office</dd>
<dt>Quoted Area:</dt>
<dd>444 sf</dd>
<dt>Space Usage:</dt>
<dd>Business Park,Commercial School</dd>
<dt>Space Status:</dt>
<dd>For Lease</dd>
<dt>Possession Status:</dt>
<dd>Vacant</dd>
</dl>
<span class="d3-tip__pin"/>
</div>
<--! and so on up to 6 blocks of dl
nth-child is to find the nth-child of any immediate parent element. In your HTML DOM, dd is single child element of each div.d3-tip element. The repetitive child is actually your div.d3tip for it immediate parent element
So your selector has to be written as below to get the first set of dd,
div.d3-tip:nth-child(1)>dl>dd
Getting the second selector also works. This is most important while writing css selector. The second nth has to work. :).
Ok, so I am not sure which of the elements you want...
So... here is a snip that should give you help.
A) with hovering.
B) with looping through the elements.
C) Bonus learn about contains() functionality of XPath...
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.action_chains import ActionChains
url = "http://your_url"
path_to_chromedriver = "C:\path_to_chromedriver"
chrome_options = Options()
#chrome_options.add_argument("--headless")
chrome_options.add_argument("--start-maximized")
browser = webdriver.Chrome(executable_path=path_to_chromedriver,
chrome_options=chrome_options)
browser.get(url)
# list_of_dt_elements_to_hover = browser.find_elements_by_xpath("//div[contains(#class,'d3-tip')]//dl/dt")
list_of_dt_elements_to_hover = browser.find_elements_by_xpath("//div[class='d3-tip n']//dl/dt")
list_of_dd_elements_to_hover = browser.find_elements_by_xpath("//div[contains(#class,'d3-tip')]//dl/dd")
hover = ActionChains(browser).move_to_element(list_of_dt_elements_to_hover[0])
hover.perform()
for dd_ele in list_of_dt_elements_to_hover:
hover = ActionChains(browser).move_to_element(dd_ele)
hover.perform()
print(dd_ele.text)
for dd_ele in list_of_dd_elements_to_hover:
hover = ActionChains(browser).move_to_element(dd_ele)
hover.perform()
print(dd_ele.text)
I hope you find this helpful!

Get a css property with selenium webdriver by selectors

I am doing a exercise with client java to use cssSelector method to retrieve some objects having a particular web element's CSS property.
The statement
driver.findElements(By.cssSelector(".item-result .content-main .block-opening"))
returns all elements from page using the class ".item-result .content-main .block-opening" (refer to my blocks below) and all is fine up to there!
Nevertheless, I only want those which have a property text-indent whose value is -999em. To perform it, I first use
driver.findElements(By.cssSelector(".item-result .content-main .block-opening[text-indent]"))
to retrieve all elements having a text-indent css property but I realize that no element is matching while I have text-indent property inside my css block.
HTML block
<html id="ng-app" data-ng-app="rwd" data-ng-controller="AppCtrl" lang="fr" class="ng-
scope">
<head>...</head>
<body>
...
<span class="block-opening icon-time-filled ng-scope" data-ng-if="bloc.openClosed ==
'O'">Ouvert</span>
...
</body>
</html>
CSS block
.item-result .content-main .block-opening {
width: 25px;
color: #a1a1a1;
text-indent: -999em;
}
I was hoping to find exactly what i want to by the use of
driver.findElements(By.cssSelector(".item-result .content-main .block-opening[text-indent='-999em']"))
Since elements related to text-indent are not found, I am blocked to find those having text-indent to -999em.
Please any help would be appreciated!
Perhaps a little bit of a longer route but you could try getting a list of all the elements and checking the css-properties, with the appropriate method.
List<Webelement> elements = driver.findElements(By.cssSelector(".item-result .content-main .block-opening"));
for (Webelement element : elements) {
if (element.getCssValue("text-indent").equals("-999em")) {
return element;
}
}
Caveat, I've never tried to get the text-indent value, as such I can't guarantee that the above will work.
http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/WebElement.html#getCssValue(java.lang.String)
You can locate that element using xpath using inner text value
By.xpath("//span[text()='Ouvert']")

Putting a block level <span> element inside a <p> element

I know that <p> is to be used specifically with inline elements. But what if you change an inline element like <span> into a block-level element using { display:block } and contain it within a <p>?
ie.
<html>
<head>
<style>
p {
background: red;
height: 100px;
width: 100px;
}
p span {
display: block;
background: blue;
height: 50px;
width: 50px;
}
</style>
</head>
<body>
<p>
<span>I am a pizza</span>
</p>
</body>
</html>
Is that just wrong in every sense of the word? I know it is not common (ie. most would question why I didn't just use a div) but it's a hypothetical situation. It passes validation tests, but is it sloppy as all heck/bad practice? Would you scoff if you read that code?
A span element is always a text/inline/phrase element in HTML, and the HTML syntax rules that restrict p element content to such elements relate to HTML only. So they are not affected by CSS settings that may make a span a block element in the CSS (rendering) sense.
In CSS, you can assign any defined value to the display property, no matter what the element is like. CSS is ignorant of the meanings of elements as defined in HTML or other markup language specifications.
Thus, there is no formal objection.
Whether it is good style, or otherwise acceptable, is more complicated. There does not seem to be any statement on this in specifications, but it is reasonable to say that you should not change basic rendering features elements in vain. For example, in normal conditions, you should not use span and then say display: block in CSS, when there is the more logical approach of using div. One reason to this principle is that it keeps your document in a better shape in non-CSS rendering situations or when all or some of your style sheet is not applied.
On the other hand, you would not change display in vain if you have a text paragraph and you wish to render part of its content as a block, e.g. as a centered or indented line, possibly with a background color that stretches through the available width. You cannot use div inside p, so the more natural markup is not available.
Since the example is not a real one, it is impossible to say whether it is OK to deploy this approach in your case.
It's HTML5 valid and it's not that bad in certain situations e.g.
<p>
This is some text <span class="highlight">I am a pizza</span> and this is some more text...
</p>
.highlight {
background: yellow;
}

How to make a div to a input text form?

There is some drawbacks using textarea and input-text as input of text forms. textarea has a little annoying triangle in right-lower corner and input-text is a single-line input.
I try to have a input of text like the facebook update input form. The input auto resize after linebreaks. And the element or tag used was <div>. I said "used" because, after they redesigned Facebook, I can't figure-out which tag is used now. There is CSS property that enables the user to edit the text in a div element. I actually copied the CSS property, but now I lost it. Can someone tell me which CSS property it was? I have a weak memory that it began with the -webkit prefix though
If you use html5 you can use:
<div id="divThatYouCanWriteStuffIn" contenteditable>
<!-- you can write in here -->
</div>
If you couple this with the css:
#divThatYouCanWriteStuffIn {
min-height: 4em; /* it should resize as required from this minimum height */
}
To get rid of the 'annoying little triangle' in textareas:
textarea {
resize: none;
}
JS Fiddle demo of both ideas.
I know you can do this in javascript by doing getElementByID('mydiv').contentEditable='true';, but I do not know how this would be done in CSS
The Facebook update input field is a TEXTAREA element. The trick is to use the resize property:
textarea { resize:none; }
That will make the triangle disappear.
You should be able to add your style to a textarea like you do with tags like p, h1, h2 etc..
So you can target all textareas or ones with specific classes or ids on them
Example:
textarea {
font-size:11px;
font-family:Verdana, Arial, Helvetica, sans-serif;
font-weight:normal;
line-height:140%;
color:black;
margin:0 0 5px 5px;
padding:5px;
background-color:#999999;
border:1px solid black;
}
This example will target all textareas on the page.
Change textarea to .nameOfClass or #nameOfId if you want to target a class or an id.
Hope this helps.