Confused with BEM: how to deal with IMG and TABLE tags - bem

I'm trying to wrap my head around BEM naming convention in CSS, but for some parts I find it bit confusing.
In my case, my HTML (on a rough level) looks like this:
<div class="wrapper">
<img src="images/img.png">
<span class="header">Heading</span>
<table>
<tbody>
<tr>
<td class="itemInfo">
<span class="item">Item</span>
<span class="itemDetails">Item Details</span>
</td>
<td class="itemDate">01/01/1980</td>
</tr>
</tbody>
</table>
</div>
In my CSS I have defined styles for the .wrapper, .header, .item, .itemInfo, .itemDetails and .itemDate classes. Turning these into BEM should be straightforward.
However, my questions are related to some other tags in my HTML:
1) How do I deal with the IMG tag? It has styling defined in my CSS file:
img {
style definition 1;
style definition 2;
..
}
Should I BEM this element, both in HTML and in CSS files, by giving image tag a CSS class with BEM convention in my HTML file and also defining this very same class in my CSS, too?
2) In my example, how is TABLE tag understood in the BEM context? In other words, TABLE and TD selectors have their own style definitions in my CSS file (the same way as the IMG tag). Should I also treat those tags the same way as in the case of IMG tag (with/without BEM)?

BEM is designed to provide clarity to developers reading code, especially since CSS/Sass can get convoluted easily. For your <img> tag, I can make one of two assumptions:
You have styling you want to apply to all images, but also
specific styles to apply to this.
There are no other <img> tags and it doesn't matter.
Either way, you should create some CSS classes like so
.standard-img{
rule1: universal-value;
rule2: universal-value;
}
.img-to-style{
rule1: that-only-applies-to-this-img;
}
Obviously, your <img> HTML should look like this, then:
<img class="standard-img img-to-style" src="blah" />
As for the Table, what does it do? I'd do something like this:
<table class="ItemsTable">
<tbody>
<tr class="table__item-row">
<td class="item-row__info">
<span></span>
<span></span>
</td>
<td class="item-row__date">
// Content
</td>
</tr>
</tbody>
</table>
Makes sense, right? Mirror it in your CSS.

Related

Passing computed string to x-teleport in alpine.js

I want to append an element to a specific element when the user clicks the button. The scenario goes like this. Is there another way to deal with that kind of problem?
<table>
<tbody>
<tr>
<td>
One
<button>delete</button>
<button x-on:click="edit(passIdToFunc)">edit</button>
</td>
</tr>
<tr id="one" style="display: hidden"></tr>
<!-- append x-teleport dom node to here when current value is id = one -->
<tr>Two</tr>
<tr id="two" style="display: hidden"></tr>
<tr>Three</tr>
<tr id="three" style="display: hidden"></tr>
...
</tbody>
</table>
<!--
For the initial render, or if there is no table data,
I would like to append it to somewhere else with display none.
-->
<template x-teleport="computedString">
...
</template>
This looks like the wrong usage for x-teleport, though it's not clear from the example where you are teleporting to. You can just use x-show to toggle display:none if that's what you're looking for.

SASS: Applying style based on presence of child element type

I have a collection of tables nested within each other and background colors that are applied to each <td> in each row. I would ideally like to set the background as transparent on those <td> elements that themselves contain a child table, but I cannot identify how I'd specify this in SASS.
For example, I might have something like the following:
<table>
<tbody>
<tr>
<th>Data Point</th>
<!-- This should be styled with a red background -->
<td>0.025</td>
</tr>
<tr>
<th>Data Point</th>
<!-- This should be styled with a transparent background since it contains a table -->
<td>
<table>
<tbody>
<tr>
<th>Sub-point</th>
<!-- This should styled with a red background -->
<td>0.75</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
I can just have a naive selector like the following to apply the background on my td elements:
td {
background: #ff0000;
}
But it's not clear how I might then modify this (without adding another class to everything) to set the background to transparent if the <td> contains a <table>.
I'm ideally looking to avoid all use of JavaScript and only handle this through SASS.
Attempt #1
At first, the pseudo-class :has() looked promising, but the guidance in this issue suggests it cannot be used in this scenario.
Attempt #2
I could just specify a new class on the <td> containing the nested element and override the background style from there, but this isn't as clean an approach. I'll reserve this as the fallback solution, but a selector-based approach would be preferred.
Is this even possible?

XPATH Firebug filter does not filter as expected

Basically I have a list of presidents and I am only interested in the Nixon link and not Clinton or Obama.
What I find is that filtering as I have done returns the correct number of presidents (ie 1 in this case) but returns ALL of the a links instead of just the one for Nixon.
HTML:
<div class="headlineBlock">
<h2>Obama</h2>
<p class="tudor"><strong>Conditions:</strong> Always sunny </p>
<table class="resultGrid"><tr> <td class="first">
<h4><a href="http://www.thelinkiwant.com?params" title="Click to view result"</a></h4>
<div class="headlineBlock">
<h2>Nixon</h2>
<p class="nixon"><strong>Conditions:</strong> Sometimes late </p>
<table class="resultGrid"><tr> <td class="first">
<h4><a href="http://www.thelinkiwant.com/?params" title="Click to view result"</a></h4>
<div class="headlineBlock">
<h2>Clinton</h2>
<p class="tudor"><strong>Conditions:</strong> Never rainy </p>
<table class="resultGrid"><tr> <td class="first">
<h4><a href="http://www.thelinkiwant/?params" title="Click to view result"</a></h4>
XPATH:
$x("//div[#class='headlineBlock']/h2[not(contains('|Clinton|Obama|',concat('|',.,'|') ))]//../../table/a/#href")
There are several issues with your example.
There brackets missing after ever single "Click to view result", your "headlineBlock" divs and tables aren't closed, etc. So first you should make sure that your data is well formatted.
W3C's Xml Validator can help with that
Your XPath looks mostly ok, I think the issue is with the // at the end - they are a bit too early. Try this instead:
//div[#class='headlineBlock']/h2[not(contains('|Clinton|Obama|',concat('|',.,'|') ))]/..//a/#href
//div[#class='headlineBlock']
All divs of class headlineBlock ...
/h2[not(contains('|Clinton|Obama|',concat('|',.,'|') ))]
... that don't contain certain terms.
/..
Up one level (now we are at div headlineBlock again)
//a
Any direct descendants of element type a
/#href
H-Ref Attribute

CKEditor Removing attributes in closing tags

I have allowedcontent=true which is working and allowing me to have attributes in my opening tags; however, CKEdtior is still removing the closing tag attributes. I am using the editor to allow modification of simple Handlebars templates that use {{each}} and {{/each}}. The issue comes when using this with a table and wanting to repeat my rows.
For example, I have the following HTML entered into source:
<table>
<tr data-each={{each Person}}">
<td class="col-student-id">{{Identifier}}</td>
<td class="col-name">{{Name}}</td>
</tr data-each="{{/each}}">
</table>
When I click out of source, it removes the attribute on my closing tr tag.
Is there anyway to force CKEditor to not remove this attribute? If not, does anyone know of a way to allows me to use something like this:
<table>
{{each Person}}
<tr>
<td class="col-student-id">{{Identifier}}</td>
<td class="col-name">{{Name}}</td>
</tr>
{{/each}}
</table>
When I try the above example, it is reformatted to be:
<section>{{each Person}} {{/each}}
<table>
<tr>
<td class="col-student-id">{{Identifier}}</td>
<td class="col-name">{{Name}}</td>
</tr>
</table>
Your input source code is invalid - closing tags cannot have attributes in HTML, so CKEditor ignores them. Read more in CKEditor HTML Autocorrection Issue.

Hiding DIV in TPL file based on if an image exists?

<div><div style="margin-left:67px"><table style="border:1px #80A0BB solid;" padding="5px"><tr><td><img src="{$smarty.const.DOC_ROOT}/images/thumbs/{$link.ID}-300x225.png" alt="" /></td></tr></table></div></div>
I'm trying to hide a div based on if an image exists on my server. How would I check to see if an image exists and hide the div if it doesn't exist? Or is there a better way to do this?
The easiest way is just to use write a function in PHP and then use it in Smarty.
In PHP:
function linkImageExists($link){
//Check to see if image for link exists and return true if it does.
// otherwise:
return false;
}
In Smarty template:
{if linkImageExists($link)}
<div>
<div style="margin-left:67px">
<table style="border:1px #80A0BB solid;" padding="5px">
<tr>
<td>
<a href="{$link.URL|trim}" target="_blank">
<img src="{$smarty.const.DOC_ROOT}/images/thumbs/{$link.ID}-300x225.png" alt="" />
</a>
</td>
</tr>
</table>
</div>
</div>
{else}
{* image doesn't exist *}
{/if}
You may want to consider turning $link into an object and then you can call functions on it, rather than having to use global functions which may producer cleaner code in the future.

Resources